aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2011-06-13 10:58:34 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2011-06-24 03:48:43 -0400
commite8856a8797e76e6883ae81f8f9ecbb231cc535df (patch)
treef256d1100f2458e01ca2680052466b24bbabe664 /arch/arm
parentdbc125168fd7dda4ffb24a29548746c7bd3b3d87 (diff)
ARM: pm: convert cpu_suspend() to a normal function
cpu_suspend() has a weird calling method which makes it only possible to call from assembly code: it returns with a modified stack pointer to finish the suspend, but on resume, it 'returns' via a provided pointer. We can make cpu_suspend() appear to be a normal function merely by swapping the resume pointer argument and the link register. Do so, and update all callers to take account of this more traditional behaviour. Acked-by: Frank Hofmann <frank.hofmann@tomtom.com> Tested-by: Kevin Hilman <khilman@ti.com> Acked-by: Jean Pihet <j-pihet@ti.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/include/asm/system.h2
-rw-r--r--arch/arm/kernel/sleep.S10
-rw-r--r--arch/arm/mach-exynos4/sleep.S7
-rw-r--r--arch/arm/mach-pxa/sleep.S13
-rw-r--r--arch/arm/mach-s3c64xx/sleep.S9
-rw-r--r--arch/arm/mach-s5pv210/sleep.S7
-rw-r--r--arch/arm/mach-sa1100/sleep.S13
-rw-r--r--arch/arm/plat-s3c24xx/sleep.S10
8 files changed, 31 insertions, 40 deletions
diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h
index 832888d0c20c..50be6055df89 100644
--- a/arch/arm/include/asm/system.h
+++ b/arch/arm/include/asm/system.h
@@ -106,6 +106,8 @@ extern void __show_regs(struct pt_regs *);
106 106
107extern int cpu_architecture(void); 107extern int cpu_architecture(void);
108extern void cpu_init(void); 108extern void cpu_init(void);
109extern void cpu_suspend(int, long, unsigned long, void (*)(unsigned long));
110extern void cpu_resume(void);
109 111
110void arm_machine_restart(char mode, const char *cmd); 112void arm_machine_restart(char mode, const char *cmd);
111extern void (*arm_pm_restart)(char str, const char *cmd); 113extern void (*arm_pm_restart)(char str, const char *cmd);
diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S
index b924bcc32dcd..e0626779fe92 100644
--- a/arch/arm/kernel/sleep.S
+++ b/arch/arm/kernel/sleep.S
@@ -11,13 +11,11 @@
11 * Save CPU state for a suspend 11 * Save CPU state for a suspend
12 * r1 = v:p offset 12 * r1 = v:p offset
13 * r2 = suspend function arg0 13 * r2 = suspend function arg0
14 * r3 = virtual return function 14 * r3 = suspend function
15 * Note: sp is decremented to allocate space for CPU state on stack 15 * Note: does not return until system resumes
16 * r0-r3,ip,lr corrupted
17 */ 16 */
18ENTRY(cpu_suspend) 17ENTRY(cpu_suspend)
19 stmfd sp!, {r3} 18 stmfd sp!, {r4 - r11, lr}
20 stmfd sp!, {r4 - r11}
21#ifdef MULTI_CPU 19#ifdef MULTI_CPU
22 ldr r10, =processor 20 ldr r10, =processor
23 ldr r5, [r10, #CPU_SLEEP_SIZE] @ size of CPU sleep state 21 ldr r5, [r10, #CPU_SLEEP_SIZE] @ size of CPU sleep state
@@ -33,7 +31,7 @@ ENTRY(cpu_suspend)
33 stmfd sp!, {r1, r6, ip} @ save v:p, virt SP, phys resume fn 31 stmfd sp!, {r1, r6, ip} @ save v:p, virt SP, phys resume fn
34 ldr r5, =sleep_save_sp 32 ldr r5, =sleep_save_sp
35 add r6, sp, r1 @ convert SP to phys 33 add r6, sp, r1 @ convert SP to phys
36 stmfd sp!, {r2, lr} @ save suspend func arg and pointer 34 stmfd sp!, {r2, r3} @ save suspend func arg and pointer
37#ifdef CONFIG_SMP 35#ifdef CONFIG_SMP
38 ALT_SMP(mrc p15, 0, lr, c0, c0, 5) 36 ALT_SMP(mrc p15, 0, lr, c0, c0, 5)
39 ALT_UP(mov lr, #0) 37 ALT_UP(mov lr, #0)
diff --git a/arch/arm/mach-exynos4/sleep.S b/arch/arm/mach-exynos4/sleep.S
index 6b62425417a6..d9a2287b4641 100644
--- a/arch/arm/mach-exynos4/sleep.S
+++ b/arch/arm/mach-exynos4/sleep.S
@@ -42,16 +42,15 @@
42ENTRY(s3c_cpu_save) 42ENTRY(s3c_cpu_save)
43 43
44 stmfd sp!, { r3 - r12, lr } 44 stmfd sp!, { r3 - r12, lr }
45 ldr r3, =resume_with_mmu 45 adr r3, BSYM(exynos4_finish_suspend)
46 bl cpu_suspend 46 bl cpu_suspend
47 ldmfd sp!, { r3 - r12, pc }
47 48
49exynos4_finish_suspend:
48 ldr r0, =pm_cpu_sleep 50 ldr r0, =pm_cpu_sleep
49 ldr r0, [ r0 ] 51 ldr r0, [ r0 ]
50 mov pc, r0 52 mov pc, r0
51 53
52resume_with_mmu:
53 ldmfd sp!, { r3 - r12, pc }
54
55 .ltorg 54 .ltorg
56 55
57 /* 56 /*
diff --git a/arch/arm/mach-pxa/sleep.S b/arch/arm/mach-pxa/sleep.S
index 613ddfa2c295..3a67887e6dbd 100644
--- a/arch/arm/mach-pxa/sleep.S
+++ b/arch/arm/mach-pxa/sleep.S
@@ -35,9 +35,11 @@ ENTRY(pxa3xx_cpu_suspend)
35#endif 35#endif
36 stmfd sp!, {r2 - r12, lr} @ save registers on stack 36 stmfd sp!, {r2 - r12, lr} @ save registers on stack
37 mov r1, r0 37 mov r1, r0
38 ldr r3, =pxa_cpu_resume @ resume function 38 adr r3, BSYM(pxa3xx_finish_suspend)
39 bl cpu_suspend 39 bl cpu_suspend
40 b pxa_cpu_resume
40 41
42pxa3xx_finish_suspend:
41 mov r0, #0x06 @ S2D3C4 mode 43 mov r0, #0x06 @ S2D3C4 mode
42 mcr p14, 0, r0, c7, c0, 0 @ enter sleep 44 mcr p14, 0, r0, c7, c0, 0 @ enter sleep
43 45
@@ -60,9 +62,11 @@ ENTRY(pxa27x_cpu_suspend)
60#endif 62#endif
61 stmfd sp!, {r2 - r12, lr} @ save registers on stack 63 stmfd sp!, {r2 - r12, lr} @ save registers on stack
62 mov r2, r0 @ save sleep mode 64 mov r2, r0 @ save sleep mode
63 ldr r3, =pxa_cpu_resume @ resume function 65 adr r3, BSYM(pxa27x_finish_suspend)
64 bl cpu_suspend 66 bl cpu_suspend
67 b pxa_cpu_resume
65 68
69pxa27x_finish_suspend:
66 @ Put the processor to sleep 70 @ Put the processor to sleep
67 @ (also workaround for sighting 28071) 71 @ (also workaround for sighting 28071)
68 72
@@ -110,8 +114,11 @@ ENTRY(pxa27x_cpu_suspend)
110ENTRY(pxa25x_cpu_suspend) 114ENTRY(pxa25x_cpu_suspend)
111 stmfd sp!, {r2 - r12, lr} @ save registers on stack 115 stmfd sp!, {r2 - r12, lr} @ save registers on stack
112 mov r2, r0 @ save sleep mode 116 mov r2, r0 @ save sleep mode
113 ldr r3, =pxa_cpu_resume @ resume function 117 adr r3, BSYM(pxa25x_finish_suspend)
114 bl cpu_suspend 118 bl cpu_suspend
119 b pxa_cpu_resume
120
121pxa25x_finish_suspend:
115 @ prepare value for sleep mode 122 @ prepare value for sleep mode
116 mov r1, r0 @ sleep mode 123 mov r1, r0 @ sleep mode
117 124
diff --git a/arch/arm/mach-s3c64xx/sleep.S b/arch/arm/mach-s3c64xx/sleep.S
index 1f87732b2320..dc4f58202101 100644
--- a/arch/arm/mach-s3c64xx/sleep.S
+++ b/arch/arm/mach-s3c64xx/sleep.S
@@ -36,18 +36,15 @@
36 36
37ENTRY(s3c_cpu_save) 37ENTRY(s3c_cpu_save)
38 stmfd sp!, { r4 - r12, lr } 38 stmfd sp!, { r4 - r12, lr }
39 ldr r3, =resume_with_mmu 39 adr r3, BSYM(s3c64xx_finish_suspend)
40 bl cpu_suspend 40 bl cpu_suspend
41 ldmfd sp!, { r4 - r12, pc }
41 42
43s3c64xx_finish_suspend:
42 @@ call final suspend code 44 @@ call final suspend code
43 ldr r0, =pm_cpu_sleep 45 ldr r0, =pm_cpu_sleep
44 ldr pc, [r0] 46 ldr pc, [r0]
45 47
46 @@ return to the caller, after the MMU is turned on.
47 @@ restore the last bits of the stack and return.
48resume_with_mmu:
49 ldmfd sp!, { r4 - r12, pc } @ return, from sp from s3c_cpu_save
50
51 /* Sleep magic, the word before the resume entry point so that the 48 /* Sleep magic, the word before the resume entry point so that the
52 * bootloader can check for a resumeable image. */ 49 * bootloader can check for a resumeable image. */
53 50
diff --git a/arch/arm/mach-s5pv210/sleep.S b/arch/arm/mach-s5pv210/sleep.S
index a3d649466fb1..1182fc848a79 100644
--- a/arch/arm/mach-s5pv210/sleep.S
+++ b/arch/arm/mach-s5pv210/sleep.S
@@ -41,16 +41,15 @@
41ENTRY(s3c_cpu_save) 41ENTRY(s3c_cpu_save)
42 42
43 stmfd sp!, { r3 - r12, lr } 43 stmfd sp!, { r3 - r12, lr }
44 ldr r3, =resume_with_mmu 44 adr r3, BSYM(s5pv210_finish_suspend)
45 bl cpu_suspend 45 bl cpu_suspend
46 ldmfd sp!, { r3 - r12, pc }
46 47
48s5pv210_finish_suspend:
47 ldr r0, =pm_cpu_sleep 49 ldr r0, =pm_cpu_sleep
48 ldr r0, [ r0 ] 50 ldr r0, [ r0 ]
49 mov pc, r0 51 mov pc, r0
50 52
51resume_with_mmu:
52 ldmfd sp!, { r3 - r12, pc }
53
54 .ltorg 53 .ltorg
55 54
56 /* sleep magic, to allow the bootloader to check for an valid 55 /* sleep magic, to allow the bootloader to check for an valid
diff --git a/arch/arm/mach-sa1100/sleep.S b/arch/arm/mach-sa1100/sleep.S
index 122ab3c66923..f3fe39773f8b 100644
--- a/arch/arm/mach-sa1100/sleep.S
+++ b/arch/arm/mach-sa1100/sleep.S
@@ -31,9 +31,11 @@
31ENTRY(sa1100_cpu_suspend) 31ENTRY(sa1100_cpu_suspend)
32 stmfd sp!, {r4 - r12, lr} @ save registers on stack 32 stmfd sp!, {r4 - r12, lr} @ save registers on stack
33 mov r1, r0 33 mov r1, r0
34 ldr r3, =sa1100_cpu_resume @ return function 34 adr r3, BSYM(sa1100_finish_suspend)
35 bl cpu_suspend 35 bl cpu_suspend
36 ldmfd sp!, {r4 - r12, pc} @ return to caller
36 37
38sa1100_finish_suspend:
37 @ disable clock switching 39 @ disable clock switching
38 mcr p15, 0, r1, c15, c2, 2 40 mcr p15, 0, r1, c15, c2, 2
39 41
@@ -139,12 +141,3 @@ sa1110_sdram_controller_fix:
139 str r13, [r12] 141 str r13, [r12]
140 142
14120: b 20b @ loop waiting for sleep 14320: b 20b @ loop waiting for sleep
142
143/*
144 * cpu_sa1100_resume()
145 *
146 * entry point from bootloader into kernel during resume
147 */
148 .align 5
149sa1100_cpu_resume:
150 ldmfd sp!, {r4 - r12, pc} @ return to caller
diff --git a/arch/arm/plat-s3c24xx/sleep.S b/arch/arm/plat-s3c24xx/sleep.S
index fd7032f84ae7..f822e6282dd4 100644
--- a/arch/arm/plat-s3c24xx/sleep.S
+++ b/arch/arm/plat-s3c24xx/sleep.S
@@ -49,21 +49,17 @@
49 49
50ENTRY(s3c_cpu_save) 50ENTRY(s3c_cpu_save)
51 stmfd sp!, { r4 - r12, lr } 51 stmfd sp!, { r4 - r12, lr }
52 ldr r3, =resume_with_mmu 52 adr r3, BSYM(s3c24xx_finish_suspend)
53 bl cpu_suspend 53 bl cpu_suspend
54 ldmfd sp!, { r4 - r12, pc }
54 55
56s3c24xx_finish_suspend:
55 @@ jump to final code to send system to sleep 57 @@ jump to final code to send system to sleep
56 ldr r0, =pm_cpu_sleep 58 ldr r0, =pm_cpu_sleep
57 @@ldr pc, [ r0 ] 59 @@ldr pc, [ r0 ]
58 ldr r0, [ r0 ] 60 ldr r0, [ r0 ]
59 mov pc, r0 61 mov pc, r0
60 62
61 @@ return to the caller, after having the MMU
62 @@ turned on, this restores the last bits from the
63 @@ stack
64resume_with_mmu:
65 ldmfd sp!, { r4 - r12, pc }
66
67 .ltorg 63 .ltorg
68 64
69 /* sleep magic, to allow the bootloader to check for an valid 65 /* sleep magic, to allow the bootloader to check for an valid