aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorBen Dooks <ben-linux@fluff.org>2009-03-10 07:48:07 -0400
committerBen Dooks <ben-linux@fluff.org>2009-03-10 07:48:07 -0400
commitfff94cd9f5527bbba13aa5ea5719d16531ca8e65 (patch)
treebddf3ef686410872d8da882688229688710d574b /arch
parentaa8aba6944203a17a7e941b42d8415153c649660 (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>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/plat-s3c/include/plat/pm.h8
-rw-r--r--arch/arm/plat-s3c/pm.c20
-rw-r--r--arch/arm/plat-s3c24xx/sleep.S25
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 */
163extern void s3c_pm_save_gpios(void); 163extern 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 */
171extern void s3c_pm_cb_flushcache(void);
172
165extern void s3c_pm_save_core(void); 173extern void s3c_pm_save_core(void);
166extern void s3c_pm_restore_core(void); 174extern 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
230static int s3c_pm_enter(suspend_state_t state) 230static 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 */
325void s3c_pm_cb_flushcache(void)
326{
327 flush_cache_all();
328}
329
328static int s3c_pm_prepare(void) 330static 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
62ENTRY(s3c_cpu_save) 50ENTRY(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
80resume_with_mmu: 74resume_with_mmu:
81 mov r0, #1
82 ldmfd sp!, { r4 - r12, pc } 75 ldmfd sp!, { r4 - r12, pc }
83 76
84 .ltorg 77 .ltorg