MIPS: loongson64/timer: Migrate to new 'set-state' interface
authorViresh Kumar <viresh.kumar@linaro.org>
Mon, 6 Jul 2015 11:12:01 +0000 (16:42 +0530)
committerRalf Baechle <ralf@linux-mips.org>
Thu, 3 Sep 2015 10:07:53 +0000 (12:07 +0200)
Migrate loongson 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.

[ralf@linux-mips.org: Folded in Viresh's followon fix.]

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Cc: Huacai Chen <chenhc@lemote.com>
Cc: Michael Opdenacker <michael.opdenacker@free-electrons.com>
Cc: Hongliang Tao <taohl@lemote.com>
Cc: Valentin Rothberg <valentinrothberg@gmail.com>
Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
Cc: linux-mips@linux-mips.org
Cc: linaro-kernel@lists.linaro.org
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Viresh Kumar <viresh.kumar@linaro.org>
Patchwork: https://patchwork.linux-mips.org/patch/10608/
Patchwork: https://patchwork.linux-mips.org/patch/10883/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
arch/mips/loongson64/common/cs5536/cs5536_mfgpt.c
arch/mips/loongson64/loongson-3/hpet.c

index 875037063a80ecc634d74759ce3032b78261ea19..da77d412514c03db21e6577466a9c8b8e8ac158b 100644 (file)
@@ -51,40 +51,36 @@ void enable_mfgpt0_counter(void)
 }
 EXPORT_SYMBOL(enable_mfgpt0_counter);
 
-static void init_mfgpt_timer(enum clock_event_mode mode,
-                            struct clock_event_device *evt)
+static int mfgpt_timer_set_periodic(struct clock_event_device *evt)
 {
        raw_spin_lock(&mfgpt_lock);
 
-       switch (mode) {
-       case CLOCK_EVT_MODE_PERIODIC:
-               outw(COMPARE, MFGPT0_CMP2);     /* set comparator2 */
-               outw(0, MFGPT0_CNT);    /* set counter to 0 */
-               enable_mfgpt0_counter();
-               break;
-
-       case CLOCK_EVT_MODE_SHUTDOWN:
-       case CLOCK_EVT_MODE_UNUSED:
-               if (evt->mode == CLOCK_EVT_MODE_PERIODIC ||
-                   evt->mode == CLOCK_EVT_MODE_ONESHOT)
-                       disable_mfgpt0_counter();
-               break;
-
-       case CLOCK_EVT_MODE_ONESHOT:
-               /* The oneshot mode have very high deviation, Not use it! */
-               break;
-
-       case CLOCK_EVT_MODE_RESUME:
-               /* Nothing to do here */
-               break;
-       }
+       outw(COMPARE, MFGPT0_CMP2);     /* set comparator2 */
+       outw(0, MFGPT0_CNT);            /* set counter to 0 */
+       enable_mfgpt0_counter();
+
        raw_spin_unlock(&mfgpt_lock);
+       return 0;
+}
+
+static int mfgpt_timer_shutdown(struct clock_event_device *evt)
+{
+       if (clockevent_state_periodic(evt) || clockevent_state_oneshot(evt)) {
+               raw_spin_lock(&mfgpt_lock);
+               disable_mfgpt0_counter();
+               raw_spin_unlock(&mfgpt_lock);
+       }
+
+       return 0;
 }
 
 static struct clock_event_device mfgpt_clockevent = {
        .name = "mfgpt",
        .features = CLOCK_EVT_FEAT_PERIODIC,
-       .set_mode = init_mfgpt_timer,
+
+       /* The oneshot mode have very high deviation, don't use it! */
+       .set_state_shutdown = mfgpt_timer_shutdown,
+       .set_state_periodic = mfgpt_timer_set_periodic,
        .irq = CS5536_MFGPT_INTR,
 };
 
index 5c21cd3bd339ab253c8b9a956de7bd20534e00f5..bf9f1a77f0e59825fcdb6ced3ce73ca78d8c7c19 100644 (file)
@@ -78,55 +78,77 @@ static void hpet_enable_legacy_int(void)
        /* Do nothing on Loongson-3 */
 }
 
