aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2011-09-22 17:39:23 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2011-09-22 17:39:23 -0400
commitb0a37dca72a05b7b579f288d8a67afeed96bffa5 (patch)
treea3057a3debd078f569e90e709d7b320006d8cb32
parentf70cac8d9c7125f83048f8b3d1c60f5a041a165c (diff)
parent8e6f83bbdf770014c070c5a41c8e89617cb2a66b (diff)
Merge branch 'pm' into devel-stable
-rw-r--r--arch/arm/include/asm/proc-fns.h8
-rw-r--r--arch/arm/include/asm/suspend.h17
-rw-r--r--arch/arm/kernel/Makefile2
-rw-r--r--arch/arm/kernel/sleep.S85
-rw-r--r--arch/arm/kernel/suspend.c72
-rw-r--r--arch/arm/mm/proc-arm920.S21
-rw-r--r--arch/arm/mm/proc-arm926.S21
-rw-r--r--arch/arm/mm/proc-sa1100.S25
-rw-r--r--arch/arm/mm/proc-v6.S44
-rw-r--r--arch/arm/mm/proc-v7.S50
-rw-r--r--arch/arm/mm/proc-xsc3.S28
-rw-r--r--arch/arm/mm/proc-xscale.S25
12 files changed, 197 insertions, 201 deletions
diff --git a/arch/arm/include/asm/proc-fns.h b/arch/arm/include/asm/proc-fns.h
index 633d1cb84d8..9e92cb205e6 100644
--- a/arch/arm/include/asm/proc-fns.h
+++ b/arch/arm/include/asm/proc-fns.h
@@ -81,6 +81,10 @@ extern void cpu_dcache_clean_area(void *, int);
81extern void cpu_do_switch_mm(unsigned long pgd_phys, struct mm_struct *mm); 81extern void cpu_do_switch_mm(unsigned long pgd_phys, struct mm_struct *mm);
82extern void cpu_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext); 82extern void cpu_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext);
83extern void cpu_reset(unsigned long addr) __attribute__((noreturn)); 83extern void cpu_reset(unsigned long addr) __attribute__((noreturn));
84
85/* These three are private to arch/arm/kernel/suspend.c */
86extern void cpu_do_suspend(void *);
87extern void cpu_do_resume(void *);
84#else 88#else
85#define cpu_proc_init processor._proc_init 89#define cpu_proc_init processor._proc_init
86#define cpu_proc_fin processor._proc_fin 90#define cpu_proc_fin processor._proc_fin
@@ -89,6 +93,10 @@ extern void cpu_reset(unsigned long addr) __attribute__((noreturn));
89#define cpu_dcache_clean_area processor.dcache_clean_area 93#define cpu_dcache_clean_area processor.dcache_clean_area
90#define cpu_set_pte_ext processor.set_pte_ext 94#define cpu_set_pte_ext processor.set_pte_ext
91#define cpu_do_switch_mm processor.switch_mm 95#define cpu_do_switch_mm processor.switch_mm
96
97/* These three are private to arch/arm/kernel/suspend.c */
98#define cpu_do_suspend processor.do_suspend
99#define cpu_do_resume processor.do_resume
92#endif 100#endif
93 101
94extern void cpu_resume(void); 102extern void cpu_resume(void);
diff --git a/arch/arm/include/asm/suspend.h b/arch/arm/include/asm/suspend.h
index b0e4e1a0231..1c0a551ae37 100644
--- a/arch/arm/include/asm/suspend.h
+++ b/arch/arm/include/asm/suspend.h
@@ -1,22 +1,7 @@
1#ifndef __ASM_ARM_SUSPEND_H 1#ifndef __ASM_ARM_SUSPEND_H
2#define __ASM_ARM_SUSPEND_H 2#define __ASM_ARM_SUSPEND_H
3 3
4#include <asm/memory.h>
5#include <asm/tlbflush.h>
6
7extern void cpu_resume(void); 4extern void cpu_resume(void);
8 5extern int cpu_suspend(unsigned long, int (*)(unsigned long));
9/*
10 * Hide the first two arguments to __cpu_suspend - these are an implementation
11 * detail which platform code shouldn't have to know about.
12 */
13static inline int cpu_suspend(unsigned long arg, int (*fn)(unsigned long))
14{
15 extern int __cpu_suspend(int, long, unsigned long,
16 int (*)(unsigned long));
17 int ret = __cpu_suspend(0, PHYS_OFFSET - PAGE_OFFSET, arg, fn);
18 flush_tlb_all();
19 return ret;
20}
21 6
22#endif 7#endif
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index af32e466e1c..8fa83f54c96 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -29,7 +29,7 @@ obj-$(CONFIG_MODULES) += armksyms.o module.o
29obj-$(CONFIG_ARTHUR) += arthur.o 29obj-$(CONFIG_ARTHUR) += arthur.o
30obj-$(CONFIG_ISA_DMA) += dma-isa.o 30obj-$(CONFIG_ISA_DMA) += dma-isa.o
31obj-$(CONFIG_PCI) += bios32.o isa.o 31obj-$(CONFIG_PCI) += bios32.o isa.o
32obj-$(CONFIG_PM_SLEEP) += sleep.o 32obj-$(CONFIG_PM_SLEEP) += sleep.o suspend.o
33obj-$(CONFIG_HAVE_SCHED_CLOCK) += sched_clock.o 33obj-$(CONFIG_HAVE_SCHED_CLOCK) += sched_clock.o
34obj-$(CONFIG_SMP) += smp.o smp_tlb.o 34obj-$(CONFIG_SMP) += smp.o smp_tlb.o
35obj-$(CONFIG_HAVE_ARM_SCU) += smp_scu.o 35obj-$(CONFIG_HAVE_ARM_SCU) += smp_scu.o
diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S
index dc902f2c684..020e99c845e 100644
--- a/arch/arm/kernel/sleep.S
+++ b/arch/arm/kernel/sleep.S
@@ -8,92 +8,61 @@
8 .text 8 .text
9 9
10/* 10/*
11 * Save CPU state for a suspend 11 * Save CPU state for a suspend. This saves the CPU general purpose
12 * r1 = v:p offset 12 * registers, and allocates space on the kernel stack to save the CPU
13 * r2 = suspend function arg0 13 * specific registers and some other data for resume.
14 * r3 = suspend function 14 * r0 = suspend function arg0
15 * r1 = suspend function
15 */ 16 */
16ENTRY(__cpu_suspend) 17ENTRY(__cpu_suspend)
17 stmfd sp!, {r4 - r11, lr} 18 stmfd sp!, {r4 - r11, lr}
18#ifdef MULTI_CPU 19#ifdef MULTI_CPU
19 ldr r10, =processor 20 ldr r10, =processor
20 ldr r5, [r10, #CPU_SLEEP_SIZE] @ size of CPU sleep state 21 ldr r4, [r10, #CPU_SLEEP_SIZE] @ size of CPU sleep state
21 ldr ip, [r10, #CPU_DO_RESUME] @ virtual resume function
22#else 22#else
23 ldr r5, =cpu_suspend_size 23 ldr r4, =cpu_suspend_size
24 ldr ip, =cpu_do_resume
25#endif 24#endif
26 mov r6, sp @ current virtual SP 25 mov r5, sp @ current virtual SP
27 sub sp, sp, r5 @ allocate CPU state on stack 26 add r4, r4, #12 @ Space for pgd, virt sp, phys resume fn
28 mov r0, sp @ save pointer to CPU save block 27 sub sp, sp, r4 @ allocate CPU state on stack
29 add ip, ip, r1 @ convert resume fn to phys 28 stmfd sp!, {r0, r1} @ save suspend func arg and pointer
30 stmfd sp!, {r1, r6, ip} @ save v:p, virt SP, phys resume fn 29 add r0, sp, #8 @ save pointer to save block
31 ldr r5, =sleep_save_sp 30 mov r1, r4 @ size of save block
32 add r6, sp, r1 @ convert SP to phys 31 mov r2, r5 @ virtual SP
33 stmfd sp!, {r2, r3} @ save suspend func arg and pointer 32 ldr r3, =sleep_save_sp
34#ifdef CONFIG_SMP 33#ifdef CONFIG_SMP
35 ALT_SMP(mrc p15, 0, lr, c0, c0, 5) 34 ALT_SMP(mrc p15, 0, lr, c0, c0, 5)
36 ALT_UP(mov lr, #0) 35 ALT_UP(mov lr, #0)
37 and lr, lr, #15 36 and lr, lr, #15
38 str r6, [r5, lr, lsl #2] @ save phys SP 37 add r3, r3, lr, lsl #2
39#else
40 str r6, [r5] @ save phys SP
41#endif
42#ifdef MULTI_CPU
43 mov lr, pc
44 ldr pc, [r10, #CPU_DO_SUSPEND] @ save CPU state
45#else
46 bl cpu_do_suspend
47#endif
48
49 @ flush data cache
50#ifdef MULTI_CACHE
51 ldr r10, =cpu_cache
52 mov lr, pc
53 ldr pc, [r10, #CACHE_FLUSH_KERN_ALL]
54#else
55 bl __cpuc_flush_kern_all
56#endif 38#endif
39 bl __cpu_suspend_save
57 adr lr, BSYM(cpu_suspend_abort) 40 adr lr, BSYM(cpu_suspend_abort)
58 ldmfd sp!, {r0, pc} @ call suspend fn 41 ldmfd sp!, {r0, pc} @ call suspend fn
59ENDPROC(__cpu_suspend) 42ENDPROC(__cpu_suspend)
60 .ltorg 43 .ltorg
61 44
62cpu_suspend_abort: 45cpu_suspend_abort:
63 ldmia sp!, {r1 - r3} @ pop v:p, virt SP, phys resume fn 46 ldmia sp!, {r1 - r3} @ pop phys pgd, virt SP, phys resume fn
47 teq r0, #0
48 moveq r0, #1 @ force non-zero value
64 mov sp, r2 49 mov sp, r2
65 ldmfd sp!, {r4 - r11, pc} 50 ldmfd sp!, {r4 - r11, pc}
66ENDPROC(cpu_suspend_abort) 51ENDPROC(cpu_suspend_abort)
67 52
68/* 53/*
69 * r0 = control register value 54 * r0 = control register value
70 * r1 = v:p offset (preserved by cpu_do_resume)
71 * r2 = phys page table base
72 * r3 = L1 section flags
73 */ 55 */
56 .align 5
74ENTRY(cpu_resume_mmu) 57ENTRY(cpu_resume_mmu)
75 adr r4, cpu_resume_turn_mmu_on
76 mov r4, r4, lsr #20
77 orr r3, r3, r4, lsl #20
78 ldr r5, [r2, r4, lsl #2] @ save old mapping
79 str r3, [r2, r4, lsl #2] @ setup 1:1 mapping for mmu code
80 sub r2, r2, r1
81 ldr r3, =cpu_resume_after_mmu 58 ldr r3, =cpu_resume_after_mmu
82 bic r1, r0, #CR_C @ ensure D-cache is disabled 59 mcr p15, 0, r0, c1, c0, 0 @ turn on MMU, I-cache, etc
83 b cpu_resume_turn_mmu_on 60 mrc p15, 0, r0, c0, c0, 0 @ read id reg
84ENDPROC(cpu_resume_mmu) 61 mov r0, r0
85 .ltorg 62 mov r0, r0
86 .align 5
87cpu_resume_turn_mmu_on:
88 mcr p15, 0, r1, c1, c0, 0 @ turn on MMU, I-cache, etc
89 mrc p15, 0, r1, c0, c0, 0 @ read id reg
90 mov r1, r1
91 mov r1, r1
92 mov pc, r3 @ jump to virtual address 63 mov pc, r3 @ jump to virtual address
93ENDPROC(cpu_resume_turn_mmu_on) 64ENDPROC(cpu_resume_mmu)
94cpu_resume_after_mmu: 65cpu_resume_after_mmu:
95 str r5, [r2, r4, lsl #2] @ restore old mapping
96 mcr p15, 0, r0, c1, c0, 0 @ turn on D-cache
97 bl cpu_init @ restore the und/abt/irq banked regs 66 bl cpu_init @ restore the und/abt/irq banked regs
98 mov r0, #0 @ return zero on success 67 mov r0, #0 @ return zero on success
99 ldmfd sp!, {r4 - r11, pc} 68 ldmfd sp!, {r4 - r11, pc}
@@ -119,7 +88,7 @@ ENTRY(cpu_resume)
119 ldr r0, sleep_save_sp @ stack phys addr 88 ldr r0, sleep_save_sp @ stack phys addr
120#endif 89#endif
121 setmode PSR_I_BIT | PSR_F_BIT | SVC_MODE, r1 @ set SVC, irqs off 90 setmode PSR_I_BIT | PSR_F_BIT | SVC_MODE, r1 @ set SVC, irqs off
122 @ load v:p, stack, resume fn 91 @ load phys pgd, stack, resume fn
123 ARM( ldmia r0!, {r1, sp, pc} ) 92 ARM( ldmia r0!, {r1, sp, pc} )
124THUMB( ldmia r0!, {r1, r2, r3} ) 93THUMB( ldmia r0!, {r1, r2, r3} )
125THUMB( mov sp, r2 ) 94THUMB( mov sp, r2 )
diff --git a/arch/arm/kernel/suspend.c b/arch/arm/kernel/suspend.c
new file mode 100644
index 00000000000..93a22d282c1
--- /dev/null
+++ b/arch/arm/kernel/suspend.c
@@ -0,0 +1,72 @@
1#include <linux/init.h>
2
3#include <asm/pgalloc.h>
4#include <asm/pgtable.h>
5#include <asm/memory.h>
6#include <asm/suspend.h>
7#include <asm/tlbflush.h>
8
9static pgd_t *suspend_pgd;
10
11extern int __cpu_suspend(unsigned long, int (*)(unsigned long));
12extern void cpu_resume_mmu(void);
13
14/*
15 * This is called by __cpu_suspend() to save the state, and do whatever
16 * flushing is required to ensure that when the CPU goes to sleep we have
17 * the necessary data available when the caches are not searched.
18 */
19void __cpu_suspend_save(u32 *ptr, u32 ptrsz, u32 sp, u32 *save_ptr)
20{
21 *save_ptr = virt_to_phys(ptr);
22
23 /* This must correspond to the LDM in cpu_resume() assembly */
24 *ptr++ = virt_to_phys(suspend_pgd);
25 *ptr++ = sp;
26 *ptr++ = virt_to_phys(cpu_do_resume);
27
28 cpu_do_suspend(ptr);
29
30 flush_cache_all();
31 outer_clean_range(*save_ptr, *save_ptr + ptrsz);
32 outer_clean_range(virt_to_phys(save_ptr),
33 virt_to_phys(save_ptr) + sizeof(*save_ptr));
34}
35
36/*
37 * Hide the first two arguments to __cpu_suspend - these are an implementation
38 * detail which platform code shouldn't have to know about.
39 */
40int cpu_suspend(unsigned long arg, int (*fn)(unsigned long))
41{
42 struct mm_struct *mm = current->active_mm;
43 int ret;
44
45 if (!suspend_pgd)
46 return -EINVAL;
47
48 /*
49 * Provide a temporary page table with an identity mapping for
50 * the MMU-enable code, required for resuming. On successful
51 * resume (indicated by a zero return code), we need to switch
52 * back to the correct page tables.
53 */
54 ret = __cpu_suspend(arg, fn);
55 if (ret == 0) {
56 cpu_switch_mm(mm->pgd, mm);
57 local_flush_tlb_all();
58 }
59
60 return ret;
61}
62
63static int __init cpu_suspend_init(void)
64{
65 suspend_pgd = pgd_alloc(&init_mm);
66 if (suspend_pgd) {
67 unsigned long addr = virt_to_phys(cpu_resume_mmu);
68 identity_mapping_add(suspend_pgd, addr, addr + SECTION_SIZE);
69 }
70 return suspend_pgd ? 0 : -ENOMEM;
71}
72core_initcall(cpu_suspend_init);
diff --git a/arch/arm/mm/proc-arm920.S b/arch/arm/mm/proc-arm920.S
index 2e6849b41f6..88fb3d9e064 100644
--- a/arch/arm/mm/proc-arm920.S
+++ b/arch/arm/mm/proc-arm920.S
@@ -379,31 +379,26 @@ ENTRY(cpu_arm920_set_pte_ext)
379 379
380/* Suspend/resume support: taken from arch/arm/plat-s3c24xx/sleep.S */ 380/* Suspend/resume support: taken from arch/arm/plat-s3c24xx/sleep.S */
381.globl cpu_arm920_suspend_size 381.globl cpu_arm920_suspend_size
382.equ cpu_arm920_suspend_size, 4 * 4 382.equ cpu_arm920_suspend_size, 4 * 3
383#ifdef CONFIG_PM_SLEEP 383#ifdef CONFIG_PM_SLEEP
384ENTRY(cpu_arm920_do_suspend) 384ENTRY(cpu_arm920_do_suspend)
385 stmfd sp!, {r4 - r7, lr} 385 stmfd sp!, {r4 - r6, lr}
386 mrc p15, 0, r4, c13, c0, 0 @ PID 386 mrc p15, 0, r4, c13, c0, 0 @ PID
387 mrc p15, 0, r5, c3, c0, 0 @ Domain ID 387 mrc p15, 0, r5, c3, c0, 0 @ Domain ID
388 mrc p15, 0, r6, c2, c0, 0 @ TTB address 388 mrc p15, 0, r6, c1, c0, 0 @ Control register
389 mrc p15, 0, r7, c1, c0, 0 @ Control register 389 stmia r0, {r4 - r6}
390 stmia r0, {r4 - r7} 390 ldmfd sp!, {r4 - r6, pc}
391 ldmfd sp!, {r4 - r7, pc}
392ENDPROC(cpu_arm920_do_suspend) 391ENDPROC(cpu_arm920_do_suspend)
393 392
394ENTRY(cpu_arm920_do_resume) 393ENTRY(cpu_arm920_do_resume)
395 mov ip, #0 394 mov ip, #0
396 mcr p15, 0, ip, c8, c7, 0 @ invalidate I+D TLBs 395 mcr p15, 0, ip, c8, c7, 0 @ invalidate I+D TLBs
397 mcr p15, 0, ip, c7, c7, 0 @ invalidate I+D caches 396 mcr p15, 0, ip, c7, c7, 0 @ invalidate I+D caches
398 ldmia r0, {r4 - r7} 397 ldmia r0, {r4 - r6}
399 mcr p15, 0, r4, c13, c0, 0 @ PID 398 mcr p15, 0, r4, c13, c0, 0 @ PID
400 mcr p15, 0, r5, c3, c0, 0 @ Domain ID 399 mcr p15, 0, r5, c3, c0, 0 @ Domain ID
401 mcr p15, 0, r6, c2, c0, 0 @ TTB address 400 mcr p15, 0, r1, c2, c0, 0 @ TTB address
402 mov r0, r7 @ control register 401 mov r0, r6 @ control register
403 mov r2, r6, lsr #14 @ get TTB0 base
404 mov r2, r2, lsl #14
405 ldr r3, =PMD_TYPE_SECT | PMD_SECT_BUFFERABLE | \
406 PMD_SECT_CACHEABLE | PMD_BIT4 | PMD_SECT_AP_WRITE
407 b cpu_resume_mmu 402 b cpu_resume_mmu
408ENDPROC(cpu_arm920_do_resume) 403ENDPROC(cpu_arm920_do_resume)
409#endif 404#endif
diff --git a/arch/arm/mm/proc-arm926.S b/arch/arm/mm/proc-arm926.S
index cd8f79c3a28..9f8fd91f918 100644
--- a/arch/arm/mm/proc-arm926.S
+++ b/arch/arm/mm/proc-arm926.S
@@ -394,31 +394,26 @@ ENTRY(cpu_arm926_set_pte_ext)
394 394
395/* Suspend/resume support: taken from arch/arm/plat-s3c24xx/sleep.S */ 395/* Suspend/resume support: taken from arch/arm/plat-s3c24xx/sleep.S */
396.globl cpu_arm926_suspend_size 396.globl cpu_arm926_suspend_size
397.equ cpu_arm926_suspend_size, 4 * 4 397.equ cpu_arm926_suspend_size, 4 * 3
398#ifdef CONFIG_PM_SLEEP 398#ifdef CONFIG_PM_SLEEP
399ENTRY(cpu_arm926_do_suspend) 399ENTRY(cpu_arm926_do_suspend)
400 stmfd sp!, {r4 - r7, lr} 400 stmfd sp!, {r4 - r6, lr}
401 mrc p15, 0, r4, c13, c0, 0 @ PID 401 mrc p15, 0, r4, c13, c0, 0 @ PID
402 mrc p15, 0, r5, c3, c0, 0 @ Domain ID 402 mrc p15, 0, r5, c3, c0, 0 @ Domain ID
403 mrc p15, 0, r6, c2, c0, 0 @ TTB address 403 mrc p15, 0, r6, c1, c0, 0 @ Control register
404 mrc p15, 0, r7, c1, c0, 0 @ Control register 404 stmia r0, {r4 - r6}
405 stmia r0, {r4 - r7} 405 ldmfd sp!, {r4 - r6, pc}
406 ldmfd sp!, {r4 - r7, pc}
407ENDPROC(cpu_arm926_do_suspend) 406ENDPROC(cpu_arm926_do_suspend)
408 407
409ENTRY(cpu_arm926_do_resume) 408ENTRY(cpu_arm926_do_resume)
410 mov ip, #0 409 mov ip, #0
411 mcr p15, 0, ip, c8, c7, 0 @ invalidate I+D TLBs 410 mcr p15, 0, ip, c8, c7, 0 @ invalidate I+D TLBs
412 mcr p15, 0, ip, c7, c7, 0 @ invalidate I+D caches 411 mcr p15, 0, ip, c7, c7, 0 @ invalidate I+D caches
413 ldmia r0, {r4 - r7} 412 ldmia r0, {r4 - r6}
414 mcr p15, 0, r4, c13, c0, 0 @ PID 413 mcr p15, 0, r4, c13, c0, 0 @ PID
415 mcr p15, 0, r5, c3, c0, 0 @ Domain ID 414 mcr p15, 0, r5, c3, c0, 0 @ Domain ID
416 mcr p15, 0, r6, c2, c0, 0 @ TTB address 415 mcr p15, 0, r1, c2, c0, 0 @ TTB address
417 mov r0, r7 @ control register 416 mov r0, r6 @ control register
418 mov r2, r6, lsr #14 @ get TTB0 base
419 mov r2, r2, lsl #14
420 ldr r3, =PMD_TYPE_SECT | PMD_SECT_BUFFERABLE | \
421 PMD_SECT_CACHEABLE | PMD_BIT4 | PMD_SECT_AP_WRITE
422 b cpu_resume_mmu 417 b cpu_resume_mmu
423ENDPROC(cpu_arm926_do_resume) 418ENDPROC(cpu_arm926_do_resume)
424#endif 419#endif
diff --git a/arch/arm/mm/proc-sa1100.S b/arch/arm/mm/proc-sa1100.S
index 69e7f2ef738..7d91545d089 100644
--- a/arch/arm/mm/proc-sa1100.S
+++ b/arch/arm/mm/proc-sa1100.S
@@ -168,20 +168,19 @@ ENTRY(cpu_sa1100_set_pte_ext)
168 mov pc, lr 168 mov pc, lr
169 169
170.globl cpu_sa1100_suspend_size 170.globl cpu_sa1100_suspend_size
171.equ cpu_sa1100_suspend_size, 4*4 171.equ cpu_sa1100_suspend_size, 4 * 3
172#ifdef CONFIG_PM_SLEEP 172#ifdef CONFIG_PM_SLEEP
173ENTRY(cpu_sa1100_do_suspend) 173ENTRY(cpu_sa1100_do_suspend)
174 stmfd sp!, {r4 - r7, lr} 174 stmfd sp!, {r4 - r6, lr}
175 mrc p15, 0, r4, c3, c0, 0 @ domain ID 175 mrc p15, 0, r4, c3, c0, 0 @ domain ID
176 mrc p15, 0, r5, c2, c0, 0 @ translation table base addr 176 mrc p15, 0, r5, c13, c0, 0 @ PID
177 mrc p15, 0, r6, c13, c0, 0 @ PID 177 mrc p15, 0, r6, c1, c0, 0 @ control reg
178 mrc p15, 0, r7, c1, c0, 0 @ control reg 178 stmia r0, {r4 - r6} @ store cp regs
179 stmia r0, {r4 - r7} @ store cp regs 179 ldmfd sp!, {r4 - r6, pc}
180 ldmfd sp!, {r4 - r7, pc}
181ENDPROC(cpu_sa1100_do_suspend) 180ENDPROC(cpu_sa1100_do_suspend)
182 181
183ENTRY(cpu_sa1100_do_resume) 182ENTRY(cpu_sa1100_do_resume)
184 ldmia r0, {r4 - r7} @ load cp regs 183 ldmia r0, {r4 - r6} @ load cp regs
185 mov ip, #0 184 mov ip, #0
186 mcr p15, 0, ip, c8, c7, 0 @ flush I+D TLBs 185 mcr p15, 0, ip, c8, c7, 0 @ flush I+D TLBs
187 mcr p15, 0, ip, c7, c7, 0 @ flush I&D cache 186 mcr p15, 0, ip, c7, c7, 0 @ flush I&D cache
@@ -189,13 +188,9 @@ ENTRY(cpu_sa1100_do_resume)
189 mcr p15, 0, ip, c9, c0, 5 @ allow user space to use RB 188 mcr p15, 0, ip, c9, c0, 5 @ allow user space to use RB
190 189
191 mcr p15, 0, r4, c3, c0, 0 @ domain ID 190 mcr p15, 0, r4, c3, c0, 0 @ domain ID
192 mcr p15, 0, r5, c2, c0, 0 @ translation table base addr 191 mcr p15, 0, r1, c2, c0, 0 @ translation table base addr
193 mcr p15, 0, r6, c13, c0, 0 @ PID 192 mcr p15, 0, r5, c13, c0, 0 @ PID
194 mov r0, r7 @ control register 193 mov r0, r6 @ control register
195 mov r2, r5, lsr #14 @ get TTB0 base
196 mov r2, r2, lsl #14
197 ldr r3, =PMD_TYPE_SECT | PMD_SECT_BUFFERABLE | \
198 PMD_SECT_CACHEABLE | PMD_SECT_AP_WRITE
199 b cpu_resume_mmu 194 b cpu_resume_mmu
200ENDPROC(cpu_sa1100_do_resume) 195ENDPROC(cpu_sa1100_do_resume)
201#endif 196#endif
diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S
index a923aa0fd00..d061d2fa550 100644
--- a/arch/arm/mm/proc-v6.S
+++ b/arch/arm/mm/proc-v6.S
@@ -128,20 +128,18 @@ ENTRY(cpu_v6_set_pte_ext)
128 128
129/* Suspend/resume support: taken from arch/arm/mach-s3c64xx/sleep.S */ 129/* Suspend/resume support: taken from arch/arm/mach-s3c64xx/sleep.S */
130.globl cpu_v6_suspend_size 130.globl cpu_v6_suspend_size
131.equ cpu_v6_suspend_size, 4 * 8 131.equ cpu_v6_suspend_size, 4 * 6
132#ifdef CONFIG_PM_SLEEP 132#ifdef CONFIG_PM_SLEEP
133ENTRY(cpu_v6_do_suspend) 133ENTRY(cpu_v6_do_suspend)
134 stmfd sp!, {r4 - r11, lr} 134 stmfd sp!, {r4 - r9, lr}
135 mrc p15, 0, r4, c13, c0, 0 @ FCSE/PID 135 mrc p15, 0, r4, c13, c0, 0 @ FCSE/PID
136 mrc p15, 0, r5, c13, c0, 1 @ Context ID 136 mrc p15, 0, r5, c3, c0, 0 @ Domain ID
137 mrc p15, 0, r6, c3, c0, 0 @ Domain ID 137 mrc p15, 0, r6, c2, c0, 1 @ Translation table base 1
138 mrc p15, 0, r7, c2, c0, 0 @ Translation table base 0 138 mrc p15, 0, r7, c1, c0, 1 @ auxiliary control register
139 mrc p15, 0, r8, c2, c0, 1 @ Translation table base 1 139 mrc p15, 0, r8, c1, c0, 2 @ co-processor access control
140 mrc p15, 0, r9, c1, c0, 1 @ auxiliary control register 140 mrc p15, 0, r9, c1, c0, 0 @ control register
141 mrc p15, 0, r10, c1, c0, 2 @ co-processor access control 141 stmia r0, {r4 - r9}
142 mrc p15, 0, r11, c1, c0, 0 @ control register 142 ldmfd sp!, {r4- r9, pc}
143 stmia r0, {r4 - r11}
144 ldmfd sp!, {r4- r11, pc}
145ENDPROC(cpu_v6_do_suspend) 143ENDPROC(cpu_v6_do_suspend)
146 144
147ENTRY(cpu_v6_do_resume) 145ENTRY(cpu_v6_do_resume)
@@ -150,25 +148,21 @@ ENTRY(cpu_v6_do_resume)
150 mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache 148 mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache
151 mcr p15, 0, ip, c7, c15, 0 @ clean+invalidate cache 149 mcr p15, 0, ip, c7, c15, 0 @ clean+invalidate cache
152 mcr p15, 0, ip, c7, c10, 4 @ drain write buffer 150 mcr p15, 0, ip, c7, c10, 4 @ drain write buffer
153 ldmia r0, {r4 - r11} 151 mcr p15, 0, ip, c13, c0, 1 @ set reserved context ID
152 ldmia r0, {r4 - r9}
154 mcr p15, 0, r4, c13, c0, 0 @ FCSE/PID 153 mcr p15, 0, r4, c13, c0, 0 @ FCSE/PID
155 mcr p15, 0, r5, c13, c0, 1 @ Context ID 154 mcr p15, 0, r5, c3, c0, 0 @ Domain ID
156 mcr p15, 0, r6, c3, c0, 0 @ Domain ID 155 ALT_SMP(orr r1, r1, #TTB_FLAGS_SMP)
157 mcr p15, 0, r7, c2, c0, 0 @ Translation table base 0 156 ALT_UP(orr r1, r1, #TTB_FLAGS_UP)
158 mcr p15, 0, r8, c2, c0, 1 @ Translation table base 1 157 mcr p15, 0, r1, c2, c0, 0 @ Translation table base 0
159 mcr p15, 0, r9, c1, c0, 1 @ auxiliary control register 158 mcr p15, 0, r6, c2, c0, 1 @ Translation table base 1
160 mcr p15, 0, r10, c1, c0, 2 @ co-processor access control 159 mcr p15, 0, r7, c1, c0, 1 @ auxiliary control register
160 mcr p15, 0, r8, c1, c0, 2 @ co-processor access control
161 mcr p15, 0, ip, c2, c0, 2 @ TTB control register 161 mcr p15, 0, ip, c2, c0, 2 @ TTB control register
162 mcr p15, 0, ip, c7, c5, 4 @ ISB 162 mcr p15, 0, ip, c7, c5, 4 @ ISB
163 mov r0, r11 @ control register 163 mov r0, r9 @ control register
164 mov r2, r7, lsr #14 @ get TTB0 base
165 mov r2, r2, lsl #14
166 ldr r3, cpu_resume_l1_flags
167 b cpu_resume_mmu 164 b cpu_resume_mmu
168ENDPROC(cpu_v6_do_resume) 165ENDPROC(cpu_v6_do_resume)
169cpu_resume_l1_flags:
170 ALT_SMP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_FLAGS_SMP)
171 ALT_UP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_FLAGS_UP)
172#endif 166#endif
173 167
174 string cpu_v6_name, "ARMv6-compatible processor" 168 string cpu_v6_name, "ARMv6-compatible processor"
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index 9049c0764db..6af366ce016 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -217,56 +217,50 @@ ENDPROC(cpu_v7_set_pte_ext)
217 217
218/* Suspend/resume support: derived from arch/arm/mach-s5pv210/sleep.S */ 218/* Suspend/resume support: derived from arch/arm/mach-s5pv210/sleep.S */
219.globl cpu_v7_suspend_size 219.globl cpu_v7_suspend_size
220.equ cpu_v7_suspend_size, 4 * 9 220.equ cpu_v7_suspend_size, 4 * 7
221#ifdef CONFIG_PM_SLEEP 221#ifdef CONFIG_PM_SLEEP
222ENTRY(cpu_v7_do_suspend) 222ENTRY(cpu_v7_do_suspend)
223 stmfd sp!, {r4 - r11, lr} 223 stmfd sp!, {r4 - r10, lr}
224 mrc p15, 0, r4, c13, c0, 0 @ FCSE/PID 224 mrc p15, 0, r4, c13, c0, 0 @ FCSE/PID
225 mrc p15, 0, r5, c13, c0, 1 @ Context ID 225 mrc p15, 0, r5, c13, c0, 3 @ User r/o thread ID
226 mrc p15, 0, r6, c13, c0, 3 @ User r/o thread ID 226 stmia r0!, {r4 - r5}
227 stmia r0!, {r4 - r6}
228 mrc p15, 0, r6, c3, c0, 0 @ Domain ID 227 mrc p15, 0, r6, c3, c0, 0 @ Domain ID
229 mrc p15, 0, r7, c2, c0, 0 @ TTB 0 228 mrc p15, 0, r7, c2, c0, 1 @ TTB 1
230 mrc p15, 0, r8, c2, c0, 1 @ TTB 1 229 mrc p15, 0, r8, c1, c0, 0 @ Control register
231 mrc p15, 0, r9, c1, c0, 0 @ Control register 230 mrc p15, 0, r9, c1, c0, 1 @ Auxiliary control register
232 mrc p15, 0, r10, c1, c0, 1 @ Auxiliary control register 231 mrc p15, 0, r10, c1, c0, 2 @ Co-processor access control
233 mrc p15, 0, r11, c1, c0, 2 @ Co-processor access control 232 stmia r0, {r6 - r10}
234 stmia r0, {r6 - r11} 233 ldmfd sp!, {r4 - r10, pc}
235 ldmfd sp!, {r4 - r11, pc}
236ENDPROC(cpu_v7_do_suspend) 234ENDPROC(cpu_v7_do_suspend)
237 235
238ENTRY(cpu_v7_do_resume) 236ENTRY(cpu_v7_do_resume)
239 mov ip, #0 237 mov ip, #0
240 mcr p15, 0, ip, c8, c7, 0 @ invalidate TLBs 238 mcr p15, 0, ip, c8, c7, 0 @ invalidate TLBs
241 mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache 239 mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache
242 ldmia r0!, {r4 - r6} 240 mcr p15, 0, ip, c13, c0, 1 @ set reserved context ID
241 ldmia r0!, {r4 - r5}
243 mcr p15, 0, r4, c13, c0, 0 @ FCSE/PID 242 mcr p15, 0, r4, c13, c0, 0 @ FCSE/PID
244 mcr p15, 0, r5, c13, c0, 1 @ Context ID 243 mcr p15, 0, r5, c13, c0, 3 @ User r/o thread ID
245 mcr p15, 0, r6, c13, c0, 3 @ User r/o thread ID 244 ldmia r0, {r6 - r10}
246 ldmia r0, {r6 - r11}
247 mcr p15, 0, r6, c3, c0, 0 @ Domain ID 245 mcr p15, 0, r6, c3, c0, 0 @ Domain ID
248 mcr p15, 0, r7, c2, c0, 0 @ TTB 0 246 ALT_SMP(orr r1, r1, #TTB_FLAGS_SMP)
249 mcr p15, 0, r8, c2, c0, 1 @ TTB 1 247 ALT_UP(orr r1, r1, #TTB_FLAGS_UP)
248 mcr p15, 0, r1, c2, c0, 0 @ TTB 0
249 mcr p15, 0, r7, c2, c0, 1 @ TTB 1
250 mcr p15, 0, ip, c2, c0, 2 @ TTB control register 250 mcr p15, 0, ip, c2, c0, 2 @ TTB control register
251 mrc p15, 0, r4, c1, c0, 1 @ Read Auxiliary control register 251 mrc p15, 0, r4, c1, c0, 1 @ Read Auxiliary control register
252 teq r4, r10 @ Is it already set? 252 teq r4, r9 @ Is it already set?
253 mcrne p15, 0, r10, c1, c0, 1 @ No, so write it 253 mcrne p15, 0, r9, c1, c0, 1 @ No, so write it
254 mcr p15, 0, r11, c1, c0, 2 @ Co-processor access control 254 mcr p15, 0, r10, c1, c0, 2 @ Co-processor access control
255 ldr r4, =PRRR @ PRRR 255 ldr r4, =PRRR @ PRRR
256 ldr r5, =NMRR @ NMRR 256 ldr r5, =NMRR @ NMRR
257 mcr p15, 0, r4, c10, c2, 0 @ write PRRR 257 mcr p15, 0, r4, c10, c2, 0 @ write PRRR
258 mcr p15, 0, r5, c10, c2, 1 @ write NMRR 258 mcr p15, 0, r5, c10, c2, 1 @ write NMRR
259 isb 259 isb
260 dsb 260 dsb
261 mov r0, r9 @ control register 261 mov r0, r8 @ control register
262 mov r2, r7, lsr #14 @ get TTB0 base
263 mov r2, r2, lsl #14
264 ldr r3, cpu_resume_l1_flags
265 b cpu_resume_mmu 262 b cpu_resume_mmu
266ENDPROC(cpu_v7_do_resume) 263ENDPROC(cpu_v7_do_resume)
267cpu_resume_l1_flags:
268 ALT_SMP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_FLAGS_SMP)
269 ALT_UP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_FLAGS_UP)
270#endif 264#endif
271 265
272 __CPUINIT 266 __CPUINIT
diff --git a/arch/arm/mm/proc-xsc3.S b/arch/arm/mm/proc-xsc3.S
index 755e1bf2268..abf0507a08a 100644
--- a/arch/arm/mm/proc-xsc3.S
+++ b/arch/arm/mm/proc-xsc3.S
@@ -406,24 +406,23 @@ ENTRY(cpu_xsc3_set_pte_ext)
406 .align 406 .align
407 407
408.globl cpu_xsc3_suspend_size 408.globl cpu_xsc3_suspend_size
409.equ cpu_xsc3_suspend_size, 4 * 7 409.equ cpu_xsc3_suspend_size, 4 * 6
410#ifdef CONFIG_PM_SLEEP 410#ifdef CONFIG_PM_SLEEP
411ENTRY(cpu_xsc3_do_suspend) 411ENTRY(cpu_xsc3_do_suspend)
412 stmfd sp!, {r4 - r10, lr} 412 stmfd sp!, {r4 - r9, lr}
413 mrc p14, 0, r4, c6, c0, 0 @ clock configuration, for turbo mode 413 mrc p14, 0, r4, c6, c0, 0 @ clock configuration, for turbo mode
414 mrc p15, 0, r5, c15, c1, 0 @ CP access reg 414 mrc p15, 0, r5, c15, c1, 0 @ CP access reg
415 mrc p15, 0, r6, c13, c0, 0 @ PID 415 mrc p15, 0, r6, c13, c0, 0 @ PID
416 mrc p15, 0, r7, c3, c0, 0 @ domain ID 416 mrc p15, 0, r7, c3, c0, 0 @ domain ID
417 mrc p15, 0, r8, c2, c0, 0 @ translation table base addr 417 mrc p15, 0, r8, c1, c0, 1 @ auxiliary control reg
418 mrc p15, 0, r9, c1, c0, 1 @ auxiliary control reg 418 mrc p15, 0, r9, c1, c0, 0 @ control reg
419 mrc p15, 0, r10, c1, c0, 0 @ control reg
420 bic r4, r4, #2 @ clear frequency change bit 419 bic r4, r4, #2 @ clear frequency change bit
421 stmia r0, {r4 - r10} @ store cp regs 420 stmia r0, {r4 - r9} @ store cp regs
422 ldmia sp!, {r4 - r10, pc} 421 ldmia sp!, {r4 - r9, pc}
423ENDPROC(cpu_xsc3_do_suspend) 422ENDPROC(cpu_xsc3_do_suspend)
424 423
425ENTRY(cpu_xsc3_do_resume) 424ENTRY(cpu_xsc3_do_resume)
426 ldmia r0, {r4 - r10} @ load cp regs 425 ldmia r0, {r4 - r9} @ load cp regs
427 mov ip, #0 426 mov ip, #0
428 mcr p15, 0, ip, c7, c7, 0 @ invalidate I & D caches, BTB 427 mcr p15, 0, ip, c7, c7, 0 @ invalidate I & D caches, BTB
429 mcr p15, 0, ip, c7, c10, 4 @ drain write (&fill) buffer 428 mcr p15, 0, ip, c7, c10, 4 @ drain write (&fill) buffer
@@ -433,15 +432,10 @@ ENTRY(cpu_xsc3_do_resume)
433 mcr p15, 0, r5, c15, c1, 0 @ CP access reg 432 mcr p15, 0, r5, c15, c1, 0 @ CP access reg
434 mcr p15, 0, r6, c13, c0, 0 @ PID 433 mcr p15, 0, r6, c13, c0, 0 @ PID
435 mcr p15, 0, r7, c3, c0, 0 @ domain ID 434 mcr p15, 0, r7, c3, c0, 0 @ domain ID
436 mcr p15, 0, r8, c2, c0, 0 @ translation table base addr 435 orr r1, r1, #0x18 @ cache the page table in L2
437 mcr p15, 0, r9, c1, c0, 1 @ auxiliary control reg 436 mcr p15, 0, r1, c2, c0, 0 @ translation table base addr
438 437 mcr p15, 0, r8, c1, c0, 1 @ auxiliary control reg
439 @ temporarily map resume_turn_on_mmu into the page table, 438 mov r0, r9 @ control register
440 @ otherwise prefetch abort occurs after MMU is turned on
441 mov r0, r10 @ control register
442 mov r2, r8, lsr #14 @ get TTB0 base
443 mov r2, r2, lsl #14
444 ldr r3, =0x542e @ section flags
445 b cpu_resume_mmu 439 b cpu_resume_mmu
446ENDPROC(cpu_xsc3_do_resume) 440ENDPROC(cpu_xsc3_do_resume)
447#endif 441#endif
diff --git a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S
index fbc06e55b87..3277904beba 100644
--- a/arch/arm/mm/proc-xscale.S
+++ b/arch/arm/mm/proc-xscale.S
@@ -520,24 +520,23 @@ ENTRY(cpu_xscale_set_pte_ext)
520 .align 520 .align
521 521
522.globl cpu_xscale_suspend_size 522.globl cpu_xscale_suspend_size
523.equ cpu_xscale_suspend_size, 4 * 7 523.equ cpu_xscale_suspend_size, 4 * 6
524#ifdef CONFIG_PM_SLEEP 524#ifdef CONFIG_PM_SLEEP
525ENTRY(cpu_xscale_do_suspend) 525ENTRY(cpu_xscale_do_suspend)
526 stmfd sp!, {r4 - r10, lr} 526 stmfd sp!, {r4 - r9, lr}
527 mrc p14, 0, r4, c6, c0, 0 @ clock configuration, for turbo mode 527 mrc p14, 0, r4, c6, c0, 0 @ clock configuration, for turbo mode
528 mrc p15, 0, r5, c15, c1, 0 @ CP access reg 528 mrc p15, 0, r5, c15, c1, 0 @ CP access reg
529 mrc p15, 0, r6, c13, c0, 0 @ PID 529 mrc p15, 0, r6, c13, c0, 0 @ PID
530 mrc p15, 0, r7, c3, c0, 0 @ domain ID 530 mrc p15, 0, r7, c3, c0, 0 @ domain ID
531 mrc p15, 0, r8, c2, c0, 0 @ translation table base addr 531 mrc p15, 0, r8, c1, c1, 0 @ auxiliary control reg
532 mrc p15, 0, r9, c1, c1, 0 @ auxiliary control reg 532 mrc p15, 0, r9, c1, c0, 0 @ control reg
533 mrc p15, 0, r10, c1, c0, 0 @ control reg
534 bic r4, r4, #2 @ clear frequency change bit 533 bic r4, r4, #2 @ clear frequency change bit
535 stmia r0, {r4 - r10} @ store cp regs 534 stmia r0, {r4 - r9} @ store cp regs
536 ldmfd sp!, {r4 - r10, pc} 535 ldmfd sp!, {r4 - r9, pc}
537ENDPROC(cpu_xscale_do_suspend) 536ENDPROC(cpu_xscale_do_suspend)
538 537
539ENTRY(cpu_xscale_do_resume) 538ENTRY(cpu_xscale_do_resume)
540 ldmia r0, {r4 - r10} @ load cp regs 539 ldmia r0, {r4 - r9} @ load cp regs
541 mov ip, #0 540 mov ip, #0
542 mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs 541 mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
543 mcr p15, 0, ip, c7, c7, 0 @ invalidate I & D caches, BTB 542 mcr p15, 0, ip, c7, c7, 0 @ invalidate I & D caches, BTB
@@ -545,13 +544,9 @@ ENTRY(cpu_xscale_do_resume)
545 mcr p15, 0, r5, c15, c1, 0 @ CP access reg 544 mcr p15, 0, r5, c15, c1, 0 @ CP access reg
546 mcr p15, 0, r6, c13, c0, 0 @ PID 545 mcr p15, 0, r6, c13, c0, 0 @ PID
547 mcr p15, 0, r7, c3, c0, 0 @ domain ID 546 mcr p15, 0, r7, c3, c0, 0 @ domain ID
548 mcr p15, 0, r8, c2, c0, 0 @ translation table base addr 547 mcr p15, 0, r1, c2, c0, 0 @ translation table base addr
549 mcr p15, 0, r9, c1, c1, 0 @ auxiliary control reg 548 mcr p15, 0, r8, c1, c1, 0 @ auxiliary control reg
550 mov r0, r10 @ control register 549 mov r0, r9 @ control register
551 mov r2, r8, lsr #14 @ get TTB0 base
552 mov r2, r2, lsl #14
553 ldr r3, =PMD_TYPE_SECT | PMD_SECT_BUFFERABLE | \
554 PMD_SECT_CACHEABLE | PMD_SECT_AP_WRITE
555 b cpu_resume_mmu 550 b cpu_resume_mmu
556ENDPROC(cpu_xscale_do_resume) 551ENDPROC(cpu_xscale_do_resume)
557#endif 552#endif