diff options
author | Ben Dooks <ben-linux@fluff.org> | 2009-03-10 07:48:07 -0400 |
---|---|---|
committer | Ben Dooks <ben-linux@fluff.org> | 2009-03-10 07:48:07 -0400 |
commit | fff94cd9f5527bbba13aa5ea5719d16531ca8e65 (patch) | |
tree | bddf3ef686410872d8da882688229688710d574b | |
parent | aa8aba6944203a17a7e941b42d8415153c649660 (diff) |
[ARM] S3C: Tidy sleep code path to fix call flow
As noted by Russell King, the sleep code path is not
elegant and makes use of leaving items on the stack
between calls.
Change the code that does the following:
if (s3c_cpu_save(regs_save) == 0) {
flush_cache_all();
S3C_PMDBG("preparing to sleep\n");
pm_cpu_sleep();
}
to simply call s3c_cpu_save, and let that do the
necessary calls to quiesce and sleep the system.
Signed-off-by: Ben Dooks <ben-linux@fluff.org>
-rw-r--r-- | arch/arm/plat-s3c/include/plat/pm.h | 8 | ||||
-rw-r--r-- | arch/arm/plat-s3c/pm.c | 20 | ||||
-rw-r--r-- | arch/arm/plat-s3c24xx/sleep.S | 25 |
3 files changed, 28 insertions, 25 deletions
diff --git a/arch/arm/plat-s3c/include/plat/pm.h b/arch/arm/plat-s3c/include/plat/pm.h index 5ee26da27028..3779775133a9 100644 --- a/arch/arm/plat-s3c/include/plat/pm.h +++ b/arch/arm/plat-s3c/include/plat/pm.h | |||
@@ -162,5 +162,13 @@ extern void s3c_pm_restore_gpios(void); | |||
162 | */ | 162 | */ |
163 | extern void s3c_pm_save_gpios(void); | 163 | extern void s3c_pm_save_gpios(void); |
164 | 164 | ||
165 | /** | ||
166 | * s3c_pm_cb_flushcache - callback for assembly code | ||
167 | * | ||
168 | * Callback to issue flush_cache_all() as this call is | ||
169 | * not a directly callable object. | ||
170 | */ | ||
171 | extern void s3c_pm_cb_flushcache(void); | ||
172 | |||
165 | extern void s3c_pm_save_core(void); | 173 | extern void s3c_pm_save_core(void); |
166 | extern void s3c_pm_restore_core(void); | 174 | extern void s3c_pm_restore_core(void); |
diff --git a/arch/arm/plat-s3c/pm.c b/arch/arm/plat-s3c/pm.c index a0ca18a75b0e..061182ca66e3 100644 --- a/arch/arm/plat-s3c/pm.c +++ b/arch/arm/plat-s3c/pm.c | |||
@@ -229,7 +229,7 @@ void (*pm_cpu_sleep)(void); | |||
229 | 229 | ||
230 | static int s3c_pm_enter(suspend_state_t state) | 230 | static int s3c_pm_enter(suspend_state_t state) |
231 | { | 231 | { |
232 | unsigned long regs_save[16]; | 232 | static unsigned long regs_save[16]; |
233 | 233 | ||
234 | /* ensure the debug is initialised (if enabled) */ | 234 | /* ensure the debug is initialised (if enabled) */ |
235 | 235 | ||
@@ -289,15 +289,11 @@ static int s3c_pm_enter(suspend_state_t state) | |||
289 | 289 | ||
290 | s3c_pm_arch_stop_clocks(); | 290 | s3c_pm_arch_stop_clocks(); |
291 | 291 | ||
292 | /* s3c2410_cpu_save will also act as our return point from when | 292 | /* s3c_cpu_save will also act as our return point from when |
293 | * we resume as it saves its own register state, so use the return | 293 | * we resume as it saves its own register state and restores it |
294 | * code to differentiate return from save and return from sleep */ | 294 | * during the resume. */ |
295 | 295 | ||
296 | if (s3c_cpu_save(regs_save) == 0) { | 296 | s3c_cpu_save(regs_save); |
297 | flush_cache_all(); | ||
298 | S3C_PMDBG("preparing to sleep\n"); | ||
299 | pm_cpu_sleep(); | ||
300 | } | ||
301 | 297 | ||
302 | /* restore the cpu state using the kernel's cpu init code. */ | 298 | /* restore the cpu state using the kernel's cpu init code. */ |
303 | 299 | ||
@@ -325,6 +321,12 @@ static int s3c_pm_enter(suspend_state_t state) | |||
325 | return 0; | 321 | return 0; |
326 | } | 322 | } |
327 | 323 | ||
324 | /* callback from assembly code */ | ||
325 | void s3c_pm_cb_flushcache(void) | ||
326 | { | ||
327 | flush_cache_all(); | ||
328 | } | ||
329 | |||
328 | static int s3c_pm_prepare(void) | 330 | static int s3c_pm_prepare(void) |
329 | { | 331 | { |
330 | /* prepare check area if configured */ | 332 | /* prepare check area if configured */ |
diff --git a/arch/arm/plat-s3c24xx/sleep.S b/arch/arm/plat-s3c24xx/sleep.S index ecb830be67d6..e73e3b6e88d2 100644 --- a/arch/arm/plat-s3c24xx/sleep.S +++ b/arch/arm/plat-s3c24xx/sleep.S | |||
@@ -43,20 +43,8 @@ | |||
43 | 43 | ||
44 | /* s3c_cpu_save | 44 | /* s3c_cpu_save |
45 | * | 45 | * |
46 | * save enough of the CPU state to allow us to re-start | ||
47 | * pm.c code. as we store items like the sp/lr, we will | ||
48 | * end up returning from this function when the cpu resumes | ||
49 | * so the return value is set to mark this. | ||
50 | * | ||
51 | * This arangement means we avoid having to flush the cache | ||
52 | * from this code. | ||
53 | * | ||
54 | * entry: | 46 | * entry: |
55 | * r0 = pointer to save block | 47 | * r0 = save address (virtual addr of s3c_sleep_save_phys) |
56 | * | ||
57 | * exit: | ||
58 | * r0 = 0 => we stored everything | ||
59 | * 1 => resumed from sleep | ||
60 | */ | 48 | */ |
61 | 49 | ||
62 | ENTRY(s3c_cpu_save) | 50 | ENTRY(s3c_cpu_save) |
@@ -71,14 +59,19 @@ ENTRY(s3c_cpu_save) | |||
71 | 59 | ||
72 | stmia r0, { r4 - r13 } | 60 | stmia r0, { r4 - r13 } |
73 | 61 | ||
74 | mov r0, #0 | 62 | @@ write our state back to RAM |
75 | ldmfd sp, { r4 - r12, pc } | 63 | bl s3c_pm_cb_flushcache |
76 | 64 | ||
65 | @@ jump to final code to send system to sleep | ||
66 | ldr r0, =pm_cpu_sleep | ||
67 | @@ldr pc, [ r0 ] | ||
68 | ldr r0, [ r0 ] | ||
69 | mov pc, r0 | ||
70 | |||
77 | @@ return to the caller, after having the MMU | 71 | @@ return to the caller, after having the MMU |
78 | @@ turned on, this restores the last bits from the | 72 | @@ turned on, this restores the last bits from the |
79 | @@ stack | 73 | @@ stack |
80 | resume_with_mmu: | 74 | resume_with_mmu: |
81 | mov r0, #1 | ||
82 | ldmfd sp!, { r4 - r12, pc } | 75 | ldmfd sp!, { r4 - r12, pc } |
83 | 76 | ||
84 | .ltorg | 77 | .ltorg |