aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorTony Lindgren <tony@atomide.com>2015-05-28 10:22:08 -0400
committerTony Lindgren <tony@atomide.com>2015-05-28 10:22:08 -0400
commitd8a50941c91a68da202aaa96a3dacd471ea9c693 (patch)
treed93e31d2087145196a977d9b9426e0f3ab76fe87 /arch
parentf25bf74c8862efdc30453d16d60cf22958a4873e (diff)
ARM: OMAP3: Fix booting with thumb2 kernel
We get a NULL pointer dereference on omap3 for thumb2 compiled kernels: Internal error: Oops: 80000005 [#1] SMP THUMB2 ... [<c046497b>] (_raw_spin_unlock_irqrestore) from [<c0024375>] (omap3_enter_idle_bm+0xc5/0x178) [<c0024375>] (omap3_enter_idle_bm) from [<c0374e63>] (cpuidle_enter_state+0x77/0x27c) [<c0374e63>] (cpuidle_enter_state) from [<c00627f1>] (cpu_startup_entry+0x155/0x23c) [<c00627f1>] (cpu_startup_entry) from [<c06b9a47>] (start_kernel+0x32f/0x338) [<c06b9a47>] (start_kernel) from [<8000807f>] (0x8000807f) The power management related assembly on omaps needs to interact with ARM mode bootrom code, so we need to keep most of the related assembly in ARM mode. Turns out this error is because of missing ENDPROC for assembly code as suggested by Stephen Boyd <sboyd@codeaurora.org>. Let's fix the problem by adding ENDPROC in two places to sleep34xx.S. Let's also remove the now duplicate custom code for mode switching. This has been unnecessary since commit 6ebbf2ce437b ("ARM: convert all "mov.* pc, reg" to "bx reg" for ARMv6+"). And let's also remove the comments about local variables, they are now just confusing after the ENDPROC. The reason why ENDPROC makes a difference is it sets .type and then the compiler knows what to do with the thumb bit as explained at: https://wiki.ubuntu.com/ARM/Thumb2PortingHowto Reported-by: Kevin Hilman <khilman@kernel.org> Tested-by: Kevin Hilman <khilman@linaro.org> Signed-off-by: Tony Lindgren <tony@atomide.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-omap2/sleep34xx.S22
1 files changed, 2 insertions, 20 deletions
diff --git a/arch/arm/mach-omap2/sleep34xx.S b/arch/arm/mach-omap2/sleep34xx.S
index d1dedc8195ed..eafd120b53f1 100644
--- a/arch/arm/mach-omap2/sleep34xx.S
+++ b/arch/arm/mach-omap2/sleep34xx.S
@@ -203,23 +203,8 @@ save_context_wfi:
203 */ 203 */
204 ldr r1, kernel_flush 204 ldr r1, kernel_flush
205 blx r1 205 blx r1
206 /*
207 * The kernel doesn't interwork: v7_flush_dcache_all in particluar will
208 * always return in Thumb state when CONFIG_THUMB2_KERNEL is enabled.
209 * This sequence switches back to ARM. Note that .align may insert a
210 * nop: bx pc needs to be word-aligned in order to work.
211 */
212 THUMB( .thumb )
213 THUMB( .align )
214 THUMB( bx pc )
215 THUMB( nop )
216 .arm
217
218 b omap3_do_wfi 206 b omap3_do_wfi
219 207ENDPROC(omap34xx_cpu_suspend)
220/*
221 * Local variables
222 */
223omap3_do_wfi_sram_addr: 208omap3_do_wfi_sram_addr:
224 .word omap3_do_wfi_sram 209 .word omap3_do_wfi_sram
225kernel_flush: 210kernel_flush:
@@ -364,10 +349,7 @@ exit_nonoff_modes:
364 * =================================== 349 * ===================================
365 */ 350 */
366 ldmfd sp!, {r4 - r11, pc} @ restore regs and return 351 ldmfd sp!, {r4 - r11, pc} @ restore regs and return
367 352ENDPROC(omap3_do_wfi)
368/*
369 * Local variables
370 */
371sdrc_power: 353sdrc_power:
372 .word SDRC_POWER_V 354 .word SDRC_POWER_V
373cm_idlest1_core: 355cm_idlest1_core: