aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2011-02-11 06:32:19 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2011-02-22 12:11:26 -0500
commit941aefac4c243cf407d7665d3e64beb32d556acf (patch)
tree1e43bde1d1c50d028f8c677f396fa95f194b2687 /arch/arm/kernel
parent2e2f3d3792de5913897b6bb49ac13915b0b020d5 (diff)
ARM: pm: allow generic sleep code to be used with SMP CPU idle
Allow the generic sleep code to be used with SMP CPU idle by storing N CPU stack pointers rather than just one. Tested on Assabet and Tegra 2. Tested-by: Colin Cross <ccross@android.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/kernel')
-rw-r--r--arch/arm/kernel/sleep.S27
1 files changed, 26 insertions, 1 deletions
diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S
index 2ba17946619e..bfad698a02e7 100644
--- a/arch/arm/kernel/sleep.S
+++ b/arch/arm/kernel/sleep.S
@@ -1,4 +1,5 @@
1#include <linux/linkage.h> 1#include <linux/linkage.h>
2#include <linux/threads.h>
2#include <asm/asm-offsets.h> 3#include <asm/asm-offsets.h>
3#include <asm/assembler.h> 4#include <asm/assembler.h>
4#include <asm/glue-cache.h> 5#include <asm/glue-cache.h>
@@ -26,7 +27,14 @@ ENTRY(cpu_suspend)
26 stmfd sp!, {r1, r2, r3, ip} @ save v:p, virt SP, retfn, phys resume fn 27 stmfd sp!, {r1, r2, r3, ip} @ save v:p, virt SP, retfn, phys resume fn
27 ldr r3, =sleep_save_sp 28 ldr r3, =sleep_save_sp
28 add r2, sp, r1 @ convert SP to phys 29 add r2, sp, r1 @ convert SP to phys
30#ifdef CONFIG_SMP
31 ALT_SMP(mrc p15, 0, lr, c0, c0, 5)
32 ALT_UP(mov lr, #0)
33 and lr, lr, #15
34 str r2, [r3, lr, lsl #2] @ save phys SP
35#else
29 str r2, [r3] @ save phys SP 36 str r2, [r3] @ save phys SP
37#endif
30 mov lr, pc 38 mov lr, pc
31 ldr pc, [r10, #CPU_DO_SUSPEND] @ save CPU state 39 ldr pc, [r10, #CPU_DO_SUSPEND] @ save CPU state
32#else 40#else
@@ -37,7 +45,14 @@ ENTRY(cpu_suspend)
37 stmfd sp!, {r1, r2, r3} @ save v:p, virt SP, return fn 45 stmfd sp!, {r1, r2, r3} @ save v:p, virt SP, return fn
38 ldr r3, =sleep_save_sp 46 ldr r3, =sleep_save_sp
39 add r2, sp, r1 @ convert SP to phys 47 add r2, sp, r1 @ convert SP to phys
48#ifdef CONFIG_SMP
49 ALT_SMP(mrc p15, 0, lr, c0, c0, 5)
50 ALT_UP(mov lr, #0)
51 and lr, lr, #15
52 str r2, [r3, lr, lsl #2] @ save phys SP
53#else
40 str r2, [r3] @ save phys SP 54 str r2, [r3] @ save phys SP
55#endif
41 bl cpu_do_suspend 56 bl cpu_do_suspend
42#endif 57#endif
43 58
@@ -95,7 +110,15 @@ ENDPROC(cpu_resume_after_mmu)
95 .data 110 .data
96 .align 111 .align
97ENTRY(cpu_resume) 112ENTRY(cpu_resume)
113#ifdef CONFIG_SMP
114 adr r0, sleep_save_sp
115 ALT_SMP(mrc p15, 0, r1, c0, c0, 5)
116 ALT_UP(mov r1, #0)
117 and r1, r1, #15
118 ldr r0, [r0, r1, lsl #2] @ stack phys addr
119#else
98 ldr r0, sleep_save_sp @ stack phys addr 120 ldr r0, sleep_save_sp @ stack phys addr
121#endif
99 msr cpsr_c, #PSR_I_BIT | PSR_F_BIT | SVC_MODE @ set SVC, irqs off 122 msr cpsr_c, #PSR_I_BIT | PSR_F_BIT | SVC_MODE @ set SVC, irqs off
100#ifdef MULTI_CPU 123#ifdef MULTI_CPU
101 ldmia r0!, {r1, sp, lr, pc} @ load v:p, stack, return fn, resume fn 124 ldmia r0!, {r1, sp, lr, pc} @ load v:p, stack, return fn, resume fn
@@ -106,4 +129,6 @@ ENTRY(cpu_resume)
106ENDPROC(cpu_resume) 129ENDPROC(cpu_resume)
107 130
108sleep_save_sp: 131sleep_save_sp:
109 .word 0 @ preserve stack phys ptr here 132 .rept CONFIG_NR_CPUS
133 .long 0 @ preserve stack phys ptr here
134 .endr