-static void hpet_set_mode(enum clock_event_mode mode,
-                               struct clock_event_device *evt)
+static int hpet_set_state_periodic(struct clock_event_device *evt)
 {
-       int cfg = 0;
+       int cfg;
 
        spin_lock(&hpet_lock);
-       switch (mode) {
-       case CLOCK_EVT_MODE_PERIODIC:
-               pr_info("set clock event to periodic mode!\n");
-               /* stop counter */
-               hpet_stop_counter();
-
-               /* enables the timer0 to generate a periodic interrupt */
-               cfg = hpet_read(HPET_T0_CFG);
-               cfg &= ~HPET_TN_LEVEL;
-               cfg |= HPET_TN_ENABLE | HPET_TN_PERIODIC |
-                               HPET_TN_SETVAL | HPET_TN_32BIT;
-               hpet_write(HPET_T0_CFG, cfg);
-
-               /* set the comparator */
-               hpet_write(HPET_T0_CMP, HPET_COMPARE_VAL);
-               udelay(1);
-               hpet_write(HPET_T0_CMP, HPET_COMPARE_VAL);
-
-               /* start counter */
-               hpet_start_counter();
-               break;
-       case CLOCK_EVT_MODE_SHUTDOWN:
-       case CLOCK_EVT_MODE_UNUSED:
-               cfg = hpet_read(HPET_T0_CFG);
-               cfg &= ~HPET_TN_ENABLE;
-               hpet_write(HPET_T0_CFG, cfg);
-               break;
-       case CLOCK_EVT_MODE_ONESHOT:
-               pr_info("set clock event to one shot mode!\n");
-               cfg = hpet_read(HPET_T0_CFG);
-               /* set timer0 type
-                * 1 : periodic interrupt
-                * 0 : non-periodic(oneshot) interrupt
-                */
-               cfg &= ~HPET_TN_PERIODIC;
-               cfg |= HPET_TN_ENABLE | HPET_TN_32BIT;
-               hpet_write(HPET_T0_CFG, cfg);
-               break;
-       case CLOCK_EVT_MODE_RESUME:
-               hpet_enable_legacy_int();
-               break;
-       }
+
+       pr_info("set clock event to periodic mode!\n");
+       /* stop counter */
+       hpet_stop_counter();
+
+       /* enables the timer0 to generate a periodic interrupt */
+       cfg = hpet_read(HPET_T0_CFG);
+       cfg &= ~HPET_TN_LEVEL;
+       cfg |= HPET_TN_ENABLE | HPET_TN_PERIODIC | HPET_TN_SETVAL |
+               HPET_TN_32BIT;
+       hpet_write(HPET_T0_CFG, cfg);
+
+       /* set the comparator */
+       hpet_write(HPET_T0_CMP, HPET_COMPARE_VAL);
+       udelay(1);
+       hpet_write(HPET_T0_CMP, HPET_COMPARE_VAL);
+
+       /* start counter */
+       hpet_start_counter();
+
+       spin_unlock(&hpet_lock);
+       return 0;
+}
+
+static int hpet_set_state_shutdown(struct clock_event_device *evt)
+{
+       int cfg;
+
+       spin_lock(&hpet_lock);
+
+       cfg = hpet_read(HPET_T0_CFG);
+       cfg &= ~HPET_TN_ENABLE;
+       hpet_write(HPET_T0_CFG, cfg);
+
        spin_unlock(&hpet_lock);
+       return 0;
+}
+
+static int hpet_set_state_oneshot(struct clock_event_device *evt)
+{
+       int cfg;
+
+       spin_lock(&hpet_lock);
+
+       pr_info("set clock event to one shot mode!\n");
+       cfg = hpet_read(HPET_T0_CFG);
+       /*
+        * set timer0 type
+        * 1 : periodic interrupt
+        * 0 : non-periodic(oneshot) interrupt
+        */
+       cfg &= ~HPET_TN_PERIODIC;
+       cfg |= HPET_TN_ENABLE | HPET_TN_32BIT;
+       hpet_write(HPET_T0_CFG, cfg);
+
+       spin_unlock(&hpet_lock);
+       return 0;
+}
+
+static int hpet_tick_resume(struct clock_event_device *evt)
+{
+       spin_lock(&hpet_lock);
+       hpet_enable_legacy_int();
+       spin_unlock(&hpet_lock);
+
+       return 0;
 }
 
 static int hpet_next_event(unsigned long delta,
@@ -206,7 +228,10 @@ void __init setup_hpet_timer(void)
        cd->name = "hpet";
        cd->rating = 320;
        cd->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
-       cd->set_mode = hpet_set_mode;
+       cd->set_state_shutdown = hpet_set_state_shutdown;
+       cd->set_state_periodic = hpet_set_state_periodic;
+       cd->set_state_oneshot = hpet_set_state_oneshot;
+       cd->tick_resume = hpet_tick_resume;
        cd->set_next_event = hpet_next_event;
        cd->irq = HPET_T0_IRQ;
        cd->cpumask = cpumask_of(cpu);