diff options
author | Russell King <rmk@dyn-67.arm.linux.org.uk> | 2008-08-27 07:55:04 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2008-09-09 11:32:52 -0400 |
commit | 4104980a3c21801f701e53961375b3d736ee9a73 (patch) | |
tree | f2c0b6759e45fd696a138a4ff32caabc513f32af /arch/arm | |
parent | 63bef5473892ae683a9e989975180a5754b0ae33 (diff) |
[ARM] pxa: Allow platforms to override PSPR setting
Currently, we set PSPR just before entering sleep mode. However,
some platforms have different requirements for setting PSPR in
order to properly wake up.
Set PSPR earlier in the suspend cycle so that platforms can
change the setting by using a sysdev driver instead.
Acked-by: Eric Miao <eric.miao@marvell.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/mach-pxa/include/mach/pm.h | 2 | ||||
-rw-r--r-- | arch/arm/mach-pxa/pm.c | 18 | ||||
-rw-r--r-- | arch/arm/mach-pxa/pxa25x.c | 20 | ||||
-rw-r--r-- | arch/arm/mach-pxa/pxa27x.c | 20 |
4 files changed, 50 insertions, 10 deletions
diff --git a/arch/arm/mach-pxa/include/mach/pm.h b/arch/arm/mach-pxa/include/mach/pm.h index 261e5bc958db..83342469acac 100644 --- a/arch/arm/mach-pxa/include/mach/pm.h +++ b/arch/arm/mach-pxa/include/mach/pm.h | |||
@@ -15,6 +15,8 @@ struct pxa_cpu_pm_fns { | |||
15 | void (*restore)(unsigned long *); | 15 | void (*restore)(unsigned long *); |
16 | int (*valid)(suspend_state_t state); | 16 | int (*valid)(suspend_state_t state); |
17 | void (*enter)(suspend_state_t state); | 17 | void (*enter)(suspend_state_t state); |
18 | int (*prepare)(void); | ||
19 | void (*finish)(void); | ||
18 | }; | 20 | }; |
19 | 21 | ||
20 | extern struct pxa_cpu_pm_fns *pxa_cpu_pm_fns; | 22 | extern struct pxa_cpu_pm_fns *pxa_cpu_pm_fns; |
diff --git a/arch/arm/mach-pxa/pm.c b/arch/arm/mach-pxa/pm.c index 1b539e675579..164eb0bb6321 100644 --- a/arch/arm/mach-pxa/pm.c +++ b/arch/arm/mach-pxa/pm.c | |||
@@ -86,9 +86,27 @@ static int pxa_pm_valid(suspend_state_t state) | |||
86 | return -EINVAL; | 86 | return -EINVAL; |
87 | } | 87 | } |
88 | 88 | ||
89 | static int pxa_pm_prepare(void) | ||
90 | { | ||
91 | int ret = 0; | ||
92 | |||
93 | if (pxa_cpu_pm_fns && pxa_cpu_pm_fns->prepare) | ||
94 | ret = pxa_cpu_pm_fns->prepare(); | ||
95 | |||
96 | return ret; | ||
97 | } | ||
98 | |||
99 | static void pxa_pm_finish(void) | ||
100 | { | ||
101 | if (pxa_cpu_pm_fns && pxa_cpu_pm_fns->finish) | ||
102 | pxa_cpu_pm_fns->finish(); | ||
103 | } | ||
104 | |||
89 | static struct platform_suspend_ops pxa_pm_ops = { | 105 | static struct platform_suspend_ops pxa_pm_ops = { |
90 | .valid = pxa_pm_valid, | 106 | .valid = pxa_pm_valid, |
91 | .enter = pxa_pm_enter, | 107 | .enter = pxa_pm_enter, |
108 | .prepare = pxa_pm_prepare, | ||
109 | .finish = pxa_pm_finish, | ||
92 | }; | 110 | }; |
93 | 111 | ||
94 | static int __init pxa_pm_init(void) | 112 | static int __init pxa_pm_init(void) |
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c index 305452b56e91..db7be22ccd17 100644 --- a/arch/arm/mach-pxa/pxa25x.c +++ b/arch/arm/mach-pxa/pxa25x.c | |||
@@ -234,9 +234,6 @@ static void pxa25x_cpu_pm_save(unsigned long *sleep_save) | |||
234 | 234 | ||
235 | static void pxa25x_cpu_pm_restore(unsigned long *sleep_save) | 235 | static void pxa25x_cpu_pm_restore(unsigned long *sleep_save) |
236 | { | 236 | { |
237 | /* ensure not to come back here if it wasn't intended */ | ||
238 | PSPR = 0; | ||
239 | |||
240 | /* restore registers */ | 237 | /* restore registers */ |
241 | RESTORE(GAFR0_L); RESTORE(GAFR0_U); | 238 | RESTORE(GAFR0_L); RESTORE(GAFR0_U); |
242 | RESTORE(GAFR1_L); RESTORE(GAFR1_U); | 239 | RESTORE(GAFR1_L); RESTORE(GAFR1_U); |
@@ -256,19 +253,32 @@ static void pxa25x_cpu_pm_enter(suspend_state_t state) | |||
256 | 253 | ||
257 | switch (state) { | 254 | switch (state) { |
258 | case PM_SUSPEND_MEM: | 255 | case PM_SUSPEND_MEM: |
259 | /* set resume return address */ | ||
260 | PSPR = virt_to_phys(pxa_cpu_resume); | ||
261 | pxa25x_cpu_suspend(PWRMODE_SLEEP); | 256 | pxa25x_cpu_suspend(PWRMODE_SLEEP); |
262 | break; | 257 | break; |
263 | } | 258 | } |
264 | } | 259 | } |
265 | 260 | ||
261 | static int pxa25x_cpu_pm_prepare(void) | ||
262 | { | ||
263 | /* set resume return address */ | ||
264 | PSPR = virt_to_phys(pxa_cpu_resume); | ||
265 | return 0; | ||
266 | } | ||
267 | |||
268 | static void pxa25x_cpu_pm_finish(void) | ||
269 | { | ||
270 | /* ensure not to come back here if it wasn't intended */ | ||
271 | PSPR = 0; | ||
272 | } | ||
273 | |||
266 | static struct pxa_cpu_pm_fns pxa25x_cpu_pm_fns = { | 274 | static struct pxa_cpu_pm_fns pxa25x_cpu_pm_fns = { |
267 | .save_count = SLEEP_SAVE_COUNT, | 275 | .save_count = SLEEP_SAVE_COUNT, |
268 | .valid = suspend_valid_only_mem, | 276 | .valid = suspend_valid_only_mem, |
269 | .save = pxa25x_cpu_pm_save, | 277 | .save = pxa25x_cpu_pm_save, |
270 | .restore = pxa25x_cpu_pm_restore, | 278 | .restore = pxa25x_cpu_pm_restore, |
271 | .enter = pxa25x_cpu_pm_enter, | 279 | .enter = pxa25x_cpu_pm_enter, |
280 | .prepare = pxa25x_cpu_pm_prepare, | ||
281 | .finish = pxa25x_cpu_pm_finish, | ||
272 | }; | 282 | }; |
273 | 283 | ||
274 | static void __init pxa25x_init_pm(void) | 284 | static void __init pxa25x_init_pm(void) |
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c index c33cf6ac8c81..4835207c1426 100644 --- a/arch/arm/mach-pxa/pxa27x.c +++ b/arch/arm/mach-pxa/pxa27x.c | |||
@@ -220,9 +220,6 @@ void pxa27x_cpu_pm_save(unsigned long *sleep_save) | |||
220 | 220 | ||
221 | void pxa27x_cpu_pm_restore(unsigned long *sleep_save) | 221 | void pxa27x_cpu_pm_restore(unsigned long *sleep_save) |
222 | { | 222 | { |
223 | /* ensure not to come back here if it wasn't intended */ | ||
224 | PSPR = 0; | ||
225 | |||
226 | /* restore registers */ | 223 | /* restore registers */ |
227 | RESTORE(GAFR0_L); RESTORE(GAFR0_U); | 224 | RESTORE(GAFR0_L); RESTORE(GAFR0_U); |
228 | RESTORE(GAFR1_L); RESTORE(GAFR1_U); | 225 | RESTORE(GAFR1_L); RESTORE(GAFR1_U); |
@@ -259,8 +256,6 @@ void pxa27x_cpu_pm_enter(suspend_state_t state) | |||
259 | pxa_cpu_standby(); | 256 | pxa_cpu_standby(); |
260 | break; | 257 | break; |
261 | case PM_SUSPEND_MEM: | 258 | case PM_SUSPEND_MEM: |
262 | /* set resume return address */ | ||
263 | PSPR = virt_to_phys(pxa_cpu_resume); | ||
264 | pxa27x_cpu_suspend(PWRMODE_SLEEP); | 259 | pxa27x_cpu_suspend(PWRMODE_SLEEP); |
265 | break; | 260 | break; |
266 | } | 261 | } |
@@ -271,12 +266,27 @@ static int pxa27x_cpu_pm_valid(suspend_state_t state) | |||
271 | return state == PM_SUSPEND_MEM || state == PM_SUSPEND_STANDBY; | 266 | return state == PM_SUSPEND_MEM || state == PM_SUSPEND_STANDBY; |
272 | } | 267 | } |
273 | 268 | ||
269 | static int pxa27x_cpu_pm_prepare(void) | ||
270 | { | ||
271 | /* set resume return address */ | ||
272 | PSPR = virt_to_phys(pxa_cpu_resume); | ||
273 | return 0; | ||
274 | } | ||
275 | |||
276 | static void pxa27x_cpu_pm_finish(void) | ||
277 | { | ||
278 | /* ensure not to come back here if it wasn't intended */ | ||
279 | PSPR = 0; | ||
280 | } | ||
281 | |||
274 | static struct pxa_cpu_pm_fns pxa27x_cpu_pm_fns = { | 282 | static struct pxa_cpu_pm_fns pxa27x_cpu_pm_fns = { |
275 | .save_count = SLEEP_SAVE_COUNT, | 283 | .save_count = SLEEP_SAVE_COUNT, |
276 | .save = pxa27x_cpu_pm_save, | 284 | .save = pxa27x_cpu_pm_save, |
277 | .restore = pxa27x_cpu_pm_restore, | 285 | .restore = pxa27x_cpu_pm_restore, |
278 | .valid = pxa27x_cpu_pm_valid, | 286 | .valid = pxa27x_cpu_pm_valid, |
279 | .enter = pxa27x_cpu_pm_enter, | 287 | .enter = pxa27x_cpu_pm_enter, |
288 | .prepare = pxa27x_cpu_pm_prepare, | ||
289 | .finish = pxa27x_cpu_pm_finish, | ||
280 | }; | 290 | }; |
281 | 291 | ||
282 | static void __init pxa27x_init_pm(void) | 292 | static void __init pxa27x_init_pm(void) |