extern int cpu_architecture(void);
extern void cpu_init(void);
+extern void cpu_suspend(int, long, unsigned long, void (*)(unsigned long));
+extern void cpu_resume(void);
void arm_machine_restart(char mode, const char *cmd);
extern void (*arm_pm_restart)(char str, const char *cmd);
* Save CPU state for a suspend
* r1 = v:p offset
* r2 = suspend function arg0
- * r3 = virtual return function
- * Note: sp is decremented to allocate space for CPU state on stack
- * r0-r3,ip,lr corrupted
+ * r3 = suspend function
+ * Note: does not return until system resumes
*/
ENTRY(cpu_suspend)
- stmfd sp!, {r3}
- stmfd sp!, {r4 - r11}
+ stmfd sp!, {r4 - r11, lr}
#ifdef MULTI_CPU
ldr r10, =processor
ldr r5, [r10, #CPU_SLEEP_SIZE] @ size of CPU sleep state
stmfd sp!, {r1, r6, ip} @ save v:p, virt SP, phys resume fn
ldr r5, =sleep_save_sp
add r6, sp, r1 @ convert SP to phys
- stmfd sp!, {r2, lr} @ save suspend func arg and pointer
+ stmfd sp!, {r2, r3} @ save suspend func arg and pointer
#ifdef CONFIG_SMP
ALT_SMP(mrc p15, 0, lr, c0, c0, 5)
ALT_UP(mov lr, #0)
ENTRY(s3c_cpu_save)
stmfd sp!, { r3 - r12, lr }
- ldr r3, =resume_with_mmu
+ adr r3, BSYM(exynos4_finish_suspend)
bl cpu_suspend
+ ldmfd sp!, { r3 - r12, pc }
+exynos4_finish_suspend:
ldr r0, =pm_cpu_sleep
ldr r0, [ r0 ]
mov pc, r0
-resume_with_mmu:
- ldmfd sp!, { r3 - r12, pc }
-
.ltorg
/*
#endif
stmfd sp!, {r2 - r12, lr} @ save registers on stack
mov r1, r0
- ldr r3, =pxa_cpu_resume @ resume function
+ adr r3, BSYM(pxa3xx_finish_suspend)
bl cpu_suspend
+ b pxa_cpu_resume
+pxa3xx_finish_suspend:
mov r0, #0x06 @ S2D3C4 mode
mcr p14, 0, r0, c7, c0, 0 @ enter sleep
#endif
stmfd sp!, {r2 - r12, lr} @ save registers on stack
mov r2, r0 @ save sleep mode
- ldr r3, =pxa_cpu_resume @ resume function
+ adr r3, BSYM(pxa27x_finish_suspend)
bl cpu_suspend
+ b pxa_cpu_resume
+pxa27x_finish_suspend:
@ Put the processor to sleep
@ (also workaround for sighting 28071)
ENTRY(pxa25x_cpu_suspend)
stmfd sp!, {r2 - r12, lr} @ save registers on stack
mov r2, r0 @ save sleep mode
- ldr r3, =pxa_cpu_resume @ resume function
+ adr r3, BSYM(pxa25x_finish_suspend)
bl cpu_suspend
+ b pxa_cpu_resume
+
+pxa25x_finish_suspend:
@ prepare value for sleep mode
mov r1, r0 @ sleep mode
ENTRY(s3c_cpu_save)
stmfd sp!, { r4 - r12, lr }
- ldr r3, =resume_with_mmu
+ adr r3, BSYM(s3c64xx_finish_suspend)
bl cpu_suspend
+ ldmfd sp!, { r4 - r12, pc }
+s3c64xx_finish_suspend:
@@ call final suspend code
ldr r0, =pm_cpu_sleep
ldr pc, [r0]
- @@ return to the caller, after the MMU is turned on.
- @@ restore the last bits of the stack and return.
-resume_with_mmu:
- ldmfd sp!, { r4 - r12, pc } @ return, from sp from s3c_cpu_save
-
/* Sleep magic, the word before the resume entry point so that the
* bootloader can check for a resumeable image. */
ENTRY(s3c_cpu_save)
stmfd sp!, { r3 - r12, lr }
- ldr r3, =resume_with_mmu
+ adr r3, BSYM(s5pv210_finish_suspend)
bl cpu_suspend
+ ldmfd sp!, { r3 - r12, pc }
+s5pv210_finish_suspend:
ldr r0, =pm_cpu_sleep
ldr r0, [ r0 ]
mov pc, r0
-resume_with_mmu:
- ldmfd sp!, { r3 - r12, pc }
-
.ltorg
/* sleep magic, to allow the bootloader to check for an valid
ENTRY(sa1100_cpu_suspend)
stmfd sp!, {r4 - r12, lr} @ save registers on stack
mov r1, r0
- ldr r3, =sa1100_cpu_resume @ return function
+ adr r3, BSYM(sa1100_finish_suspend)
bl cpu_suspend
+ ldmfd sp!, {r4 - r12, pc} @ return to caller
+sa1100_finish_suspend:
@ disable clock switching
mcr p15, 0, r1, c15, c2, 2
str r13, [r12]
20: b 20b @ loop waiting for sleep
-
-/*
- * cpu_sa1100_resume()
- *
- * entry point from bootloader into kernel during resume
- */
- .align 5
-sa1100_cpu_resume:
- ldmfd sp!, {r4 - r12, pc} @ return to caller
ENTRY(s3c_cpu_save)
stmfd sp!, { r4 - r12, lr }
- ldr r3, =resume_with_mmu
+ adr r3, BSYM(s3c24xx_finish_suspend)
bl cpu_suspend
+ ldmfd sp!, { r4 - r12, pc }
+s3c24xx_finish_suspend:
@@ 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:
- ldmfd sp!, { r4 - r12, pc }
-
.ltorg
/* sleep magic, to allow the bootloader to check for an valid