diff options
author | Sang-Hun Lee <sanlee@nvidia.com> | 2012-04-16 10:55:16 -0700 |
---|---|---|
committer | Rohan Somvanshi <rsomvanshi@nvidia.com> | 2012-04-19 07:41:54 -0700 |
commit | 4e1769f2438a00e67f71c887ce0f50efbcb9fc41 (patch) | |
tree | 239215a7a08660856b5fee4477aa51f78e905f51 /arch | |
parent | d37014951a2e983935311582d72ad1fd48db6f5c (diff) |
Revert "ARM: pm: preallocate a page table for suspend/resume"
This reverts commit 55f0f45a45263ba26bd473f50f867d29dd836e46.
Bug 967887
Signed-off-by: Sang-Hun Lee <sanlee@nvidia.com>
Change-Id: I036e0bd4e391a17dec8fa0fe86da7eb6b98d503a
Reviewed-on: http://git-master/r/96795
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Varun Wadekar <vwadekar@nvidia.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/include/asm/suspend.h | 17 | ||||
-rw-r--r-- | arch/arm/kernel/Makefile | 2 | ||||
-rw-r--r-- | arch/arm/kernel/sleep.S | 34 | ||||
-rw-r--r-- | arch/arm/kernel/suspend.c | 48 | ||||
-rw-r--r-- | arch/arm/mm/proc-arm920.S | 4 | ||||
-rw-r--r-- | arch/arm/mm/proc-arm926.S | 4 | ||||
-rw-r--r-- | arch/arm/mm/proc-sa1100.S | 4 | ||||
-rw-r--r-- | arch/arm/mm/proc-v6.S | 6 | ||||
-rw-r--r-- | arch/arm/mm/proc-v7.S | 6 | ||||
-rw-r--r-- | arch/arm/mm/proc-xsc3.S | 6 | ||||
-rw-r--r-- | arch/arm/mm/proc-xscale.S | 4 |
11 files changed, 72 insertions, 63 deletions
diff --git a/arch/arm/include/asm/suspend.h b/arch/arm/include/asm/suspend.h index 1c0a551ae375..b0e4e1a02318 100644 --- a/arch/arm/include/asm/suspend.h +++ b/arch/arm/include/asm/suspend.h @@ -1,7 +1,22 @@ #ifndef __ASM_ARM_SUSPEND_H #define __ASM_ARM_SUSPEND_H +#include <asm/memory.h> +#include <asm/tlbflush.h> + extern void cpu_resume(void); -extern int cpu_suspend(unsigned long, int (*)(unsigned long)); + +/* + * Hide the first two arguments to __cpu_suspend - these are an implementation + * detail which platform code shouldn't have to know about. + */ +static inline int cpu_suspend(unsigned long arg, int (*fn)(unsigned long)) +{ + extern int __cpu_suspend(int, long, unsigned long, + int (*)(unsigned long)); + int ret = __cpu_suspend(0, PHYS_OFFSET - PAGE_OFFSET, arg, fn); + flush_tlb_all(); + return ret; +} #endif diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index 6e84750cdbe8..b6f3c9f80ea7 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile @@ -29,7 +29,7 @@ obj-$(CONFIG_MODULES) += armksyms.o module.o obj-$(CONFIG_ARTHUR) += arthur.o obj-$(CONFIG_ISA_DMA) += dma-isa.o obj-$(CONFIG_PCI) += bios32.o isa.o -obj-$(CONFIG_PM_SLEEP) += sleep.o suspend.o +obj-$(CONFIG_PM_SLEEP) += sleep.o obj-$(CONFIG_HAVE_SCHED_CLOCK) += sched_clock.o obj-$(CONFIG_SMP) += smp.o smp_tlb.o obj-$(CONFIG_HAVE_ARM_SCU) += smp_scu.o diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S index 3aa0e8cc3e91..a723e6b16bf5 100644 --- a/arch/arm/kernel/sleep.S +++ b/arch/arm/kernel/sleep.S @@ -27,7 +27,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!, {r1, r6, ip} @ save v:p, 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 +60,7 @@ ENDPROC(__cpu_suspend) .ltorg cpu_suspend_abort: - ldmia sp!, {r2 - r3} @ pop virt SP, phys resume fn + ldmia sp!, {r1 - r3} @ pop v:p, virt SP, phys resume fn teq r0, #0 moveq r0, #1 @ force non-zero value mov sp, r2 @@ -74,20 +74,28 @@ ENDPROC(cpu_suspend_abort) * r3 = L1 section flags */ ENTRY(cpu_resume_mmu) + adr r4, cpu_resume_turn_mmu_on + mov r4, r4, lsr #20 + orr r3, r3, r4, lsl #20 + ldr r5, [r2, r4, lsl #2] @ save old mapping + str r3, [r2, r4, lsl #2] @ setup 1:1 mapping for mmu code + sub r2, r2, r1 ldr r3, =cpu_resume_after_mmu + bic r1, r0, #CR_C @ ensure D-cache is disabled b cpu_resume_turn_mmu_on ENDPROC(cpu_resume_mmu) .ltorg .align 5 -ENTRY(cpu_resume_turn_mmu_on) - mcr p15, 0, r0, c1, c0, 0 @ turn on MMU, I-cache, etc - mrc p15, 0, r0, c0, c0, 0 @ read id reg - mov r0, r0 - mov r0, r0 +cpu_resume_turn_mmu_on: + mcr p15, 0, r1, c1, c0, 0 @ turn on MMU, I-cache, etc + mrc p15, 0, r1, c0, c0, 0 @ read id reg + mov r1, r1 + mov r1, r1 mov pc, r3 @ jump to virtual address ENDPROC(cpu_resume_turn_mmu_on) cpu_resume_after_mmu: - bl cpu_init + str r5, [r2, r4, lsl #2] @ restore old mapping + mcr p15, 0, r0, c1, c0, 0 @ turn on D-cache mov r0, #0 @ return zero on success ldmfd sp!, {r4 - r11, pc} ENDPROC(cpu_resume_after_mmu) @@ -112,11 +120,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 v:p, 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 deleted file mode 100644 index 0a33f109549d..000000000000 --- a/arch/arm/kernel/suspend.c +++ /dev/null @@ -1,48 +0,0 @@ -#include <linux/init.h> - -#include <asm/pgalloc.h> -#include <asm/pgtable.h> -#include <asm/memory.h> -#include <asm/suspend.h> -#include <asm/tlbflush.h> - -static pgd_t *suspend_pgd; - -extern int __cpu_suspend(int, long, unsigned long, int (*)(unsigned long)); -extern void cpu_resume_turn_mmu_on(void); - -/* - * Hide the first two arguments to __cpu_suspend - these are an implementation - * detail which platform code shouldn't have to know about. - */ -int cpu_suspend(unsigned long arg, int (*fn)(unsigned long)) -{ - struct mm_struct *mm = current->active_mm; - int ret; - - if (!suspend_pgd) - return -EINVAL; - - /* - * Temporarily switch the page tables to our suspend page - * tables, which contain the temporary identity mapping - * required for resuming. - */ - 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(); - - return ret; -} - -static int __init cpu_suspend_init(void) -{ - suspend_pgd = pgd_alloc(&init_mm); - if (suspend_pgd) { - unsigned long addr = virt_to_phys(cpu_resume_turn_mmu_on); - identity_mapping_add(suspend_pgd, addr, addr + SECTION_SIZE); - } - return suspend_pgd ? 0 : -ENOMEM; -} -core_initcall(cpu_suspend_init); diff --git a/arch/arm/mm/proc-arm920.S b/arch/arm/mm/proc-arm920.S index 035d57bf1b7a..2e6849b41f66 100644 --- a/arch/arm/mm/proc-arm920.S +++ b/arch/arm/mm/proc-arm920.S @@ -400,6 +400,10 @@ ENTRY(cpu_arm920_do_resume) mcr p15, 0, r5, c3, c0, 0 @ Domain ID mcr p15, 0, r6, c2, c0, 0 @ TTB address mov r0, r7 @ control register + mov r2, r6, lsr #14 @ get TTB0 base + mov r2, r2, lsl #14 + ldr r3, =PMD_TYPE_SECT | PMD_SECT_BUFFERABLE | \ + PMD_SECT_CACHEABLE | PMD_BIT4 | PMD_SECT_AP_WRITE b cpu_resume_mmu ENDPROC(cpu_arm920_do_resume) #endif diff --git a/arch/arm/mm/proc-arm926.S b/arch/arm/mm/proc-arm926.S index 48add848b997..cd8f79c3a282 100644 --- a/arch/arm/mm/proc-arm926.S +++ b/arch/arm/mm/proc-arm926.S @@ -415,6 +415,10 @@ ENTRY(cpu_arm926_do_resume) mcr p15, 0, r5, c3, c0, 0 @ Domain ID mcr p15, 0, r6, c2, c0, 0 @ TTB address mov r0, r7 @ control register + mov r2, r6, lsr #14 @ get TTB0 base + mov r2, r2, lsl #14 + ldr r3, =PMD_TYPE_SECT | PMD_SECT_BUFFERABLE | \ + PMD_SECT_CACHEABLE | PMD_BIT4 | PMD_SECT_AP_WRITE b cpu_resume_mmu ENDPROC(cpu_arm926_do_resume) #endif diff --git a/arch/arm/mm/proc-sa1100.S b/arch/arm/mm/proc-sa1100.S index 52f73fb47ac1..69e7f2ef7384 100644 --- a/arch/arm/mm/proc-sa1100.S +++ b/arch/arm/mm/proc-sa1100.S @@ -192,6 +192,10 @@ ENTRY(cpu_sa1100_do_resume) mcr p15, 0, r5, c2, c0, 0 @ translation table base addr mcr p15, 0, r6, c13, c0, 0 @ PID mov r0, r7 @ control register + mov r2, r5, lsr #14 @ get TTB0 base + mov r2, r2, lsl #14 + ldr r3, =PMD_TYPE_SECT | PMD_SECT_BUFFERABLE | \ + PMD_SECT_CACHEABLE | PMD_SECT_AP_WRITE b cpu_resume_mmu ENDPROC(cpu_sa1100_do_resume) #endif diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S index 414e3696bdf7..a923aa0fd00d 100644 --- a/arch/arm/mm/proc-v6.S +++ b/arch/arm/mm/proc-v6.S @@ -161,8 +161,14 @@ ENTRY(cpu_v6_do_resume) mcr p15, 0, ip, c2, c0, 2 @ TTB control register mcr p15, 0, ip, c7, c5, 4 @ ISB mov r0, r11 @ control register + mov r2, r7, lsr #14 @ get TTB0 base + mov r2, r2, lsl #14 + ldr r3, cpu_resume_l1_flags b cpu_resume_mmu ENDPROC(cpu_v6_do_resume) +cpu_resume_l1_flags: + ALT_SMP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_FLAGS_SMP) + ALT_UP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_FLAGS_UP) #endif string cpu_v6_name, "ARMv6-compatible processor" diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S index 96385a7fee81..38c78253f769 100644 --- a/arch/arm/mm/proc-v7.S +++ b/arch/arm/mm/proc-v7.S @@ -463,8 +463,14 @@ start_restore_wpt: #endif dsb mov r0, r9 @ control register + mov r2, r7, lsr #14 @ get TTB0 base + mov r2, r2, lsl #14 + ldr r3, cpu_resume_l1_flags b cpu_resume_mmu ENDPROC(cpu_v7_do_resume) +cpu_resume_l1_flags: + ALT_SMP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_FLAGS_SMP) + ALT_UP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_FLAGS_UP) #endif __CPUINIT diff --git a/arch/arm/mm/proc-xsc3.S b/arch/arm/mm/proc-xsc3.S index f6607d315307..1a2021cedc76 100644 --- a/arch/arm/mm/proc-xsc3.S +++ b/arch/arm/mm/proc-xsc3.S @@ -435,7 +435,13 @@ ENTRY(cpu_xsc3_do_resume) mcr p15, 0, r7, c3, c0, 0 @ domain ID mcr p15, 0, r8, c2, c0, 0 @ translation table base addr mcr p15, 0, r9, c1, c0, 1 @ auxiliary control reg + + @ temporarily map resume_turn_on_mmu into the page table, + @ otherwise prefetch abort occurs after MMU is turned on mov r0, r10 @ control register + mov r2, r8, lsr #14 @ get TTB0 base + mov r2, r2, lsl #14 + ldr r3, =0x542e @ section flags b cpu_resume_mmu ENDPROC(cpu_xsc3_do_resume) #endif diff --git a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S index 849fe463df57..b0fe4b1e233d 100644 --- a/arch/arm/mm/proc-xscale.S +++ b/arch/arm/mm/proc-xscale.S @@ -548,6 +548,10 @@ ENTRY(cpu_xscale_do_resume) mcr p15, 0, r8, c2, c0, 0 @ translation table base addr mcr p15, 0, r9, c1, c1, 0 @ auxiliary control reg mov r0, r10 @ control register + mov r2, r8, lsr #14 @ get TTB0 base + mov r2, r2, lsl #14 + ldr r3, =PMD_TYPE_SECT | PMD_SECT_BUFFERABLE | \ + PMD_SECT_CACHEABLE | PMD_SECT_AP_WRITE b cpu_resume_mmu ENDPROC(cpu_xscale_do_resume) #endif |