diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2014-06-30 11:29:12 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2014-07-18 07:29:04 -0400 |
commit | 6ebbf2ce437b33022d30badd49dc94d33ecfa498 (patch) | |
tree | bc015e35b456a28bb0e501803a454dc0c0d3291a /arch/arm/mach-tegra | |
parent | af040ffc9ba1e079ee4c0748aff64fa3d4716fa5 (diff) |
ARM: convert all "mov.* pc, reg" to "bx reg" for ARMv6+
ARMv6 and greater introduced a new instruction ("bx") which can be used
to return from function calls. Recent CPUs perform better when the
"bx lr" instruction is used rather than the "mov pc, lr" instruction,
and this sequence is strongly recommended to be used by the ARM
architecture manual (section A.4.1.1).
We provide a new macro "ret" with all its variants for the condition
code which will resolve to the appropriate instruction.
Rather than doing this piecemeal, and miss some instances, change all
the "mov pc" instances to use the new macro, with the exception of
the "movs" instruction and the kprobes code. This allows us to detect
the "mov pc, lr" case and fix it up - and also gives us the possibility
of deploying this for other registers depending on the CPU selection.
Reported-by: Will Deacon <will.deacon@arm.com>
Tested-by: Stephen Warren <swarren@nvidia.com> # Tegra Jetson TK1
Tested-by: Robert Jarzmik <robert.jarzmik@free.fr> # mioa701_bootresume.S
Tested-by: Andrew Lunn <andrew@lunn.ch> # Kirkwood
Tested-by: Shawn Guo <shawn.guo@freescale.com>
Tested-by: Tony Lindgren <tony@atomide.com> # OMAPs
Tested-by: Gregory CLEMENT <gregory.clement@free-electrons.com> # Armada XP, 375, 385
Acked-by: Sekhar Nori <nsekhar@ti.com> # DaVinci
Acked-by: Christoffer Dall <christoffer.dall@linaro.org> # kvm/hyp
Acked-by: Haojian Zhuang <haojian.zhuang@gmail.com> # PXA3xx
Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> # Xen
Tested-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> # ARMv7M
Tested-by: Simon Horman <horms+renesas@verge.net.au> # Shmobile
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/mach-tegra')
-rw-r--r-- | arch/arm/mach-tegra/sleep-tegra20.S | 24 | ||||
-rw-r--r-- | arch/arm/mach-tegra/sleep-tegra30.S | 14 | ||||
-rw-r--r-- | arch/arm/mach-tegra/sleep.S | 8 |
3 files changed, 23 insertions, 23 deletions
diff --git a/arch/arm/mach-tegra/sleep-tegra20.S b/arch/arm/mach-tegra/sleep-tegra20.S index aaaf3abd2688..be4bc5f853f5 100644 --- a/arch/arm/mach-tegra/sleep-tegra20.S +++ b/arch/arm/mach-tegra/sleep-tegra20.S | |||
@@ -78,7 +78,7 @@ ENTRY(tegra20_hotplug_shutdown) | |||
78 | /* Put this CPU down */ | 78 | /* Put this CPU down */ |
79 | cpu_id r0 | 79 | cpu_id r0 |
80 | bl tegra20_cpu_shutdown | 80 | bl tegra20_cpu_shutdown |
81 | mov pc, lr @ should never get here | 81 | ret lr @ should never get here |
82 | ENDPROC(tegra20_hotplug_shutdown) | 82 | ENDPROC(tegra20_hotplug_shutdown) |
83 | 83 | ||
84 | /* | 84 | /* |
@@ -96,7 +96,7 @@ ENDPROC(tegra20_hotplug_shutdown) | |||
96 | */ | 96 | */ |
97 | ENTRY(tegra20_cpu_shutdown) | 97 | ENTRY(tegra20_cpu_shutdown) |
98 | cmp r0, #0 | 98 | cmp r0, #0 |
99 | moveq pc, lr @ must not be called for CPU 0 | 99 | reteq lr @ must not be called for CPU 0 |
100 | mov32 r1, TEGRA_PMC_VIRT + PMC_SCRATCH41 | 100 | mov32 r1, TEGRA_PMC_VIRT + PMC_SCRATCH41 |
101 | mov r12, #CPU_RESETTABLE | 101 | mov r12, #CPU_RESETTABLE |
102 | str r12, [r1] | 102 | str r12, [r1] |
@@ -117,7 +117,7 @@ ENTRY(tegra20_cpu_shutdown) | |||
117 | cpu_id r3 | 117 | cpu_id r3 |
118 | cmp r3, r0 | 118 | cmp r3, r0 |
119 | beq . | 119 | beq . |
120 | mov pc, lr | 120 | ret lr |
121 | ENDPROC(tegra20_cpu_shutdown) | 121 | ENDPROC(tegra20_cpu_shutdown) |
122 | #endif | 122 | #endif |
123 | 123 | ||
@@ -164,7 +164,7 @@ ENTRY(tegra_pen_lock) | |||
164 | cmpeq r12, r0 @ !turn == cpu? | 164 | cmpeq r12, r0 @ !turn == cpu? |
165 | beq 1b @ while !turn == cpu && flag[!cpu] == 1 | 165 | beq 1b @ while !turn == cpu && flag[!cpu] == 1 |
166 | 166 | ||
167 | mov pc, lr @ locked | 167 | ret lr @ locked |
168 | ENDPROC(tegra_pen_lock) | 168 | ENDPROC(tegra_pen_lock) |
169 | 169 | ||
170 | ENTRY(tegra_pen_unlock) | 170 | ENTRY(tegra_pen_unlock) |
@@ -176,7 +176,7 @@ ENTRY(tegra_pen_unlock) | |||
176 | addne r2, r3, #PMC_SCRATCH39 | 176 | addne r2, r3, #PMC_SCRATCH39 |
177 | mov r12, #0 | 177 | mov r12, #0 |
178 | str r12, [r2] | 178 | str r12, [r2] |
179 | mov pc, lr | 179 | ret lr |
180 | ENDPROC(tegra_pen_unlock) | 180 | ENDPROC(tegra_pen_unlock) |
181 | 181 | ||
182 | /* | 182 | /* |
@@ -189,7 +189,7 @@ ENTRY(tegra20_cpu_clear_resettable) | |||
189 | mov32 r1, TEGRA_PMC_VIRT + PMC_SCRATCH41 | 189 | mov32 r1, TEGRA_PMC_VIRT + PMC_SCRATCH41 |
190 | mov r12, #CPU_NOT_RESETTABLE | 190 | mov r12, #CPU_NOT_RESETTABLE |
191 | str r12, [r1] | 191 | str r12, [r1] |
192 | mov pc, lr | 192 | ret lr |
193 | ENDPROC(tegra20_cpu_clear_resettable) | 193 | ENDPROC(tegra20_cpu_clear_resettable) |
194 | 194 | ||
195 | /* | 195 | /* |
@@ -202,7 +202,7 @@ ENTRY(tegra20_cpu_set_resettable_soon) | |||
202 | mov32 r1, TEGRA_PMC_VIRT + PMC_SCRATCH41 | 202 | mov32 r1, TEGRA_PMC_VIRT + PMC_SCRATCH41 |
203 | mov r12, #CPU_RESETTABLE_SOON | 203 | mov r12, #CPU_RESETTABLE_SOON |
204 | str r12, [r1] | 204 | str r12, [r1] |
205 | mov pc, lr | 205 | ret lr |
206 | ENDPROC(tegra20_cpu_set_resettable_soon) | 206 | ENDPROC(tegra20_cpu_set_resettable_soon) |
207 | 207 | ||
208 | /* | 208 | /* |
@@ -217,7 +217,7 @@ ENTRY(tegra20_cpu_is_resettable_soon) | |||
217 | cmp r12, #CPU_RESETTABLE_SOON | 217 | cmp r12, #CPU_RESETTABLE_SOON |
218 | moveq r0, #1 | 218 | moveq r0, #1 |
219 | movne r0, #0 | 219 | movne r0, #0 |
220 | mov pc, lr | 220 | ret lr |
221 | ENDPROC(tegra20_cpu_is_resettable_soon) | 221 | ENDPROC(tegra20_cpu_is_resettable_soon) |
222 | 222 | ||
223 | /* | 223 | /* |
@@ -239,7 +239,7 @@ ENTRY(tegra20_sleep_core_finish) | |||
239 | mov32 r1, TEGRA_IRAM_LPx_RESUME_AREA | 239 | mov32 r1, TEGRA_IRAM_LPx_RESUME_AREA |
240 | add r0, r0, r1 | 240 | add r0, r0, r1 |
241 | 241 | ||
242 | mov pc, r3 | 242 | ret r3 |
243 | ENDPROC(tegra20_sleep_core_finish) | 243 | ENDPROC(tegra20_sleep_core_finish) |
244 | 244 | ||
245 | /* | 245 | /* |
@@ -402,7 +402,7 @@ exit_selfrefresh_loop: | |||
402 | 402 | ||
403 | mov32 r0, TEGRA_PMC_BASE | 403 | mov32 r0, TEGRA_PMC_BASE |
404 | ldr r0, [r0, #PMC_SCRATCH41] | 404 | ldr r0, [r0, #PMC_SCRATCH41] |
405 | mov pc, r0 @ jump to tegra_resume | 405 | ret r0 @ jump to tegra_resume |
406 | ENDPROC(tegra20_lp1_reset) | 406 | ENDPROC(tegra20_lp1_reset) |
407 | 407 | ||
408 | /* | 408 | /* |
@@ -455,7 +455,7 @@ tegra20_switch_cpu_to_clk32k: | |||
455 | mov r0, #0 /* brust policy = 32KHz */ | 455 | mov r0, #0 /* brust policy = 32KHz */ |
456 | str r0, [r5, #CLK_RESET_SCLK_BURST] | 456 | str r0, [r5, #CLK_RESET_SCLK_BURST] |
457 | 457 | ||
458 | mov pc, lr | 458 | ret lr |
459 | 459 | ||
460 | /* | 460 | /* |
461 | * tegra20_enter_sleep | 461 | * tegra20_enter_sleep |
@@ -535,7 +535,7 @@ padsave_done: | |||
535 | adr r2, tegra20_sclk_save | 535 | adr r2, tegra20_sclk_save |
536 | str r0, [r2] | 536 | str r0, [r2] |
537 | dsb | 537 | dsb |
538 | mov pc, lr | 538 | ret lr |
539 | 539 | ||
540 | tegra20_sdram_pad_address: | 540 | tegra20_sdram_pad_address: |
541 | .word TEGRA_APB_MISC_BASE + APB_MISC_XM2CFGCPADCTRL | 541 | .word TEGRA_APB_MISC_BASE + APB_MISC_XM2CFGCPADCTRL |
diff --git a/arch/arm/mach-tegra/sleep-tegra30.S b/arch/arm/mach-tegra/sleep-tegra30.S index b16d4a57fa59..09cad9b071de 100644 --- a/arch/arm/mach-tegra/sleep-tegra30.S +++ b/arch/arm/mach-tegra/sleep-tegra30.S | |||
@@ -142,7 +142,7 @@ ENTRY(tegra30_hotplug_shutdown) | |||
142 | /* Powergate this CPU */ | 142 | /* Powergate this CPU */ |
143 | mov r0, #TEGRA30_POWER_HOTPLUG_SHUTDOWN | 143 | mov r0, #TEGRA30_POWER_HOTPLUG_SHUTDOWN |
144 | bl tegra30_cpu_shutdown | 144 | bl tegra30_cpu_shutdown |
145 | mov pc, lr @ should never get here | 145 | ret lr @ should never get here |
146 | ENDPROC(tegra30_hotplug_shutdown) | 146 | ENDPROC(tegra30_hotplug_shutdown) |
147 | 147 | ||
148 | /* | 148 | /* |
@@ -161,7 +161,7 @@ ENTRY(tegra30_cpu_shutdown) | |||
161 | bne _no_cpu0_chk @ It's not Tegra30 | 161 | bne _no_cpu0_chk @ It's not Tegra30 |
162 | 162 | ||
163 | cmp r3, #0 | 163 | cmp r3, #0 |
164 | moveq pc, lr @ Must never be called for CPU 0 | 164 | reteq lr @ Must never be called for CPU 0 |
165 | _no_cpu0_chk: | 165 | _no_cpu0_chk: |
166 | 166 | ||
167 | ldr r12, =TEGRA_FLOW_CTRL_VIRT | 167 | ldr r12, =TEGRA_FLOW_CTRL_VIRT |
@@ -266,7 +266,7 @@ ENTRY(tegra30_sleep_core_finish) | |||
266 | mov32 r1, TEGRA_IRAM_LPx_RESUME_AREA | 266 | mov32 r1, TEGRA_IRAM_LPx_RESUME_AREA |
267 | add r0, r0, r1 | 267 | add r0, r0, r1 |
268 | 268 | ||
269 | mov pc, r3 | 269 | ret r3 |
270 | ENDPROC(tegra30_sleep_core_finish) | 270 | ENDPROC(tegra30_sleep_core_finish) |
271 | 271 | ||
272 | /* | 272 | /* |
@@ -285,7 +285,7 @@ ENTRY(tegra30_sleep_cpu_secondary_finish) | |||
285 | mov r0, #0 @ power mode flags (!hotplug) | 285 | mov r0, #0 @ power mode flags (!hotplug) |
286 | bl tegra30_cpu_shutdown | 286 | bl tegra30_cpu_shutdown |
287 | mov r0, #1 @ never return here | 287 | mov r0, #1 @ never return here |
288 | mov pc, r7 | 288 | ret r7 |
289 | ENDPROC(tegra30_sleep_cpu_secondary_finish) | 289 | ENDPROC(tegra30_sleep_cpu_secondary_finish) |
290 | 290 | ||
291 | /* | 291 | /* |
@@ -529,7 +529,7 @@ __no_dual_emc_chanl: | |||
529 | 529 | ||
530 | mov32 r0, TEGRA_PMC_BASE | 530 | mov32 r0, TEGRA_PMC_BASE |
531 | ldr r0, [r0, #PMC_SCRATCH41] | 531 | ldr r0, [r0, #PMC_SCRATCH41] |
532 | mov pc, r0 @ jump to tegra_resume | 532 | ret r0 @ jump to tegra_resume |
533 | ENDPROC(tegra30_lp1_reset) | 533 | ENDPROC(tegra30_lp1_reset) |
534 | 534 | ||
535 | .align L1_CACHE_SHIFT | 535 | .align L1_CACHE_SHIFT |
@@ -659,7 +659,7 @@ _no_pll_in_iddq: | |||
659 | mov r0, #0 /* brust policy = 32KHz */ | 659 | mov r0, #0 /* brust policy = 32KHz */ |
660 | str r0, [r5, #CLK_RESET_SCLK_BURST] | 660 | str r0, [r5, #CLK_RESET_SCLK_BURST] |
661 | 661 | ||
662 | mov pc, lr | 662 | ret lr |
663 | 663 | ||
664 | /* | 664 | /* |
665 | * tegra30_enter_sleep | 665 | * tegra30_enter_sleep |
@@ -819,7 +819,7 @@ pmc_io_dpd_skip: | |||
819 | 819 | ||
820 | dsb | 820 | dsb |
821 | 821 | ||
822 | mov pc, lr | 822 | ret lr |
823 | 823 | ||
824 | .ltorg | 824 | .ltorg |
825 | /* dummy symbol for end of IRAM */ | 825 | /* dummy symbol for end of IRAM */ |
diff --git a/arch/arm/mach-tegra/sleep.S b/arch/arm/mach-tegra/sleep.S index 8d06213fbc47..f024a5109e8e 100644 --- a/arch/arm/mach-tegra/sleep.S +++ b/arch/arm/mach-tegra/sleep.S | |||
@@ -87,7 +87,7 @@ ENTRY(tegra_init_l2_for_a15) | |||
87 | mcrne p15, 0x1, r0, c9, c0, 2 | 87 | mcrne p15, 0x1, r0, c9, c0, 2 |
88 | _exit_init_l2_a15: | 88 | _exit_init_l2_a15: |
89 | 89 | ||
90 | mov pc, lr | 90 | ret lr |
91 | ENDPROC(tegra_init_l2_for_a15) | 91 | ENDPROC(tegra_init_l2_for_a15) |
92 | 92 | ||
93 | /* | 93 | /* |
@@ -111,7 +111,7 @@ ENTRY(tegra_sleep_cpu_finish) | |||
111 | add r3, r3, r0 | 111 | add r3, r3, r0 |
112 | mov r0, r1 | 112 | mov r0, r1 |
113 | 113 | ||
114 | mov pc, r3 | 114 | ret r3 |
115 | ENDPROC(tegra_sleep_cpu_finish) | 115 | ENDPROC(tegra_sleep_cpu_finish) |
116 | 116 | ||
117 | /* | 117 | /* |
@@ -139,7 +139,7 @@ ENTRY(tegra_shut_off_mmu) | |||
139 | moveq r3, #0 | 139 | moveq r3, #0 |
140 | streq r3, [r2, #L2X0_CTRL] | 140 | streq r3, [r2, #L2X0_CTRL] |
141 | #endif | 141 | #endif |
142 | mov pc, r0 | 142 | ret r0 |
143 | ENDPROC(tegra_shut_off_mmu) | 143 | ENDPROC(tegra_shut_off_mmu) |
144 | .popsection | 144 | .popsection |
145 | 145 | ||
@@ -156,6 +156,6 @@ ENTRY(tegra_switch_cpu_to_pllp) | |||
156 | str r0, [r5, #CLK_RESET_CCLK_BURST] | 156 | str r0, [r5, #CLK_RESET_CCLK_BURST] |
157 | mov r0, #0 | 157 | mov r0, #0 |
158 | str r0, [r5, #CLK_RESET_CCLK_DIVIDER] | 158 | str r0, [r5, #CLK_RESET_CCLK_DIVIDER] |
159 | mov pc, lr | 159 | ret lr |
160 | ENDPROC(tegra_switch_cpu_to_pllp) | 160 | ENDPROC(tegra_switch_cpu_to_pllp) |
161 | #endif | 161 | #endif |