| .. | .. |
|---|
| 194 | 194 | return readl_relaxed(reg_base + EXYNOS4_MCT_G_CNT_L); |
|---|
| 195 | 195 | } |
|---|
| 196 | 196 | |
|---|
| 197 | | -static u64 exynos4_frc_read(struct clocksource *cs) |
|---|
| 198 | | -{ |
|---|
| 199 | | - return exynos4_read_count_32(); |
|---|
| 200 | | -} |
|---|
| 201 | | - |
|---|
| 202 | 197 | static void exynos4_frc_resume(struct clocksource *cs) |
|---|
| 203 | 198 | { |
|---|
| 204 | 199 | exynos4_mct_frc_start(); |
|---|
| 205 | 200 | } |
|---|
| 206 | 201 | |
|---|
| 207 | | -static struct clocksource mct_frc = { |
|---|
| 208 | | - .name = "mct-frc", |
|---|
| 209 | | - .rating = 450, /* use value higher than ARM arch timer */ |
|---|
| 210 | | - .read = exynos4_frc_read, |
|---|
| 211 | | - .mask = CLOCKSOURCE_MASK(32), |
|---|
| 212 | | - .flags = CLOCK_SOURCE_IS_CONTINUOUS, |
|---|
| 213 | | - .resume = exynos4_frc_resume, |
|---|
| 202 | +static struct clocksource_user_mmio mct_frc = { |
|---|
| 203 | + .mmio.clksrc = { |
|---|
| 204 | + .name = "mct-frc", |
|---|
| 205 | + .rating = 450, /* use value higher than ARM arch timer */ |
|---|
| 206 | + .read = clocksource_mmio_readl_up, |
|---|
| 207 | + .mask = CLOCKSOURCE_MASK(32), |
|---|
| 208 | + .flags = CLOCK_SOURCE_IS_CONTINUOUS, |
|---|
| 209 | + .resume = exynos4_frc_resume, |
|---|
| 210 | + }, |
|---|
| 214 | 211 | }; |
|---|
| 215 | 212 | |
|---|
| 216 | 213 | static u64 notrace exynos4_read_sched_clock(void) |
|---|
| .. | .. |
|---|
| 231 | 228 | |
|---|
| 232 | 229 | static int __init exynos4_clocksource_init(void) |
|---|
| 233 | 230 | { |
|---|
| 231 | + struct clocksource_mmio_regs mmr; |
|---|
| 232 | + |
|---|
| 234 | 233 | exynos4_mct_frc_start(); |
|---|
| 235 | 234 | |
|---|
| 236 | 235 | #if defined(CONFIG_ARM) |
|---|
| .. | .. |
|---|
| 239 | 238 | register_current_timer_delay(&exynos4_delay_timer); |
|---|
| 240 | 239 | #endif |
|---|
| 241 | 240 | |
|---|
| 242 | | - if (clocksource_register_hz(&mct_frc, clk_rate)) |
|---|
| 243 | | - panic("%s: can't register clocksource\n", mct_frc.name); |
|---|
| 241 | + mmr.reg_upper = NULL; |
|---|
| 242 | + mmr.reg_lower = reg_base + EXYNOS4_MCT_G_CNT_L; |
|---|
| 243 | + mmr.bits_upper = 0; |
|---|
| 244 | + mmr.bits_lower = 32; |
|---|
| 245 | + mmr.revmap = NULL; |
|---|
| 246 | + if (clocksource_user_mmio_init(&mct_frc, &mmr, clk_rate)) |
|---|
| 247 | + panic("%s: can't register clocksource\n", mct_frc.mmio.clksrc.name); |
|---|
| 244 | 248 | |
|---|
| 245 | 249 | sched_clock_register(exynos4_read_sched_clock, 32, clk_rate); |
|---|
| 246 | 250 | |
|---|
| .. | .. |
|---|
| 308 | 312 | static struct clock_event_device mct_comp_device = { |
|---|
| 309 | 313 | .name = "mct-comp", |
|---|
| 310 | 314 | .features = CLOCK_EVT_FEAT_PERIODIC | |
|---|
| 311 | | - CLOCK_EVT_FEAT_ONESHOT, |
|---|
| 315 | + CLOCK_EVT_FEAT_ONESHOT | |
|---|
| 316 | + CLOCK_EVT_FEAT_PIPELINE, |
|---|
| 312 | 317 | .rating = 250, |
|---|
| 313 | 318 | .set_next_event = exynos4_comp_set_next_event, |
|---|
| 314 | 319 | .set_state_periodic = mct_set_state_periodic, |
|---|
| .. | .. |
|---|
| 324 | 329 | |
|---|
| 325 | 330 | exynos4_mct_write(0x1, EXYNOS4_MCT_G_INT_CSTAT); |
|---|
| 326 | 331 | |
|---|
| 327 | | - evt->event_handler(evt); |
|---|
| 332 | + clockevents_handle_event(evt); |
|---|
| 328 | 333 | |
|---|
| 329 | 334 | return IRQ_HANDLED; |
|---|
| 330 | 335 | } |
|---|
| .. | .. |
|---|
| 335 | 340 | clockevents_config_and_register(&mct_comp_device, clk_rate, |
|---|
| 336 | 341 | 0xf, 0xffffffff); |
|---|
| 337 | 342 | if (request_irq(mct_irqs[MCT_G0_IRQ], exynos4_mct_comp_isr, |
|---|
| 338 | | - IRQF_TIMER | IRQF_IRQPOLL, "mct_comp_irq", |
|---|
| 343 | + IRQF_TIMER | IRQF_IRQPOLL | IRQF_OOB, "mct_comp_irq", |
|---|
| 339 | 344 | &mct_comp_device)) |
|---|
| 340 | 345 | pr_err("%s: request_irq() failed\n", "mct_comp_irq"); |
|---|
| 341 | 346 | |
|---|
| .. | .. |
|---|
| 434 | 439 | |
|---|
| 435 | 440 | exynos4_mct_tick_clear(mevt); |
|---|
| 436 | 441 | |
|---|
| 437 | | - evt->event_handler(evt); |
|---|
| 442 | + clockevents_handle_event(evt); |
|---|
| 438 | 443 | |
|---|
| 439 | 444 | return IRQ_HANDLED; |
|---|
| 440 | 445 | } |
|---|
| .. | .. |
|---|
| 456 | 461 | evt->set_state_oneshot = set_state_shutdown; |
|---|
| 457 | 462 | evt->set_state_oneshot_stopped = set_state_shutdown; |
|---|
| 458 | 463 | evt->tick_resume = set_state_shutdown; |
|---|
| 459 | | - evt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; |
|---|
| 464 | + evt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT | \ |
|---|
| 465 | + CLOCK_EVT_FEAT_PIPELINE; |
|---|
| 460 | 466 | evt->rating = 500; /* use value higher than ARM arch timer */ |
|---|
| 461 | 467 | |
|---|
| 462 | 468 | exynos4_mct_write(TICK_BASE_CNT, mevt->base + MCT_L_TCNTB_OFFSET); |
|---|
| .. | .. |
|---|
| 541 | 547 | |
|---|
| 542 | 548 | if (mct_int_type == MCT_INT_PPI) { |
|---|
| 543 | 549 | |
|---|
| 544 | | - err = request_percpu_irq(mct_irqs[MCT_L0_IRQ], |
|---|
| 545 | | - exynos4_mct_tick_isr, "MCT", |
|---|
| 546 | | - &percpu_mct_tick); |
|---|
| 550 | + err = __request_percpu_irq(mct_irqs[MCT_L0_IRQ], |
|---|
| 551 | + exynos4_mct_tick_isr, IRQF_TIMER, |
|---|
| 552 | + "MCT", &percpu_mct_tick); |
|---|
| 547 | 553 | WARN(err, "MCT: can't request IRQ %d (%d)\n", |
|---|
| 548 | 554 | mct_irqs[MCT_L0_IRQ], err); |
|---|
| 549 | 555 | } else { |
|---|