clocksource/drivers/sprd: Register one always-on timer to compensate suspend time
authorBaolin Wang <baolin.wang@linaro.org>
Tue, 17 Jul 2018 07:55:17 +0000 (15:55 +0800)
committerDaniel Lezcano <daniel.lezcano@linaro.org>
Thu, 26 Jul 2018 09:26:34 +0000 (11:26 +0200)
Since the clocksource framework has introduced one suspend clocksource to
compensate the suspend time, this patch registers one always-on timer as
the suspend clocksource.

Signed-off-by: Baolin Wang <baolin.wang@linaro.org>
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
drivers/clocksource/timer-sprd.c

index ef9ebea..430cb99 100644 (file)
@@ -156,4 +156,54 @@ static int __init sprd_timer_init(struct device_node *np)
        return 0;
 }
 
+static struct timer_of suspend_to = {
+       .flags = TIMER_OF_BASE | TIMER_OF_CLOCK,
+};
+
+static u64 sprd_suspend_timer_read(struct clocksource *cs)
+{
+       return ~(u64)readl_relaxed(timer_of_base(&suspend_to) +
+                                  TIMER_VALUE_SHDW_LO) & cs->mask;
+}
+
+static int sprd_suspend_timer_enable(struct clocksource *cs)
+{
+       sprd_timer_update_counter(timer_of_base(&suspend_to),
+                                 TIMER_VALUE_LO_MASK);
+       sprd_timer_enable(timer_of_base(&suspend_to), TIMER_CTL_PERIOD_MODE);
+
+       return 0;
+}
+
+static void sprd_suspend_timer_disable(struct clocksource *cs)
+{
+       sprd_timer_disable(timer_of_base(&suspend_to));
+}
+
+static struct clocksource suspend_clocksource = {
+       .name   = "sprd_suspend_timer",
+       .rating = 200,
+       .read   = sprd_suspend_timer_read,
+       .enable = sprd_suspend_timer_enable,
+       .disable = sprd_suspend_timer_disable,
+       .mask   = CLOCKSOURCE_MASK(32),
+       .flags  = CLOCK_SOURCE_IS_CONTINUOUS | CLOCK_SOURCE_SUSPEND_NONSTOP,
+};
+
+static int __init sprd_suspend_timer_init(struct device_node *np)
+{
+       int ret;
+
+       ret = timer_of_init(np, &suspend_to);
+       if (ret)
+               return ret;
+
+       clocksource_register_hz(&suspend_clocksource,
+                               timer_of_rate(&suspend_to));
+
+       return 0;
+}
+
 TIMER_OF_DECLARE(sc9860_timer, "sprd,sc9860-timer", sprd_timer_init);
+TIMER_OF_DECLARE(sc9860_persistent_timer, "sprd,sc9860-suspend-timer",
+                sprd_suspend_timer_init);