diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index 0d75bfd..c333bfd 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -80,7 +80,9 @@ extern void save_secure_ram_context(u32 *addr);
 extern void omap3_save_scratchpad_contents(void);
 
 extern unsigned int omap24xx_idle_loop_suspend_sz;
+extern char *const omap34xx_cpu_suspend_base;
 extern unsigned int omap34xx_suspend_sz;
+extern char *const save_secure_ram_context_base;
 extern unsigned int save_secure_ram_context_sz;
 extern unsigned int omap24xx_cpu_suspend_sz;
 extern unsigned int omap34xx_cpu_suspend_sz;
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 0ec8a04..93f0ee8 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -982,11 +982,18 @@ static int __init clkdms_setup(struct clockdomain *clkdm, void *unused)
 
 void omap_push_sram_idle(void)
 {
-	_omap_sram_idle = omap_sram_push(omap34xx_cpu_suspend,
+	_omap_sram_idle = omap_sram_push(omap34xx_cpu_suspend_base,
 					omap34xx_cpu_suspend_sz);
-	if (omap_type() != OMAP2_DEVICE_TYPE_GP)
-		_omap_save_secure_sram = omap_sram_push(save_secure_ram_context,
+	_omap_sram_idle += (char *)omap34xx_cpu_suspend -
+		omap34xx_cpu_suspend_base;
+
+	if (omap_type() != OMAP2_DEVICE_TYPE_GP) {
+		_omap_save_secure_sram = omap_sram_push(
+				save_secure_ram_context_base,
 				save_secure_ram_context_sz);
+		_omap_save_secure_sram += (char *)save_secure_ram_context -
+			save_secure_ram_context_base;
+	}
 }
 
 static int __init omap3_pm_init(void)
diff --git a/arch/arm/mach-omap2/sleep34xx.S b/arch/arm/mach-omap2/sleep34xx.S
index 2fb205a..06ae955 100644
--- a/arch/arm/mach-omap2/sleep34xx.S
+++ b/arch/arm/mach-omap2/sleep34xx.S
@@ -61,6 +61,7 @@
 
         .text
 /* Function to acquire the semaphore in scratchpad */
+	.arm			@ Do this in ARM for now, due to use of SWP.
 ENTRY(lock_scratchpad_sem)
 	stmfd	sp!, {lr}	@ save registers on stack
 wait_sem:
@@ -74,6 +75,9 @@ wait_loop:
 	cmp	r2, r0		@ did we succeed ?
 	beq	wait_sem	@ no - try again
 	ldmfd	sp!, {pc}	@ restore regs and return
+ENDPROC(lock_scratchpad_sem)
+ THUMB(	.thumb		)
+	.align
 sdrc_scratchpad_sem:
         .word SDRC_SCRATCHPAD_SEM_V
 ENTRY(lock_scratchpad_sem_sz)
@@ -87,6 +91,7 @@ ENTRY(unlock_scratchpad_sem)
 	mov	r2,#0
 	str	r2,[r3]
 	ldmfd	sp!, {pc}	@ restore regs and return
+ENDPROC(unlock_scratchpad_sem)
 ENTRY(unlock_scratchpad_sem_sz)
         .word   . - unlock_scratchpad_sem
 
@@ -96,6 +101,7 @@ ENTRY(get_restore_pointer)
         stmfd   sp!, {lr}     @ save registers on stack
 	adr	r0, restore
         ldmfd   sp!, {pc}     @ restore regs and return
+ENDPROC(get_restore_pointer)
 ENTRY(get_restore_pointer_sz)
         .word   . - get_restore_pointer
 
@@ -105,10 +111,16 @@ ENTRY(get_es3_restore_pointer)
 	stmfd	sp!, {lr}	@ save registers on stack
 	adr	r0, restore_es3
 	ldmfd	sp!, {pc}	@ restore regs and return
+ENDPROC(get_es3_restore_pointer)
 ENTRY(get_es3_restore_pointer_sz)
 	.word	. - get_es3_restore_pointer
 
-ENTRY(es3_sdrc_fix)
+@ For simplicity, make this ARM so it gets called OK from es3_restore.
+@ Demote to a local symbol, since this gives this function an ARM ABI interface
+@ which won't be callable directly from a Thumb-2 kernel.  This code
+@ shouldn't be called from outside anyway...
+	.arm
+es3_sdrc_fix:
 	ldr	r4, sdrc_syscfg		@ get config addr
 	ldr	r5, [r4]		@ get value
 	tst	r5, #0x100		@ is part access blocked
@@ -134,6 +146,9 @@ ENTRY(es3_sdrc_fix)
 	mov	r5, #0x2		@ autorefresh command
 	str	r5, [r4]		@ kick off refreshes
 	bx	lr
+ENDPROC(es3_sdrc_fix)
+ THUMB(	.thumb		)
+	.align
 sdrc_syscfg:
 	.word	SDRC_SYSCONFIG_P
 sdrc_mr_0:
@@ -150,8 +165,12 @@ sdrc_manual_1:
 	.word	SDRC_MANUAL_1_P
 ENTRY(es3_sdrc_fix_sz)
 	.word	. - es3_sdrc_fix
+ THUMB(	.thumb		)
 
 /* Function to call rom code to save secure ram context */
+	.arm			@ Do this in ARM for now, due to use of SMC,
+				@ in case the Secure World firmware may depends
+				@ on decoding the SMC instruction.
 ENTRY(save_secure_ram_context)
 	stmfd	sp!, {r1-r12, lr}	@ save registers on stack
 save_secure_ram_debug:
@@ -175,6 +194,9 @@ save_secure_ram_debug:
 	nop
 	nop
 	ldmfd	sp!, {r1-r12, pc}
+ENDPROC(save_secure_ram_context)
+ THUMB(	.thumb		)
+	.align
 sram_phy_addr_mask:
 	.word	SRAM_BASE_P
 high_mask:
@@ -183,6 +205,8 @@ api_params:
 	.word	0x4, 0x0, 0x0, 0x1, 0x1
 ENTRY(save_secure_ram_context_sz)
 	.word	. - save_secure_ram_context
+ENTRY(save_secure_ram_context_base)
+	.word	save_secure_ram_context_base
 
 /*
  * Forces OMAP into idle state
@@ -193,6 +217,7 @@ ENTRY(save_secure_ram_context_sz)
  * Note: This code get's copied to internal SRAM at boot. When the OMAP
  *	 wakes up it continues execution at the point it went to sleep.
  */
+	.arm			@ Do this in ARM for now, due to use of SMC.
 ENTRY(omap34xx_cpu_suspend)
 	stmfd	sp!, {r0-r12, lr}		@ save registers on stack
 loop:
@@ -563,10 +588,12 @@ loop2:
 	mov     r9, r4
 	/* create working copy of max way size*/
 loop3:
+	mov     r1, r9, lsl r5
+	mov     r2, r7, lsl r2
 	/* factor way and cache number into r11 */
-	orr     r11, r10, r9, lsl r5
+	orr     r11, r10, r1
 	/* factor index number into r11 */
-	orr     r11, r11, r7, lsl r2
+	orr     r11, r11, r2
 	/*clean & invalidate by set/way */
 	mcr     p15, 0, r11, c7, c10, 2
 	/* decrement the way*/
@@ -631,7 +658,9 @@ wait_dll_lock:
         cmp     r5, #0x4
         bne     wait_dll_lock
         bx      lr
+ENDPROC(omap34xx_cpu_suspend)
 
+	.align
 cm_idlest1_core:
 	.word	CM_IDLEST1_CORE_V
 sdrc_dlla_status:
@@ -670,3 +699,5 @@ control_stat:
 	.word	CONTROL_STAT
 ENTRY(omap34xx_cpu_suspend_sz)
 	.word	. - omap34xx_cpu_suspend
+ENTRY(omap34xx_cpu_suspend_base)
+	.word	omap34xx_cpu_suspend
diff --git a/arch/arm/mach-omap2/sram34xx.S b/arch/arm/mach-omap2/sram34xx.S
index 3637274..65fd54f 100644
--- a/arch/arm/mach-omap2/sram34xx.S
+++ b/arch/arm/mach-omap2/sram34xx.S
@@ -105,29 +105,42 @@
  * can satisfy the above requirement can enable the CONFIG_OMAP3_SDRC_AC_TIMING
  * option.
  */
+__omap3_sram_configure_core_dpll_base:	@ Separate local symbol with the Thumb
+					@ bit _not_ set (for base address when
+					@ copying to sram).
 ENTRY(omap3_sram_configure_core_dpll)
 	stmfd	sp!, {r1-r12, lr}	@ store regs to stack
 
 					@ pull the extra args off the stack
 					@  and store them in SRAM
+
+@ PC-relative stores lead to undefined behaviour in Thumb-2: use a r7 as a
+@ base instead.
+@ Be careful not to clobber r7 when maintaing this file.
+ THUMB(	adr	r7, omap3_sram_configure_core_dpll			)
+	.macro strtext Rt:req, label:req
+ ARM(	str	\Rt, \label						)
+ THUMB(	str	\Rt, [r7, \label - omap3_sram_configure_core_dpll]	)
+	.endm
+
 	ldr	r4, [sp, #52]
-	str     r4, omap_sdrc_rfr_ctrl_0_val
+	strtext	r4, omap_sdrc_rfr_ctrl_0_val
 	ldr	r4, [sp, #56]
-	str     r4, omap_sdrc_actim_ctrl_a_0_val
+	strtext	r4, omap_sdrc_actim_ctrl_a_0_val
 	ldr	r4, [sp, #60]
-	str     r4, omap_sdrc_actim_ctrl_b_0_val
+	strtext	r4, omap_sdrc_actim_ctrl_b_0_val
 	ldr	r4, [sp, #64]
-	str     r4, omap_sdrc_mr_0_val
+	strtext	r4, omap_sdrc_mr_0_val
 	ldr	r4, [sp, #68]
-	str     r4, omap_sdrc_rfr_ctrl_1_val
+	strtext	r4, omap_sdrc_rfr_ctrl_1_val
 	cmp	r4, #0			@ if SDRC_RFR_CTRL_1 is 0,
 	beq	skip_cs1_params		@  do not use cs1 params
 	ldr	r4, [sp, #72]
-	str     r4, omap_sdrc_actim_ctrl_a_1_val
+	strtext	r4, omap_sdrc_actim_ctrl_a_1_val
 	ldr	r4, [sp, #76]
-	str     r4, omap_sdrc_actim_ctrl_b_1_val
+	strtext	r4, omap_sdrc_actim_ctrl_b_1_val
 	ldr	r4, [sp, #80]
-	str     r4, omap_sdrc_mr_1_val
+	strtext	r4, omap_sdrc_mr_1_val
 skip_cs1_params:
 	mrc	p15, 0, r8, c1, c0, 0	@ read ctrl register
 	bic	r10, r8, #0x800		@ clear Z-bit, disable branch prediction
@@ -264,7 +277,9 @@ configure_sdrc:
 skip_cs1_prog:
 	ldr	r12, [r11]		@ posted-write barrier for SDRC
 	bx	lr
+ENDPROC(omap3_sram_configure_core_dpll)
 
+	.align
 omap3_sdrc_power:
 	.word OMAP34XX_SDRC_REGADDR(SDRC_POWER)
 omap3_cm_clksel1_pll:
@@ -316,4 +331,5 @@ core_m2_mask_val:
 
 ENTRY(omap3_sram_configure_core_dpll_sz)
 	.word	. - omap3_sram_configure_core_dpll
-
+ENTRY(omap3_sram_configure_core_dpll_base)
+	.word	__omap3_sram_configure_core_dpll_base
diff --git a/arch/arm/plat-omap/include/plat/sram.h b/arch/arm/plat-omap/include/plat/sram.h
index 5905100..2f27167 100644
--- a/arch/arm/plat-omap/include/plat/sram.h
+++ b/arch/arm/plat-omap/include/plat/sram.h
@@ -67,6 +67,7 @@ extern u32 omap3_sram_configure_core_dpll(
 			u32 sdrc_rfr_ctrl_1, u32 sdrc_actim_ctrl_a_1,
 			u32 sdrc_actim_ctrl_b_1, u32 sdrc_mr_1);
 extern unsigned long omap3_sram_configure_core_dpll_sz;
+extern char *omap3_sram_configure_core_dpll_base;
 
 #ifdef CONFIG_PM
 extern void omap_push_sram_idle(void);
diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c
index e2c8eeb..61282f4 100644
--- a/arch/arm/plat-omap/sram.c
+++ b/arch/arm/plat-omap/sram.c
@@ -386,8 +386,11 @@ void omap3_sram_restore_context(void)
 	omap_sram_ceil = omap_sram_base + omap_sram_size;
 
 	_omap3_sram_configure_core_dpll =
-		omap_sram_push(omap3_sram_configure_core_dpll,
+		omap_sram_push(omap3_sram_configure_core_dpll_base,
 			       omap3_sram_configure_core_dpll_sz);
+	_omap3_sram_configure_core_dpll +=
+		(char *)omap3_sram_configure_core_dpll -
+		omap3_sram_configure_core_dpll_base;
 	omap_push_sram_idle();
 }
 #endif /* CONFIG_PM */
@@ -395,8 +398,11 @@ void omap3_sram_restore_context(void)
 static int __init omap34xx_sram_init(void)
 {
 	_omap3_sram_configure_core_dpll =
-		omap_sram_push(omap3_sram_configure_core_dpll,
+		omap_sram_push(omap3_sram_configure_core_dpll_base,
 			       omap3_sram_configure_core_dpll_sz);
+	_omap3_sram_configure_core_dpll +=
+		(char *)omap3_sram_configure_core_dpll -
+		omap3_sram_configure_core_dpll_base;
 	omap_push_sram_idle();
 	return 0;
 }
