diff options
Diffstat (limited to 'arch/arm/mach-at91/pm.c')
-rw-r--r-- | arch/arm/mach-at91/pm.c | 50 |
1 files changed, 19 insertions, 31 deletions
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index 62ad95556c36..f630250c6b87 100644 --- a/arch/arm/mach-at91/pm.c +++ b/arch/arm/mach-at91/pm.c | |||
@@ -34,7 +34,6 @@ | |||
34 | /* | 34 | /* |
35 | * Show the reason for the previous system reset. | 35 | * Show the reason for the previous system reset. |
36 | */ | 36 | */ |
37 | #if defined(AT91_RSTC) | ||
38 | 37 | ||
39 | #include <mach/at91_rstc.h> | 38 | #include <mach/at91_rstc.h> |
40 | #include <mach/at91_shdwc.h> | 39 | #include <mach/at91_shdwc.h> |
@@ -58,10 +57,10 @@ static void __init show_reset_status(void) | |||
58 | char *reason, *r2 = reset; | 57 | char *reason, *r2 = reset; |
59 | u32 reset_type, wake_type; | 58 | u32 reset_type, wake_type; |
60 | 59 | ||
61 | if (!at91_shdwc_base) | 60 | if (!at91_shdwc_base || !at91_rstc_base) |
62 | return; | 61 | return; |
63 | 62 | ||
64 | reset_type = at91_sys_read(AT91_RSTC_SR) & AT91_RSTC_RSTTYP; | 63 | reset_type = at91_rstc_read(AT91_RSTC_SR) & AT91_RSTC_RSTTYP; |
65 | wake_type = at91_shdwc_read(AT91_SHDW_SR); | 64 | wake_type = at91_shdwc_read(AT91_SHDW_SR); |
66 | 65 | ||
67 | switch (reset_type) { | 66 | switch (reset_type) { |
@@ -102,10 +101,6 @@ static void __init show_reset_status(void) | |||
102 | } | 101 | } |
103 | pr_info("AT91: Starting after %s %s\n", reason, r2); | 102 | pr_info("AT91: Starting after %s %s\n", reason, r2); |
104 | } | 103 | } |
105 | #else | ||
106 | static void __init show_reset_status(void) {} | ||
107 | #endif | ||
108 | |||
109 | 104 | ||
110 | static int at91_pm_valid_state(suspend_state_t state) | 105 | static int at91_pm_valid_state(suspend_state_t state) |
111 | { | 106 | { |
@@ -141,7 +136,7 @@ static int at91_pm_verify_clocks(void) | |||
141 | unsigned long scsr; | 136 | unsigned long scsr; |
142 | int i; | 137 | int i; |
143 | 138 | ||
144 | scsr = at91_sys_read(AT91_PMC_SCSR); | 139 | scsr = at91_pmc_read(AT91_PMC_SCSR); |
145 | 140 | ||
146 | /* USB must not be using PLLB */ | 141 | /* USB must not be using PLLB */ |
147 | if (cpu_is_at91rm9200()) { | 142 | if (cpu_is_at91rm9200()) { |
@@ -155,11 +150,6 @@ static int at91_pm_verify_clocks(void) | |||
155 | pr_err("AT91: PM - Suspend-to-RAM with USB still active\n"); | 150 | pr_err("AT91: PM - Suspend-to-RAM with USB still active\n"); |
156 | return 0; | 151 | return 0; |
157 | } | 152 | } |
158 | } else if (cpu_is_at91cap9()) { | ||
159 | if ((scsr & AT91CAP9_PMC_UHP) != 0) { | ||
160 | pr_err("AT91: PM - Suspend-to-RAM with USB still active\n"); | ||
161 | return 0; | ||
162 | } | ||
163 | } | 153 | } |
164 | 154 | ||
165 | #ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS | 155 | #ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS |
@@ -170,7 +160,7 @@ static int at91_pm_verify_clocks(void) | |||
170 | if ((scsr & (AT91_PMC_PCK0 << i)) == 0) | 160 | if ((scsr & (AT91_PMC_PCK0 << i)) == 0) |
171 | continue; | 161 | continue; |
172 | 162 | ||
173 | css = at91_sys_read(AT91_PMC_PCKR(i)) & AT91_PMC_CSS; | 163 | css = at91_pmc_read(AT91_PMC_PCKR(i)) & AT91_PMC_CSS; |
174 | if (css != AT91_PMC_CSS_SLOW) { | 164 | if (css != AT91_PMC_CSS_SLOW) { |
175 | pr_err("AT91: PM - Suspend-to-RAM with PCK%d src %d\n", i, css); | 165 | pr_err("AT91: PM - Suspend-to-RAM with PCK%d src %d\n", i, css); |
176 | return 0; | 166 | return 0; |
@@ -198,23 +188,23 @@ int at91_suspend_entering_slow_clock(void) | |||
198 | EXPORT_SYMBOL(at91_suspend_entering_slow_clock); | 188 | EXPORT_SYMBOL(at91_suspend_entering_slow_clock); |
199 | 189 | ||
200 | 190 | ||
201 | static void (*slow_clock)(void); | 191 | static void (*slow_clock)(void __iomem *pmc, void __iomem *ramc0, |
192 | void __iomem *ramc1, int memctrl); | ||
202 | 193 | ||
203 | #ifdef CONFIG_AT91_SLOW_CLOCK | 194 | #ifdef CONFIG_AT91_SLOW_CLOCK |
204 | extern void at91_slow_clock(void); | 195 | extern void at91_slow_clock(void __iomem *pmc, void __iomem *ramc0, |
196 | void __iomem *ramc1, int memctrl); | ||
205 | extern u32 at91_slow_clock_sz; | 197 | extern u32 at91_slow_clock_sz; |
206 | #endif | 198 | #endif |
207 | 199 | ||
208 | |||
209 | static int at91_pm_enter(suspend_state_t state) | 200 | static int at91_pm_enter(suspend_state_t state) |
210 | { | 201 | { |
211 | u32 saved_lpr; | ||
212 | at91_gpio_suspend(); | 202 | at91_gpio_suspend(); |
213 | at91_irq_suspend(); | 203 | at91_irq_suspend(); |
214 | 204 | ||
215 | pr_debug("AT91: PM - wake mask %08x, pm state %d\n", | 205 | pr_debug("AT91: PM - wake mask %08x, pm state %d\n", |
216 | /* remember all the always-wake irqs */ | 206 | /* remember all the always-wake irqs */ |
217 | (at91_sys_read(AT91_PMC_PCSR) | 207 | (at91_pmc_read(AT91_PMC_PCSR) |
218 | | (1 << AT91_ID_FIQ) | 208 | | (1 << AT91_ID_FIQ) |
219 | | (1 << AT91_ID_SYS) | 209 | | (1 << AT91_ID_SYS) |
220 | | (at91_extern_irq)) | 210 | | (at91_extern_irq)) |
@@ -239,11 +229,18 @@ static int at91_pm_enter(suspend_state_t state) | |||
239 | * turning off the main oscillator; reverse on wakeup. | 229 | * turning off the main oscillator; reverse on wakeup. |
240 | */ | 230 | */ |
241 | if (slow_clock) { | 231 | if (slow_clock) { |
232 | int memctrl = AT91_MEMCTRL_SDRAMC; | ||
233 | |||
234 | if (cpu_is_at91rm9200()) | ||
235 | memctrl = AT91_MEMCTRL_MC; | ||
236 | else if (cpu_is_at91sam9g45()) | ||
237 | memctrl = AT91_MEMCTRL_DDRSDR; | ||
242 | #ifdef CONFIG_AT91_SLOW_CLOCK | 238 | #ifdef CONFIG_AT91_SLOW_CLOCK |
243 | /* copy slow_clock handler to SRAM, and call it */ | 239 | /* copy slow_clock handler to SRAM, and call it */ |
244 | memcpy(slow_clock, at91_slow_clock, at91_slow_clock_sz); | 240 | memcpy(slow_clock, at91_slow_clock, at91_slow_clock_sz); |
245 | #endif | 241 | #endif |
246 | slow_clock(); | 242 | slow_clock(at91_pmc_base, at91_ramc_base[0], |
243 | at91_ramc_base[1], memctrl); | ||
247 | break; | 244 | break; |
248 | } else { | 245 | } else { |
249 | pr_info("AT91: PM - no slow clock mode enabled ...\n"); | 246 | pr_info("AT91: PM - no slow clock mode enabled ...\n"); |
@@ -264,16 +261,7 @@ static int at91_pm_enter(suspend_state_t state) | |||
264 | * For ARM 926 based chips, this requirement is weaker | 261 | * For ARM 926 based chips, this requirement is weaker |
265 | * as at91sam9 can access a RAM in self-refresh mode. | 262 | * as at91sam9 can access a RAM in self-refresh mode. |
266 | */ | 263 | */ |
267 | asm volatile ( "mov r0, #0\n\t" | 264 | at91_standby(); |
268 | "b 1f\n\t" | ||
269 | ".align 5\n\t" | ||
270 | "1: mcr p15, 0, r0, c7, c10, 4\n\t" | ||
271 | : /* no output */ | ||
272 | : /* no input */ | ||
273 | : "r0"); | ||
274 | saved_lpr = sdram_selfrefresh_enable(); | ||
275 | wait_for_interrupt_enable(); | ||
276 | sdram_selfrefresh_disable(saved_lpr); | ||
277 | break; | 265 | break; |
278 | 266 | ||
279 | case PM_SUSPEND_ON: | 267 | case PM_SUSPEND_ON: |
@@ -321,7 +309,7 @@ static int __init at91_pm_init(void) | |||
321 | 309 | ||
322 | #ifdef CONFIG_ARCH_AT91RM9200 | 310 | #ifdef CONFIG_ARCH_AT91RM9200 |
323 | /* AT91RM9200 SDRAM low-power mode cannot be used with self-refresh. */ | 311 | /* AT91RM9200 SDRAM low-power mode cannot be used with self-refresh. */ |
324 | at91_sys_write(AT91_SDRAMC_LPR, 0); | 312 | at91_ramc_write(0, AT91RM9200_SDRAMC_LPR, 0); |
325 | #endif | 313 | #endif |
326 | 314 | ||
327 | suspend_set_ops(&at91_pm_ops); | 315 | suspend_set_ops(&at91_pm_ops); |