summaryrefslogtreecommitdiff
path: root/arch/arm/kernel
diff options
context:
space:
mode:
authorSang-Hun Lee <sanlee@nvidia.com>2012-04-16 10:54:09 -0700
committerRohan Somvanshi <rsomvanshi@nvidia.com>2012-04-19 07:40:43 -0700
commitdf448cf33a7683bbddc69fcf5b6f3196e50f2bc8 (patch)
treee203ca1e490f57d6180d9d0eb4a78b2c4bce8cdf /arch/arm/kernel
parent80321fce7facacbeb176410d8b08af592a30304e (diff)
Revert "ARM: pm: convert some assembly to C"
This reverts commit 11a2e1bb69affe9e8273bc6d1452cd9282ddd27a. Bug 967887 Signed-off-by: Sang-Hun Lee <sanlee@nvidia.com> Change-Id: Ibace368a190a14d24e1cc963e8e2a7ed6fdbba6a Reviewed-on: http://git-master/r/96791 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Varun Wadekar <vwadekar@nvidia.com>
Diffstat (limited to 'arch/arm/kernel')
-rw-r--r--arch/arm/kernel/sleep.S53
-rw-r--r--arch/arm/kernel/suspend.c24
2 files changed, 39 insertions, 38 deletions
diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S
index 3f4a517f5b97..54cd05876251 100644
--- a/arch/arm/kernel/sleep.S
+++ b/arch/arm/kernel/sleep.S
@@ -8,35 +8,54 @@
.text
/*
- * Save CPU state for a suspend. This saves the CPU general purpose
- * registers, and allocates space on the kernel stack to save the CPU
- * specific registers and some other data for resume.
- * r0 = suspend function arg0
- * r1 = suspend function
+ * 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 r4, [r10, #CPU_SLEEP_SIZE] @ size of CPU sleep state
+ ldr r5, [r10, #CPU_SLEEP_SIZE] @ size of CPU sleep state
+ ldr ip, [r10, #CPU_DO_RESUME] @ virtual resume function
#else
- ldr r4, =cpu_suspend_size
+ ldr r5, =cpu_suspend_size
+ ldr ip, =cpu_do_resume
#endif
- mov r5, sp @ current virtual SP
- add r4, r4, #12 @ Space for pgd, virt sp, phys resume fn
- sub sp, sp, r4 @ allocate CPU state on stack
- stmfd sp!, {r0, r1} @ save suspend func arg and pointer
- add r0, sp, #8 @ save pointer to save block
- mov r1, r4 @ size of save block
- mov r2, r5 @ virtual SP
- ldr r3, =sleep_save_sp
+ mov r6, sp @ current virtual SP
+ 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!, {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
#ifdef CONFIG_SMP
ALT_SMP(mrc p15, 0, lr, c0, c0, 5)
ALT_UP(mov lr, #0)
and lr, lr, #15
- add r3, r3, lr, lsl #2
+ str r6, [r5, lr, lsl #2] @ save phys SP
+#else
+ str r6, [r5] @ save phys SP
+#endif
+#ifdef MULTI_CPU
+ mov lr, pc
+ ldr pc, [r10, #CPU_DO_SUSPEND] @ save CPU state
+#else
+ bl cpu_do_suspend
+#endif
+
+ @ flush data cache
+#ifdef MULTI_CACHE
+ ldr r10, =cpu_cache
+ mov lr, pc
+ ldr pc, [r10, #CACHE_FLUSH_KERN_ALL]
+#else
+ bl __cpuc_flush_kern_all
#endif
- bl __cpu_suspend_save
adr lr, BSYM(cpu_suspend_abort)
ldmfd sp!, {r0, pc} @ call suspend fn
ENDPROC(__cpu_suspend)
diff --git a/arch/arm/kernel/suspend.c b/arch/arm/kernel/suspend.c
index 2d60f1903206..ed4160b64e66 100644
--- a/arch/arm/kernel/suspend.c
+++ b/arch/arm/kernel/suspend.c
@@ -8,29 +8,10 @@
static pgd_t *suspend_pgd;
-extern int __cpu_suspend(unsigned long, int (*)(unsigned long));
+extern int __cpu_suspend(int, long, unsigned long, int (*)(unsigned long));
extern void cpu_resume_mmu(void);
/*
- * This is called by __cpu_suspend() to save the state, and do whatever
- * flushing is required to ensure that when the CPU goes to sleep we have
- * the necessary data available when the caches are not searched.
- */
-void __cpu_suspend_save(u32 *ptr, u32 ptrsz, u32 sp, u32 *save_ptr)
-{
- *save_ptr = virt_to_phys(ptr);
-
- /* This must correspond to the LDM in cpu_resume() assembly */
- *ptr++ = virt_to_phys(suspend_pgd);
- *ptr++ = sp;
- *ptr++ = virt_to_phys(cpu_do_resume);
-
- cpu_do_suspend(ptr);
-
- flush_cache_all();
-}
-
-/*
* Hide the first two arguments to __cpu_suspend - these are an implementation
* detail which platform code shouldn't have to know about.
*/
@@ -48,7 +29,8 @@ int cpu_suspend(unsigned long arg, int (*fn)(unsigned long))
* resume (indicated by a zero return code), we need to switch
* back to the correct page tables.
*/
- ret = __cpu_suspend(arg, fn);
+ 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();