diff --git a/arch/arm/mach-s3c2410/pm.c b/arch/arm/mach-s3c2410/pm.c index 164a5b5847d7..46dedd37f438 100644 --- a/arch/arm/mach-s3c2410/pm.c +++ b/arch/arm/mach-s3c2410/pm.c @@ -35,6 +35,7 @@ #include #include +#include #include #include @@ -52,14 +53,6 @@ unsigned long s3c_pm_flags; -/* cache functions from arch/arm/mm/proc-arm920.S */ - -#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH -extern void arm920_flush_kern_cache_all(void); -#else -static void arm920_flush_kern_cache_all(void) { } -#endif - #define PFX "s3c24xx-pm: " static struct sleep_save core_save[] = { @@ -567,7 +560,7 @@ static int s3c2410_pm_enter(suspend_state_t state) /* flush cache back to ram */ - arm920_flush_kern_cache_all(); + flush_cache_all(); s3c2410_pm_check_store(); @@ -575,7 +568,14 @@ static int s3c2410_pm_enter(suspend_state_t state) __raw_writel(0x00, S3C2410_CLKCON); /* turn off clocks over sleep */ - s3c2410_cpu_suspend(regs_save); + /* 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 */ + + if (s3c2410_cpu_save(regs_save) == 0) { + flush_cache_all(); + s3c2410_cpu_suspend(); + } /* restore the cpu state */ diff --git a/arch/arm/mach-s3c2410/pm.h b/arch/arm/mach-s3c2410/pm.h index b04e4ca0bb4d..fa8e237cfee8 100644 --- a/arch/arm/mach-s3c2410/pm.h +++ b/arch/arm/mach-s3c2410/pm.h @@ -40,7 +40,8 @@ extern unsigned long s3c_pm_flags; /* from sleep.S */ -extern void s3c2410_cpu_suspend(unsigned long *saveblk); +extern int s3c2410_cpu_save(unsigned long *saveblk); +extern void s3c2410_cpu_suspend(void); extern void s3c2410_cpu_resume(void); extern unsigned long s3c2410_sleep_save_phys; diff --git a/arch/arm/mach-s3c2410/sleep.S b/arch/arm/mach-s3c2410/sleep.S index a7561a79fc82..e977aa1ffe18 100644 --- a/arch/arm/mach-s3c2410/sleep.S +++ b/arch/arm/mach-s3c2410/sleep.S @@ -41,15 +41,25 @@ .text - /* s3c2410_cpu_suspend + /* s3c2410_cpu_save * - * put the cpu into sleep mode + * 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 = sleep save block + * r0 = pointer to save block + * + * exit: + * r0 = 0 => we stored everything + * 1 => resumed from sleep */ -ENTRY(s3c2410_cpu_suspend) +ENTRY(s3c2410_cpu_save) stmfd sp!, { r4 - r12, lr } @@ store co-processor registers @@ -62,13 +72,15 @@ ENTRY(s3c2410_cpu_suspend) stmia r0, { r4 - r13 } - @@ flush the caches to ensure everything is back out to - @@ SDRAM before the core powers down + mov r0, #0 + ldmfd sp, { r4 - r12, pc } -#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH - bl arm920_flush_kern_cache_all -#endif + /* s3c2410_cpu_suspend + * + * put the cpu into sleep mode + */ +ENTRY(s3c2410_cpu_suspend) @@ prepare cpu to sleep ldr r4, =S3C2410_REFRESH @@ -100,6 +112,7 @@ s3c2410_do_sleep: @@ turned on, this restores the last bits from the @@ stack resume_with_mmu: + mov r0, #1 ldmfd sp!, { r4 - r12, pc } .ltorg