diff options
author | Barry Song <baohua.song@csr.com> | 2011-09-21 08:56:33 -0400 |
---|---|---|
committer | Barry Song <21cnbao@gmail.com> | 2011-09-21 10:50:08 -0400 |
commit | e5598a855b0e63b77b67c4ab708e09a23228d14f (patch) | |
tree | f63f90eec4406b98990dedef4d86c8eac834ae37 /arch/arm/mach-prima2 | |
parent | 684f741446f7a3108b4c167faf20214c42b7eeac (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.c | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/arch/arm/mach-prima2/timer.c b/arch/arm/mach-prima2/timer.c index ed7ec48d11da..3b159615de24 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 | |||
45 | static 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 | |||
52 | static u32 sirfsoc_timer_reg_val[SIRFSOC_TIMER_REG_CNT]; | ||
53 | |||
43 | static void __iomem *sirfsoc_timer_base; | 54 | static void __iomem *sirfsoc_timer_base; |
44 | static void __init sirfsoc_of_timer_map(void); | 55 | static 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 | ||
120 | static 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 | |||
130 | static 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 | |||
109 | static struct clock_event_device sirfsoc_clockevent = { | 141 | static 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 | ||
125 | static struct irqaction sirfsoc_timer_irq = { | 159 | static struct irqaction sirfsoc_timer_irq = { |