aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-prima2
diff options
context:
space:
mode:
authorBarry Song <baohua.song@csr.com>2011-09-21 08:56:33 -0400
committerBarry Song <21cnbao@gmail.com>2011-09-21 10:50:08 -0400
commite5598a855b0e63b77b67c4ab708e09a23228d14f (patch)
treef63f90eec4406b98990dedef4d86c8eac834ae37 /arch/arm/mach-prima2
parent684f741446f7a3108b4c167faf20214c42b7eeac (diff)
ARM: CSR: PM: save/restore timer status in suspend cycle
SiRFprimaII will lose power in deepsleep mode except rtc, pmu and sdram self-refresh. This patch saves timer-related registers while suspending and restore them while resuming. Signed-off-by: Barry Song <baohua.song@csr.com> Acked-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'arch/arm/mach-prima2')
-rw-r--r--arch/arm/mach-prima2/timer.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/arch/arm/mach-prima2/timer.c b/arch/arm/mach-prima2/timer.c
index ed7ec48d11d..3b159615de2 100644
--- a/arch/arm/mach-prima2/timer.c
+++ b/arch/arm/mach-prima2/timer.c
@@ -40,6 +40,17 @@
40 40
41#define SIRFSOC_TIMER_LATCH_BIT BIT(0) 41#define SIRFSOC_TIMER_LATCH_BIT BIT(0)
42 42
43#define SIRFSOC_TIMER_REG_CNT 11
44
45static const u32 sirfsoc_timer_reg_list[SIRFSOC_TIMER_REG_CNT] = {
46 SIRFSOC_TIMER_MATCH_0, SIRFSOC_TIMER_MATCH_1, SIRFSOC_TIMER_MATCH_2,
47 SIRFSOC_TIMER_MATCH_3, SIRFSOC_TIMER_MATCH_4, SIRFSOC_TIMER_MATCH_5,
48 SIRFSOC_TIMER_INT_EN, SIRFSOC_TIMER_WATCHDOG_EN, SIRFSOC_TIMER_DIV,
49 SIRFSOC_TIMER_LATCHED_LO, SIRFSOC_TIMER_LATCHED_HI,
50};
51
52static u32 sirfsoc_timer_reg_val[SIRFSOC_TIMER_REG_CNT];
53
43static void __iomem *sirfsoc_timer_base; 54static void __iomem *sirfsoc_timer_base;
44static void __init sirfsoc_of_timer_map(void); 55static void __init sirfsoc_of_timer_map(void);
45 56
@@ -106,6 +117,27 @@ static void sirfsoc_timer_set_mode(enum clock_event_mode mode,
106 } 117 }
107} 118}
108 119
120static void sirfsoc_clocksource_suspend(struct clocksource *cs)
121{
122 int i;
123
124 writel_relaxed(SIRFSOC_TIMER_LATCH_BIT, sirfsoc_timer_base + SIRFSOC_TIMER_LATCH);
125
126 for (i = 0; i < SIRFSOC_TIMER_REG_CNT; i++)
127 sirfsoc_timer_reg_val[i] = readl_relaxed(sirfsoc_timer_base + sirfsoc_timer_reg_list[i]);
128}
129
130static void sirfsoc_clocksource_resume(struct clocksource *cs)
131{
132 int i;
133
134 for (i = 0; i < SIRFSOC_TIMER_REG_CNT; i++)
135 writel_relaxed(sirfsoc_timer_reg_val[i], sirfsoc_timer_base + sirfsoc_timer_reg_list[i]);
136
137 writel_relaxed(sirfsoc_timer_reg_val[i - 2], sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_LO);
138 writel_relaxed(sirfsoc_timer_reg_val[i - 1], sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_HI);
139}
140
109static struct clock_event_device sirfsoc_clockevent = { 141static struct clock_event_device sirfsoc_clockevent = {
110 .name = "sirfsoc_clockevent", 142 .name = "sirfsoc_clockevent",
111 .rating = 200, 143 .rating = 200,
@@ -120,6 +152,8 @@ static struct clocksource sirfsoc_clocksource = {
120 .mask = CLOCKSOURCE_MASK(64), 152 .mask = CLOCKSOURCE_MASK(64),
121 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 153 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
122 .read = sirfsoc_timer_read, 154 .read = sirfsoc_timer_read,
155 .suspend = sirfsoc_clocksource_suspend,
156 .resume = sirfsoc_clocksource_resume,
123}; 157};
124 158
125static struct irqaction sirfsoc_timer_irq = { 159static struct irqaction sirfsoc_timer_irq = {