diff options
author | Viresh Kumar <viresh.kumar@linaro.org> | 2015-06-18 06:54:20 -0400 |
---|---|---|
committer | Daniel Lezcano <daniel.lezcano@linaro.org> | 2015-08-10 05:40:53 -0400 |
commit | 79e436d3a7d0510dfe6be3973efd78f6ccfe1492 (patch) | |
tree | 4b9c2ecef0ca663ccbb0351654cff51fdd37f341 /drivers/clocksource/exynos_mct.c | |
parent | cf4541c101ea497f68639cc94a2639a05cc3710f (diff) |
clockevents/drivers/exynos_mct: Migrate to new 'set-state' interface
Migrate exynos_mct driver to the new 'set-state' interface provided by
clockevents core, the earlier 'set-mode' interface is marked obsolete
now.
This also enables us to implement callbacks for new states of clockevent
devices, for example: ONESHOT_STOPPED.
Cc: Kukjin Kim <kgene.kim@samsung.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Diffstat (limited to 'drivers/clocksource/exynos_mct.c')
-rw-r--r-- | drivers/clocksource/exynos_mct.c | 85 |
1 files changed, 40 insertions, 45 deletions
diff --git a/drivers/clocksource/exynos_mct.c b/drivers/clocksource/exynos_mct.c index 4d2330a92b27..029f96ab131a 100644 --- a/drivers/clocksource/exynos_mct.c +++ b/drivers/clocksource/exynos_mct.c | |||
@@ -257,15 +257,14 @@ static void exynos4_mct_comp0_stop(void) | |||
257 | exynos4_mct_write(0, EXYNOS4_MCT_G_INT_ENB); | 257 | exynos4_mct_write(0, EXYNOS4_MCT_G_INT_ENB); |
258 | } | 258 | } |
259 | 259 | ||
260 | static void exynos4_mct_comp0_start(enum clock_event_mode mode, | 260 | static void exynos4_mct_comp0_start(bool periodic, unsigned long cycles) |
261 | unsigned long cycles) | ||
262 | { | 261 | { |
263 | unsigned int tcon; | 262 | unsigned int tcon; |
264 | cycle_t comp_cycle; | 263 | cycle_t comp_cycle; |
265 | 264 | ||
266 | tcon = readl_relaxed(reg_base + EXYNOS4_MCT_G_TCON); | 265 | tcon = readl_relaxed(reg_base + EXYNOS4_MCT_G_TCON); |
267 | 266 | ||
268 | if (mode == CLOCK_EVT_MODE_PERIODIC) { | 267 | if (periodic) { |
269 | tcon |= MCT_G_TCON_COMP0_AUTO_INC; | 268 | tcon |= MCT_G_TCON_COMP0_AUTO_INC; |
270 | exynos4_mct_write(cycles, EXYNOS4_MCT_G_COMP0_ADD_INCR); | 269 | exynos4_mct_write(cycles, EXYNOS4_MCT_G_COMP0_ADD_INCR); |
271 | } | 270 | } |
@@ -283,38 +282,38 @@ static void exynos4_mct_comp0_start(enum clock_event_mode mode, | |||
283 | static int exynos4_comp_set_next_event(unsigned long cycles, | 282 | static int exynos4_comp_set_next_event(unsigned long cycles, |
284 | struct clock_event_device *evt) | 283 | struct clock_event_device *evt) |
285 | { | 284 | { |
286 | exynos4_mct_comp0_start(evt->mode, cycles); | 285 | exynos4_mct_comp0_start(false, cycles); |
287 | 286 | ||
288 | return 0; | 287 | return 0; |
289 | } | 288 | } |
290 | 289 | ||
291 | static void exynos4_comp_set_mode(enum clock_event_mode mode, | 290 | static int mct_set_state_shutdown(struct clock_event_device *evt) |
292 | struct clock_event_device *evt) | ||
293 | { | 291 | { |
294 | unsigned long cycles_per_jiffy; | ||
295 | exynos4_mct_comp0_stop(); | 292 | exynos4_mct_comp0_stop(); |
293 | return 0; | ||
294 | } | ||
296 | 295 | ||
297 | switch (mode) { | 296 | static int mct_set_state_periodic(struct clock_event_device *evt) |
298 | case CLOCK_EVT_MODE_PERIODIC: | 297 | { |
299 | cycles_per_jiffy = | 298 | unsigned long cycles_per_jiffy; |
300 | (((unsigned long long) NSEC_PER_SEC / HZ * evt->mult) >> evt->shift); | ||
301 | exynos4_mct_comp0_start(mode, cycles_per_jiffy); | ||
302 | break; | ||
303 | 299 | ||
304 | case CLOCK_EVT_MODE_ONESHOT: | 300 | cycles_per_jiffy = (((unsigned long long)NSEC_PER_SEC / HZ * evt->mult) |
305 | case CLOCK_EVT_MODE_UNUSED: | 301 | >> evt->shift); |
306 | case CLOCK_EVT_MODE_SHUTDOWN: | 302 | exynos4_mct_comp0_stop(); |
307 | case CLOCK_EVT_MODE_RESUME: | 303 | exynos4_mct_comp0_start(true, cycles_per_jiffy); |
308 | break; | 304 | return 0; |
309 | } | ||
310 | } | 305 | } |
311 | 306 | ||
312 | static struct clock_event_device mct_comp_device = { | 307 | static struct clock_event_device mct_comp_device = { |
313 | .name = "mct-comp", | 308 | .name = "mct-comp", |
314 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, | 309 | .features = CLOCK_EVT_FEAT_PERIODIC | |
315 | .rating = 250, | 310 | CLOCK_EVT_FEAT_ONESHOT, |
316 | .set_next_event = exynos4_comp_set_next_event, | 311 | .rating = 250, |
317 | .set_mode = exynos4_comp_set_mode, | 312 | .set_next_event = exynos4_comp_set_next_event, |
313 | .set_state_periodic = mct_set_state_periodic, | ||
314 | .set_state_shutdown = mct_set_state_shutdown, | ||
315 | .set_state_oneshot = mct_set_state_shutdown, | ||
316 | .tick_resume = mct_set_state_shutdown, | ||
318 | }; | 317 | }; |
319 | 318 | ||
320 | static irqreturn_t exynos4_mct_comp_isr(int irq, void *dev_id) | 319 | static irqreturn_t exynos4_mct_comp_isr(int irq, void *dev_id) |
@@ -390,39 +389,32 @@ static int exynos4_tick_set_next_event(unsigned long cycles, | |||
390 | return 0; | 389 | return 0; |
391 | } | 390 | } |
392 | 391 | ||
393 | static inline void exynos4_tick_set_mode(enum clock_event_mode mode, | 392 | static int set_state_shutdown(struct clock_event_device *evt) |
394 | struct clock_event_device *evt) | 393 | { |
394 | exynos4_mct_tick_stop(this_cpu_ptr(&percpu_mct_tick)); | ||
395 | return 0; | ||
396 | } | ||
397 | |||
398 | static int set_state_periodic(struct clock_event_device *evt) | ||
395 | { | 399 | { |
396 | struct mct_clock_event_device *mevt = this_cpu_ptr(&percpu_mct_tick); | 400 | struct mct_clock_event_device *mevt = this_cpu_ptr(&percpu_mct_tick); |
397 | unsigned long cycles_per_jiffy; | 401 | unsigned long cycles_per_jiffy; |
398 | 402 | ||
403 | cycles_per_jiffy = (((unsigned long long)NSEC_PER_SEC / HZ * evt->mult) | ||
404 | >> evt->shift); | ||
399 | exynos4_mct_tick_stop(mevt); | 405 | exynos4_mct_tick_stop(mevt); |
400 | 406 | exynos4_mct_tick_start(cycles_per_jiffy, mevt); | |
401 | switch (mode) { | 407 | return 0; |
402 | case CLOCK_EVT_MODE_PERIODIC: | ||
403 | cycles_per_jiffy = | ||
404 | (((unsigned long long) NSEC_PER_SEC / HZ * evt->mult) >> evt->shift); | ||
405 | exynos4_mct_tick_start(cycles_per_jiffy, mevt); | ||
406 | break; | ||
407 | |||
408 | case CLOCK_EVT_MODE_ONESHOT: | ||
409 | case CLOCK_EVT_MODE_UNUSED: | ||
410 | case CLOCK_EVT_MODE_SHUTDOWN: | ||
411 | case CLOCK_EVT_MODE_RESUME: | ||
412 | break; | ||
413 | } | ||
414 | } | 408 | } |
415 | 409 | ||
416 | static void exynos4_mct_tick_clear(struct mct_clock_event_device *mevt) | 410 | static void exynos4_mct_tick_clear(struct mct_clock_event_device *mevt) |
417 | { | 411 | { |
418 | struct clock_event_device *evt = &mevt->evt; | ||
419 | |||
420 | /* | 412 | /* |
421 | * This is for supporting oneshot mode. | 413 | * This is for supporting oneshot mode. |
422 | * Mct would generate interrupt periodically | 414 | * Mct would generate interrupt periodically |
423 | * without explicit stopping. | 415 | * without explicit stopping. |
424 | */ | 416 | */ |
425 | if (evt->mode != CLOCK_EVT_MODE_PERIODIC) | 417 | if (!clockevent_state_periodic(&mevt->evt)) |
426 | exynos4_mct_tick_stop(mevt); | 418 | exynos4_mct_tick_stop(mevt); |
427 | 419 | ||
428 | /* Clear the MCT tick interrupt */ | 420 | /* Clear the MCT tick interrupt */ |
@@ -453,7 +445,10 @@ static int exynos4_local_timer_setup(struct mct_clock_event_device *mevt) | |||
453 | evt->name = mevt->name; | 445 | evt->name = mevt->name; |
454 | evt->cpumask = cpumask_of(cpu); | 446 | evt->cpumask = cpumask_of(cpu); |
455 | evt->set_next_event = exynos4_tick_set_next_event; | 447 | evt->set_next_event = exynos4_tick_set_next_event; |
456 | evt->set_mode = exynos4_tick_set_mode; | 448 | evt->set_state_periodic = set_state_periodic; |
449 | evt->set_state_shutdown = set_state_shutdown; | ||
450 | evt->set_state_oneshot = set_state_shutdown; | ||
451 | evt->tick_resume = set_state_shutdown; | ||
457 | evt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; | 452 | evt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; |
458 | evt->rating = 450; | 453 | evt->rating = 450; |
459 | 454 | ||
@@ -479,7 +474,7 @@ static void exynos4_local_timer_stop(struct mct_clock_event_device *mevt) | |||
479 | { | 474 | { |
480 | struct clock_event_device *evt = &mevt->evt; | 475 | struct clock_event_device *evt = &mevt->evt; |
481 | 476 | ||
482 | evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt); | 477 | evt->set_state_shutdown(evt); |
483 | if (mct_int_type == MCT_INT_SPI) { | 478 | if (mct_int_type == MCT_INT_SPI) { |
484 | if (evt->irq != -1) | 479 | if (evt->irq != -1) |
485 | disable_irq_nosync(evt->irq); | 480 | disable_irq_nosync(evt->irq); |