ARM: tegra: power: Add TWD context save/restore
Scott Williams [Thu, 21 Jul 2011 01:13:59 +0000 (18:13 -0700)]
Change-Id: I629f77041ce444dfff32b563795573174afea3a1
Signed-off-by: Scott Williams <scwilliams@nvidia.com>
Signed-off-by: Dan Willemsen <dwillemsen@nvidia.com>

Rebase-Id: R7a21e91127b44461d219a8bfd388f99ba7a72b53

arch/arm/mach-tegra/timer.c
arch/arm/mach-tegra/timer.h

index 73f3a17..93ef4fe 100644 (file)
@@ -33,6 +33,7 @@
 #include <asm/mach/time.h>
 #include <asm/delay.h>
 #include <asm/localtimer.h>
+#include <asm/smp_twd.h>
 #include <asm/sched_clock.h>
 
 #include <mach/irqs.h>
@@ -186,6 +187,7 @@ static struct syscore_ops tegra_timer_syscore_ops = {
 };
 
 #ifdef CONFIG_HAVE_ARM_TWD
+static void __iomem *twd_base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x600);
 static DEFINE_TWD_LOCAL_TIMER(twd_local_timer,
                              TEGRA_ARM_PERIF_BASE + 0x600,
                              IRQ_LOCALTIMER);
@@ -196,6 +198,19 @@ static void __init tegra_twd_init(void)
        if (err)
                pr_err("twd_local_timer_register failed %d\n", err);
 }
+
+void tegra_twd_suspend(struct tegra_twd_context *context)
+{
+       context->twd_ctrl = readl(twd_base + TWD_TIMER_CONTROL);
+       context->twd_load = readl(twd_base + TWD_TIMER_LOAD);
+       __raw_writel(0, twd_base + TWD_TIMER_CONTROL);
+}
+
+void tegra_twd_resume(struct tegra_twd_context *context)
+{
+       writel(context->twd_load, twd_base + TWD_TIMER_LOAD);
+       writel(context->twd_ctrl, twd_base + TWD_TIMER_CONTROL);
+}
 #else
 #define tegra_twd_init()       do {} while(0)
 #endif
index 3e29e54..6cd1f37 100644 (file)
@@ -35,4 +35,17 @@ void __init tegra2_init_timer(u32 *offset, int *irq, unsigned long rate);
 void __init tegra3_init_timer(u32 *offset, int *irq, unsigned long rate);
 #endif
 
+struct tegra_twd_context {
+       u32 twd_ctrl;
+       u32 twd_load;
+};
+
+#ifdef CONFIG_HAVE_ARM_TWD
+void tegra_twd_suspend(struct tegra_twd_context *context);
+void tegra_twd_resume(struct tegra_twd_context *context);
+#else
+static inline void tegra_twd_suspend(struct tegra_twd_context *context) {}
+static inline void tegra_twd_resume(struct tegra_twd_context *context) {}
+#endif
+
 #endif /* _MACH_TEGRA_TIMER_H_ */