aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Petazzoni <thomas.petazzoni@free-electrons.com>2014-11-21 11:00:01 -0500
committerJason Cooper <jason@lakedaemon.net>2014-11-30 11:40:09 -0500
commitf9a49ab53a269fda39ae57063bd336b4bd62fa76 (patch)
tree5ae5866c83027df010fbcc78755f46e4a380ce68
parent0f077eb5cfaf453ad7379963a721b8c04f7c62a2 (diff)
clocksource: time-armada-370-xp: add suspend/resume support
This commit adds a set of suspend/resume syscore_ops to respectively save and restore a number of timer registers, in order to make sure the clockevent and clocksource devices continue to work properly across a suspend/resume cycle. Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> Cc: Daniel Lezcano <daniel.lezcano@linaro.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: linux-kernel@vger.kernel.org Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org> Link: https://lkml.kernel.org/r/1416585613-2113-5-git-send-email-thomas.petazzoni@free-electrons.com Signed-off-by: Jason Cooper <jason@lakedaemon.net>
-rw-r--r--drivers/clocksource/time-armada-370-xp.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/drivers/clocksource/time-armada-370-xp.c b/drivers/clocksource/time-armada-370-xp.c
index 0451e62fac7a..ff37d3abb806 100644
--- a/drivers/clocksource/time-armada-370-xp.c
+++ b/drivers/clocksource/time-armada-370-xp.c
@@ -43,6 +43,7 @@
43#include <linux/module.h> 43#include <linux/module.h>
44#include <linux/sched_clock.h> 44#include <linux/sched_clock.h>
45#include <linux/percpu.h> 45#include <linux/percpu.h>
46#include <linux/syscore_ops.h>
46 47
47/* 48/*
48 * Timer block registers. 49 * Timer block registers.
@@ -223,6 +224,28 @@ static struct notifier_block armada_370_xp_timer_cpu_nb = {
223 .notifier_call = armada_370_xp_timer_cpu_notify, 224 .notifier_call = armada_370_xp_timer_cpu_notify,
224}; 225};
225 226
227static u32 timer0_ctrl_reg, timer0_local_ctrl_reg;
228
229static int armada_370_xp_timer_suspend(void)
230{
231 timer0_ctrl_reg = readl(timer_base + TIMER_CTRL_OFF);
232 timer0_local_ctrl_reg = readl(local_base + TIMER_CTRL_OFF);
233 return 0;
234}
235
236static void armada_370_xp_timer_resume(void)
237{
238 writel(0xffffffff, timer_base + TIMER0_VAL_OFF);
239 writel(0xffffffff, timer_base + TIMER0_RELOAD_OFF);
240 writel(timer0_ctrl_reg, timer_base + TIMER_CTRL_OFF);
241 writel(timer0_local_ctrl_reg, local_base + TIMER_CTRL_OFF);
242}
243
244struct syscore_ops armada_370_xp_timer_syscore_ops = {
245 .suspend = armada_370_xp_timer_suspend,
246 .resume = armada_370_xp_timer_resume,
247};
248
226static void __init armada_370_xp_timer_common_init(struct device_node *np) 249static void __init armada_370_xp_timer_common_init(struct device_node *np)
227{ 250{
228 u32 clr = 0, set = 0; 251 u32 clr = 0, set = 0;
@@ -285,6 +308,8 @@ static void __init armada_370_xp_timer_common_init(struct device_node *np)
285 /* Immediately configure the timer on the boot CPU */ 308 /* Immediately configure the timer on the boot CPU */
286 if (!res) 309 if (!res)
287 armada_370_xp_timer_setup(this_cpu_ptr(armada_370_xp_evt)); 310 armada_370_xp_timer_setup(this_cpu_ptr(armada_370_xp_evt));
311
312 register_syscore_ops(&armada_370_xp_timer_syscore_ops);
288} 313}
289 314
290static void __init armada_xp_timer_init(struct device_node *np) 315static void __init armada_xp_timer_init(struct device_node *np)