]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
[ARM] S3C: Tidy sleep code path to fix call flow
authorBen Dooks <ben-linux@fluff.org>
Tue, 10 Mar 2009 11:48:07 +0000 (11:48 +0000)
committerBen Dooks <ben-linux@fluff.org>
Tue, 10 Mar 2009 11:48:07 +0000 (11:48 +0000)
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>
arch/arm/plat-s3c/include/plat/pm.h
arch/arm/plat-s3c/pm.c
arch/arm/plat-s3c24xx/sleep.S

index 5ee26da27028dff142fcd0e190995b6bd74b527b..3779775133a9b487105b80fc86259b5d87204434 100644 (file)
@@ -162,5 +162,13 @@ extern void s3c_pm_restore_gpios(void);
  */
 extern void s3c_pm_save_gpios(void);
 
+/**
+ * s3c_pm_cb_flushcache - callback for assembly code
+ *
+ * Callback to issue flush_cache_all() as this call is
+ * not a directly callable object.
+ */
+extern void s3c_pm_cb_flushcache(void);
+
 extern void s3c_pm_save_core(void);
 extern void s3c_pm_restore_core(void);
index a0ca18a75b0e924f81a7d8e668453342d9411477..061182ca66e392246beae1abb29411339b338a8d 100644 (file)
@@ -229,7 +229,7 @@ void (*pm_cpu_sleep)(void);
 
 static int s3c_pm_enter(suspend_state_t state)
 {
-       unsigned long regs_save[16];
+       static unsigned long regs_save[16];
 
        /* ensure the debug is initialised (if enabled) */
 
@@ -289,15 +289,11 @@ static int s3c_pm_enter(suspend_state_t state)
 
        s3c_pm_arch_stop_clocks();
 
-       /* s3c2410_cpu_save will also act as our return point from when
-        * we resume as it saves its own register state, so use the return
-        * code to differentiate return from save and return from sleep */
+       /* s3c_cpu_save will also act as our return point from when
+        * we resume as it saves its own register state and restores it
+        * during the resume.  */
 
-       if (s3c_cpu_save(regs_save) == 0) {
-               flush_cache_all();
-               S3C_PMDBG("preparing to sleep\n");
-               pm_cpu_sleep();
-       }
+       s3c_cpu_save(regs_save);
 
        /* restore the cpu state using the kernel's cpu init code. */
 
@@ -325,6 +321,12 @@ static int s3c_pm_enter(suspend_state_t state)
        return 0;
 }
 
+/* callback from assembly code */
+void s3c_pm_cb_flushcache(void)
+{
+       flush_cache_all();
+}
+
 static int s3c_pm_prepare(void)
 {
        /* prepare check area if configured */
index ecb830be67d6d2520938c9d635cd20dc40672010..e73e3b6e88d2dfbb0a97ca074b0d7863f0eec282 100644 (file)
        .text
 
        /* s3c_cpu_save
-        *
-        * save enough of the CPU state to allow us to re-start
-        * pm.c code. as we store items like the sp/lr, we will
-        * end up returning from this function when the cpu resumes
-        * so the return value is set to mark this.
-        *
-        * This arangement means we avoid having to flush the cache
-        * from this code.
         *
         * entry:
-        *      r0 = pointer to save block
-        *
-        * exit:
-        *      r0 = 0 => we stored everything
-        *           1 => resumed from sleep
+        *      r0 = save address (virtual addr of s3c_sleep_save_phys)
        */
 
 ENTRY(s3c_cpu_save)
@@ -71,14 +59,19 @@ ENTRY(s3c_cpu_save)
 
        stmia   r0, { r4 - r13 }
 
-       mov     r0, #0
-       ldmfd   sp, { r4 - r12, pc }
+       @@ write our state back to RAM
+       bl      s3c_pm_cb_flushcache
 
+       @@ jump to final code to send system to sleep
+       ldr     r0, =pm_cpu_sleep
+       @@ldr   pc, [ r0 ]
+       ldr     r0, [ r0 ]
+       mov     pc, r0
+       
        @@ return to the caller, after having the MMU
        @@ turned on, this restores the last bits from the
        @@ stack
 resume_with_mmu:
-       mov     r0, #1
        ldmfd   sp!, { r4 - r12, pc }
 
        .ltorg