@@ -448,6 +448,7 @@ config SPRD_TIMER
bool "Spreadtrum timer driver" if COMPILE_TEST
depends on HAS_IOMEM
select TIMER_OF
+ select PERSISTENT_TIMER
help
Enables the support for the Spreadtrum timer driver.
@@ -7,6 +7,7 @@
#include <linux/interrupt.h>
#include "timer-of.h"
+#include "persistent-timer.h"
#define TIMER_NAME "sprd_timer"
@@ -157,3 +158,37 @@ static int __init sprd_timer_init(struct device_node *np)
}
TIMER_OF_DECLARE(sc9860_timer, "sprd,sc9860-timer", sprd_timer_init);
+
+static u64 sprd_persistent_timer_read(struct persistent_timer *p)
+{
+ return ~(u64)readl_relaxed(p->base + TIMER_VALUE_SHDW_LO) & p->mask;
+}
+
+static void sprd_persistent_timer_enable(struct persistent_timer *p)
+{
+ sprd_timer_disable(p->base);
+ sprd_timer_update_counter(p->base, TIMER_VALUE_LO_MASK);
+ sprd_timer_enable(p->base, TIMER_CTL_PERIOD_MODE);
+}
+
+static struct persistent_timer p = {
+ .read = sprd_persistent_timer_read,
+ .mask = CLOCKSOURCE_MASK(32),
+ .flags = PERSISTENT_TIMER_BASE | PERSISTENT_TIMER_CLOCK |
+ PERSISTENT_TIMER_MULT_SHIFT,
+};
+
+static int __init sprd_persistent_timer_init(struct device_node *np)
+{
+ int ret;
+
+ ret = persistent_timer_init_and_register(np, &p);
+ if (ret)
+ return ret;
+
+ sprd_persistent_timer_enable(&p);
+ return 0;
+}
+
+TIMER_OF_DECLARE(sc9860_persistent_timer, "sprd,sc9860-persistent-timer",
+ sprd_persistent_timer_init);
On Spreadtrum SC9860 platform, we need one persistent timer to calculate the suspend time to compensate the OS time. This patch registers one Spreadtrum AON timer as persistent timer, which runs at 32bit and periodic mode. Signed-off-by: Baolin Wang <baolin.wang@linaro.org> --- drivers/clocksource/Kconfig | 1 + drivers/clocksource/timer-sprd.c | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) -- 1.7.9.5