aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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 5ee26da2702..3779775133a 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);
*/
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);
diff --git a/arch/arm/plat-s3c/pm.c b/arch/arm/plat-s3c/pm.c
index a0ca18a75b0..061182ca66e 100644
--- a/arch/arm/plat-s3c/pm.c
+++ b/arch/arm/plat-s3c/pm.c
@@ -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 */
diff --git a/arch/arm/plat-s3c24xx/sleep.S b/arch/arm/plat-s3c24xx/sleep.S
index ecb830be67d..e73e3b6e88d 100644
--- a/arch/arm/plat-s3c24xx/sleep.S
+++ b/arch/arm/plat-s3c24xx/sleep.S
@@ -43,20 +43,8 @@
/* 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