[PATCH 3/5] ARM: twd: Add context save restore support

Santosh Shilimkar santosh.shilimkar at ti.com
Mon Jan 24 03:51:17 EST 2011


In CPU low power state, local timer looses its register context. This
patch adds context save restore hooks which can be used by platforms
appropriately.

Signed-off-by: Santosh Shilimkar <santosh.shilimkar at ti.com>
Cc: Russell King <rmk+kernel at arm.linux.org.uk>
---
 arch/arm/include/asm/localtimer.h |   13 +++++++++++++
 arch/arm/include/asm/smp_twd.h    |    2 ++
 arch/arm/kernel/smp_twd.c         |   24 ++++++++++++++++++++++++
 3 files changed, 39 insertions(+), 0 deletions(-)

diff --git a/arch/arm/include/asm/localtimer.h b/arch/arm/include/asm/localtimer.h
index 6bc63ab..6753754 100644
--- a/arch/arm/include/asm/localtimer.h
+++ b/arch/arm/include/asm/localtimer.h
@@ -31,6 +31,9 @@ asmlinkage void do_local_timer(struct pt_regs *);
 
 #define local_timer_ack()	twd_timer_ack()
 
+#define local_timer_save(cpu)		twd_context_save(cpu);
+#define local_timer_restore(cpu)	twd_context_save(cpu);
+
 #else
 
 /*
@@ -46,6 +49,16 @@ int local_timer_ack(void);
  */
 void local_timer_setup(struct clock_event_device *);
 
+/*
+ * Save local timer register context
+ */
+void local_timer_save(unsigned int cpu);
+
+/*
+ * Restore local timer register context
+ */
+void local_timer_restoree(unsigned int cpu);
+
 #endif
 
 #endif
diff --git a/arch/arm/include/asm/smp_twd.h b/arch/arm/include/asm/smp_twd.h
index fed9981..7828f29 100644
--- a/arch/arm/include/asm/smp_twd.h
+++ b/arch/arm/include/asm/smp_twd.h
@@ -24,5 +24,7 @@ extern void __iomem *twd_base;
 
 int twd_timer_ack(void);
 void twd_timer_setup(struct clock_event_device *);
+void twd_context_save(unsigned int cpu);
+void twd_context_restore(unsigned int cpu);
 
 #endif
diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c
index fd91566..f3098e4 100644
--- a/arch/arm/kernel/smp_twd.c
+++ b/arch/arm/kernel/smp_twd.c
@@ -24,6 +24,12 @@
 /* set up by the platform code */
 void __iomem *twd_base;
 
+/* Timer context to be saved in low power modes */
+struct twd_registers {
+	unsigned long timer_ctrl;
+	unsigned long timer_load;
+};
+static DEFINE_PER_CPU(struct twd_registers, twd_context);
 static unsigned long twd_timer_rate;
 
 static void twd_set_mode(enum clock_event_mode mode,
@@ -145,3 +151,21 @@ void __cpuinit twd_timer_setup(struct clock_event_device *clk)
 
 	clockevents_register_device(clk);
 }
+
+/* Low power context save */
+void twd_context_save(unsigned int cpu)
+{
+	struct twd_registers *regs = &per_cpu(twd_context, cpu);
+
+	regs->timer_ctrl = __raw_readl(twd_base + TWD_TIMER_CONTROL);
+	regs->timer_load = __raw_readl(twd_base + TWD_TIMER_LOAD);
+}
+
+/* Low power context restore */
+void twd_context_restore(unsigned int cpu)
+{
+	struct twd_registers *regs = &per_cpu(twd_context, cpu);
+
+	__raw_writel(regs->timer_load, twd_base + TWD_TIMER_LOAD);
+	__raw_writel(regs->timer_ctrl, twd_base + TWD_TIMER_CONTROL);
+}
-- 
1.6.0.4




More information about the linux-arm-kernel mailing list