summaryrefslogtreecommitdiff
path: root/arch/arm/kernel
diff options
context:
space:
mode:
authorVarun Wadekar <vwadekar@nvidia.com>2012-03-27 17:26:39 +0530
committerSimone Willett <swillett@nvidia.com>2012-04-05 17:52:25 -0700
commit46d9f14943770c24603ef7cdfd8eb2dbcd3c1248 (patch)
treec8aa28791f49856d583e83831d2aab328e3e821f /arch/arm/kernel
parent55f0f45a45263ba26bd473f50f867d29dd836e46 (diff)
ARM: pm: only use preallocated page table during resume
Only use the preallocated page table during the resume, not while suspending. This avoids the overhead of having to switch unnecessarily to the resume page table in the suspend path. Change-Id: Ib71c9b60b0ec39749aadc6f592549d213e6a852e Tested-by: Santosh Shilimkar <santosh.shilimkar@ti.com> Tested-by: Shawn Guo <shawn.guo@linaro.org> Tested-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> Signed-off-by: Varun Wadekar <vwadekar@nvidia.com> Reviewed-on: http://git-master/r/85725 Reviewed-by: Automatic_Commit_Validation_User
Diffstat (limited to 'arch/arm/kernel')
-rw-r--r--arch/arm/kernel/sleep.S19
-rw-r--r--arch/arm/kernel/suspend.c17
2 files changed, 19 insertions, 17 deletions
diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S
index 3aa0e8cc3e91..9d403d6c56d3 100644
--- a/arch/arm/kernel/sleep.S
+++ b/arch/arm/kernel/sleep.S
@@ -9,12 +9,14 @@
/*
* Save CPU state for a suspend
+ * r0 = phys addr of temporary page tables
* r1 = v:p offset
* r2 = suspend function arg0
* r3 = suspend function
*/
ENTRY(__cpu_suspend)
stmfd sp!, {r4 - r11, lr}
+ mov r4, r0
#ifdef MULTI_CPU
ldr r10, =processor
ldr r5, [r10, #CPU_SLEEP_SIZE] @ size of CPU sleep state
@@ -27,7 +29,7 @@ ENTRY(__cpu_suspend)
sub sp, sp, r5 @ allocate CPU state on stack
mov r0, sp @ save pointer to CPU save block
add ip, ip, r1 @ convert resume fn to phys
- stmfd sp!, {r6, ip} @ save virt SP, phys resume fn
+ stmfd sp!, {r4, r6, ip} @ save phys pgd, virt SP, phys resume fn
ldr r5, =sleep_save_sp
add r6, sp, r1 @ convert SP to phys
stmfd sp!, {r2, r3} @ save suspend func arg and pointer
@@ -60,7 +62,7 @@ ENDPROC(__cpu_suspend)
.ltorg
cpu_suspend_abort:
- ldmia sp!, {r2 - r3} @ pop virt SP, phys resume fn
+ ldmia sp!, {r1 - r3} @ pop phys pgd, virt SP, phys resume fn
teq r0, #0
moveq r0, #1 @ force non-zero value
mov sp, r2
@@ -69,9 +71,6 @@ ENDPROC(cpu_suspend_abort)
/*
* r0 = control register value
- * r1 = v:p offset (preserved by cpu_do_resume)
- * r2 = phys page table base
- * r3 = L1 section flags
*/
ENTRY(cpu_resume_mmu)
ldr r3, =cpu_resume_after_mmu
@@ -112,11 +111,11 @@ ENTRY(cpu_resume)
ldr r0, sleep_save_sp @ stack phys addr
#endif
setmode PSR_I_BIT | PSR_F_BIT | SVC_MODE, r1 @ set SVC, irqs off
- @ load stack, resume fn
- ARM( ldmia r0!, {sp, pc} )
-THUMB( ldmia r0!, {r2, r3} )
-THUMB( mov sp, r2 )
-THUMB( bx r3 )
+ @ load phys pgd, stack, resume fn
+ ARM( ldmia r0!, {r1, sp, pc} )
+THUMB( ldmia r0!, {r1, r2, r3} )
+THUMB( mov sp, r2 )
+THUMB( bx r3 )
ENDPROC(cpu_resume)
sleep_save_sp:
diff --git a/arch/arm/kernel/suspend.c b/arch/arm/kernel/suspend.c
index 0a33f109549d..2beda56e4574 100644
--- a/arch/arm/kernel/suspend.c
+++ b/arch/arm/kernel/suspend.c
@@ -24,14 +24,17 @@ int cpu_suspend(unsigned long arg, int (*fn)(unsigned long))
return -EINVAL;
/*
- * Temporarily switch the page tables to our suspend page
- * tables, which contain the temporary identity mapping
- * required for resuming.
+ * Provide a temporary page table with an identity mapping for
+ * the MMU-enable code, required for resuming. On successful
+ * resume (indicated by a zero return code), we need to switch
+ * back to the correct page tables.
*/
- cpu_switch_mm(suspend_pgd, mm);
- ret = __cpu_suspend(0, PHYS_OFFSET - PAGE_OFFSET, arg, fn);
- cpu_switch_mm(mm->pgd, mm);
- local_flush_tlb_all();
+ ret = __cpu_suspend(virt_to_phys(suspend_pgd),
+ PHYS_OFFSET - PAGE_OFFSET, arg, fn);
+ if (ret == 0) {
+ cpu_switch_mm(mm->pgd, mm);
+ local_flush_tlb_all();
+ }
return ret;
}