aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clocksource/exynos_mct.c
diff options
context:
space:
mode:
authorViresh Kumar <viresh.kumar@linaro.org>2015-06-18 06:54:20 -0400
committerDaniel Lezcano <daniel.lezcano@linaro.org>2015-08-10 05:40:53 -0400
commit79e436d3a7d0510dfe6be3973efd78f6ccfe1492 (patch)
tree4b9c2ecef0ca663ccbb0351654cff51fdd37f341 /drivers/clocksource/exynos_mct.c
parentcf4541c101ea497f68639cc94a2639a05cc3710f (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.c85
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
260static void exynos4_mct_comp0_start(enum clock_event_mode mode, 260static 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,
283static int exynos4_comp_set_next_event(unsigned long cycles, 282static 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
291static void exynos4_comp_set_mode(enum clock_event_mode mode, 290static 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) { 296static 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
312static struct clock_event_device mct_comp_device = { 307static 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
320static irqreturn_t exynos4_mct_comp_isr(int irq, void *dev_id) 319static 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
393static inline void exynos4_tick_set_mode(enum clock_event_mode mode, 392static 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
398static 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
416static void exynos4_mct_tick_clear(struct mct_clock_event_device *mevt) 410static 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);