diff mbox series

[2/2] clocksource: sprd: Add one persistent timer for Spreadtrum SC9860 platform

Message ID 3dd35afbcc2bc69bbc7a625e56257435b22dbc4c.1515486685.git.baolin.wang@linaro.org
State New
Headers show
Series [1/2] clocksource: Add persistent timer support | expand

Commit Message

(Exiting) Baolin Wang Jan. 9, 2018, 9:09 a.m. UTC
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
diff mbox series

Patch

diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 9cf3d41..322c02d 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -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.
 
diff --git a/drivers/clocksource/timer-sprd.c b/drivers/clocksource/timer-sprd.c
index ef9ebea..2304a7c 100644
--- a/drivers/clocksource/timer-sprd.c
+++ b/drivers/clocksource/timer-sprd.c
@@ -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);