All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/11] Add L2 cache cleaning to generic CPU suspend
@ 2011-09-01 12:47 ` Russell King - ARM Linux
  0 siblings, 0 replies; 56+ messages in thread
From: Russell King - ARM Linux @ 2011-09-01 12:47 UTC (permalink / raw)
  To: Santosh Shilimkar; +Cc: linux-omap, linux-arm-kernel

Some systems (such as OMAP) preserve the L2 cache across a suspend/
resume cycle.  This means they do not perform L2 cache maintanence
in their suspend finisher function.

However, the side effect is that the saved CPU state is not readable
by the resume code because it is sitting in the L2 cache.

This patch series adds L2 cache cleaning to the generic CPU suspend/
resume support code, making it possible to use this on systems with
L2 cache enabled without having to clean/invalidate the entire L2
cache.

We also add a separate page table, allocated at boot time, for the
resume process to use so we don't have to fiddle about with tweaking
entries in the current processes page table.  Moreover, the current
processes page table may be in use by another CPU in the system if
these paths are used from cpuidle or hotplug, so changing the page
table is technically unsound.

Overall, this makes it possible for OMAP4 systems to use this code.

The first four patches in this set are already merged into Linus' tree
as bug fixes, and are included here for completeness given that the
kernel.org infrastructure is currently offline.

This has (so far) only been tested on OMAP4.  Further testing on OMAP3
and Assabet will follow.

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [PATCH 00/11] Add L2 cache cleaning to generic CPU suspend
@ 2011-09-01 12:47 ` Russell King - ARM Linux
  0 siblings, 0 replies; 56+ messages in thread
From: Russell King - ARM Linux @ 2011-09-01 12:47 UTC (permalink / raw)
  To: linux-arm-kernel

Some systems (such as OMAP) preserve the L2 cache across a suspend/
resume cycle.  This means they do not perform L2 cache maintanence
in their suspend finisher function.

However, the side effect is that the saved CPU state is not readable
by the resume code because it is sitting in the L2 cache.

This patch series adds L2 cache cleaning to the generic CPU suspend/
resume support code, making it possible to use this on systems with
L2 cache enabled without having to clean/invalidate the entire L2
cache.

We also add a separate page table, allocated at boot time, for the
resume process to use so we don't have to fiddle about with tweaking
entries in the current processes page table.  Moreover, the current
processes page table may be in use by another CPU in the system if
these paths are used from cpuidle or hotplug, so changing the page
table is technically unsound.

Overall, this makes it possible for OMAP4 systems to use this code.

The first four patches in this set are already merged into Linus' tree
as bug fixes, and are included here for completeness given that the
kernel.org infrastructure is currently offline.

This has (so far) only been tested on OMAP4.  Further testing on OMAP3
and Assabet will follow.

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [PATCH 01/11] ARM: pm: CPU specific code should not overwrite r1 (v:p offset)
  2011-09-01 12:47 ` Russell King - ARM Linux
@ 2011-09-01 12:48   ` Russell King - ARM Linux
  -1 siblings, 0 replies; 56+ messages in thread
From: Russell King - ARM Linux @ 2011-09-01 12:48 UTC (permalink / raw)
  To: Santosh Shilimkar; +Cc: linux-arm-kernel, linux-omap

r1 stores the v:p offset from the CPU invariant resume code, and is
expected to be preserved by the CPU specific code.  Overwriting it is
not a good idea.

We've managed to get away with it on sa1100 platforms because most
happen to have PHYS_OFFSET == PAGE_OFFSET, but that may not be the
case depending on kernel configuration.  So fix this latent bug.

This fixes xsc3 as well which was saving and restoring this register
independently.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/mm/proc-sa1100.S |   10 +++++-----
 arch/arm/mm/proc-xsc3.S   |    6 +++---
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/arch/arm/mm/proc-sa1100.S b/arch/arm/mm/proc-sa1100.S
index 07219c2..69e7f2e 100644
--- a/arch/arm/mm/proc-sa1100.S
+++ b/arch/arm/mm/proc-sa1100.S
@@ -182,11 +182,11 @@ ENDPROC(cpu_sa1100_do_suspend)
 
 ENTRY(cpu_sa1100_do_resume)
 	ldmia	r0, {r4 - r7}			@ load cp regs
-	mov	r1, #0
-	mcr	p15, 0, r1, c8, c7, 0		@ flush I+D TLBs
-	mcr	p15, 0, r1, c7, c7, 0		@ flush I&D cache
-	mcr	p15, 0, r1, c9, c0, 0		@ invalidate RB
-	mcr	p15, 0, r1, c9, c0, 5		@ allow user space to use RB
+	mov	ip, #0
+	mcr	p15, 0, ip, c8, c7, 0		@ flush I+D TLBs
+	mcr	p15, 0, ip, c7, c7, 0		@ flush I&D cache
+	mcr	p15, 0, ip, c9, c0, 0		@ invalidate RB
+	mcr	p15, 0, ip, c9, c0, 5		@ allow user space to use RB
 
 	mcr	p15, 0, r4, c3, c0, 0		@ domain ID
 	mcr	p15, 0, r5, c2, c0, 0		@ translation table base addr
diff --git a/arch/arm/mm/proc-xsc3.S b/arch/arm/mm/proc-xsc3.S
index 28c72a2..755e1bf 100644
--- a/arch/arm/mm/proc-xsc3.S
+++ b/arch/arm/mm/proc-xsc3.S
@@ -406,7 +406,7 @@ ENTRY(cpu_xsc3_set_pte_ext)
 	.align
 
 .globl	cpu_xsc3_suspend_size
-.equ	cpu_xsc3_suspend_size, 4 * 8
+.equ	cpu_xsc3_suspend_size, 4 * 7
 #ifdef CONFIG_PM_SLEEP
 ENTRY(cpu_xsc3_do_suspend)
 	stmfd	sp!, {r4 - r10, lr}
@@ -418,12 +418,12 @@ ENTRY(cpu_xsc3_do_suspend)
 	mrc	p15, 0, r9, c1, c0, 1	@ auxiliary control reg
 	mrc 	p15, 0, r10, c1, c0, 0	@ control reg
 	bic	r4, r4, #2		@ clear frequency change bit
-	stmia	r0, {r1, r4 - r10}	@ store v:p offset + cp regs
+	stmia	r0, {r4 - r10}		@ store cp regs
 	ldmia	sp!, {r4 - r10, pc}
 ENDPROC(cpu_xsc3_do_suspend)
 
 ENTRY(cpu_xsc3_do_resume)
-	ldmia	r0, {r1, r4 - r10}	@ load v:p offset + cp regs
+	ldmia	r0, {r4 - r10}		@ load cp regs
 	mov	ip, #0
 	mcr	p15, 0, ip, c7, c7, 0	@ invalidate I & D caches, BTB
 	mcr	p15, 0, ip, c7, c10, 4	@ drain write (&fill) buffer
-- 
1.7.4.4


^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [PATCH 01/11] ARM: pm: CPU specific code should not overwrite r1 (v:p offset)
@ 2011-09-01 12:48   ` Russell King - ARM Linux
  0 siblings, 0 replies; 56+ messages in thread
From: Russell King - ARM Linux @ 2011-09-01 12:48 UTC (permalink / raw)
  To: linux-arm-kernel

r1 stores the v:p offset from the CPU invariant resume code, and is
expected to be preserved by the CPU specific code.  Overwriting it is
not a good idea.

We've managed to get away with it on sa1100 platforms because most
happen to have PHYS_OFFSET == PAGE_OFFSET, but that may not be the
case depending on kernel configuration.  So fix this latent bug.

This fixes xsc3 as well which was saving and restoring this register
independently.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/mm/proc-sa1100.S |   10 +++++-----
 arch/arm/mm/proc-xsc3.S   |    6 +++---
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/arch/arm/mm/proc-sa1100.S b/arch/arm/mm/proc-sa1100.S
index 07219c2..69e7f2e 100644
--- a/arch/arm/mm/proc-sa1100.S
+++ b/arch/arm/mm/proc-sa1100.S
@@ -182,11 +182,11 @@ ENDPROC(cpu_sa1100_do_suspend)
 
 ENTRY(cpu_sa1100_do_resume)
 	ldmia	r0, {r4 - r7}			@ load cp regs
-	mov	r1, #0
-	mcr	p15, 0, r1, c8, c7, 0		@ flush I+D TLBs
-	mcr	p15, 0, r1, c7, c7, 0		@ flush I&D cache
-	mcr	p15, 0, r1, c9, c0, 0		@ invalidate RB
-	mcr	p15, 0, r1, c9, c0, 5		@ allow user space to use RB
+	mov	ip, #0
+	mcr	p15, 0, ip, c8, c7, 0		@ flush I+D TLBs
+	mcr	p15, 0, ip, c7, c7, 0		@ flush I&D cache
+	mcr	p15, 0, ip, c9, c0, 0		@ invalidate RB
+	mcr	p15, 0, ip, c9, c0, 5		@ allow user space to use RB
 
 	mcr	p15, 0, r4, c3, c0, 0		@ domain ID
 	mcr	p15, 0, r5, c2, c0, 0		@ translation table base addr
diff --git a/arch/arm/mm/proc-xsc3.S b/arch/arm/mm/proc-xsc3.S
index 28c72a2..755e1bf 100644
--- a/arch/arm/mm/proc-xsc3.S
+++ b/arch/arm/mm/proc-xsc3.S
@@ -406,7 +406,7 @@ ENTRY(cpu_xsc3_set_pte_ext)
 	.align
 
 .globl	cpu_xsc3_suspend_size
-.equ	cpu_xsc3_suspend_size, 4 * 8
+.equ	cpu_xsc3_suspend_size, 4 * 7
 #ifdef CONFIG_PM_SLEEP
 ENTRY(cpu_xsc3_do_suspend)
 	stmfd	sp!, {r4 - r10, lr}
@@ -418,12 +418,12 @@ ENTRY(cpu_xsc3_do_suspend)
 	mrc	p15, 0, r9, c1, c0, 1	@ auxiliary control reg
 	mrc 	p15, 0, r10, c1, c0, 0	@ control reg
 	bic	r4, r4, #2		@ clear frequency change bit
-	stmia	r0, {r1, r4 - r10}	@ store v:p offset + cp regs
+	stmia	r0, {r4 - r10}		@ store cp regs
 	ldmia	sp!, {r4 - r10, pc}
 ENDPROC(cpu_xsc3_do_suspend)
 
 ENTRY(cpu_xsc3_do_resume)
-	ldmia	r0, {r1, r4 - r10}	@ load v:p offset + cp regs
+	ldmia	r0, {r4 - r10}		@ load cp regs
 	mov	ip, #0
 	mcr	p15, 0, ip, c7, c7, 0	@ invalidate I & D caches, BTB
 	mcr	p15, 0, ip, c7, c10, 4	@ drain write (&fill) buffer
-- 
1.7.4.4

^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [PATCH 02/11] ARM: pm: arm920/926: fix number of registers saved
  2011-09-01 12:47 ` Russell King - ARM Linux
@ 2011-09-01 12:48   ` Russell King - ARM Linux
  -1 siblings, 0 replies; 56+ messages in thread
From: Russell King - ARM Linux @ 2011-09-01 12:48 UTC (permalink / raw)
  To: Santosh Shilimkar; +Cc: linux-arm-kernel, linux-omap

ARM920 and ARM926 save four registers, not three.  Fix the size of
the suspend region required.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/mm/proc-arm920.S |    2 +-
 arch/arm/mm/proc-arm926.S |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mm/proc-arm920.S b/arch/arm/mm/proc-arm920.S
index 92bd102..2e6849b 100644
--- a/arch/arm/mm/proc-arm920.S
+++ b/arch/arm/mm/proc-arm920.S
@@ -379,7 +379,7 @@ ENTRY(cpu_arm920_set_pte_ext)
 
 /* Suspend/resume support: taken from arch/arm/plat-s3c24xx/sleep.S */
 .globl	cpu_arm920_suspend_size
-.equ	cpu_arm920_suspend_size, 4 * 3
+.equ	cpu_arm920_suspend_size, 4 * 4
 #ifdef CONFIG_PM_SLEEP
 ENTRY(cpu_arm920_do_suspend)
 	stmfd	sp!, {r4 - r7, lr}
diff --git a/arch/arm/mm/proc-arm926.S b/arch/arm/mm/proc-arm926.S
index 2bbcf05..cd8f79c 100644
--- a/arch/arm/mm/proc-arm926.S
+++ b/arch/arm/mm/proc-arm926.S
@@ -394,7 +394,7 @@ ENTRY(cpu_arm926_set_pte_ext)
 
 /* Suspend/resume support: taken from arch/arm/plat-s3c24xx/sleep.S */
 .globl	cpu_arm926_suspend_size
-.equ	cpu_arm926_suspend_size, 4 * 3
+.equ	cpu_arm926_suspend_size, 4 * 4
 #ifdef CONFIG_PM_SLEEP
 ENTRY(cpu_arm926_do_suspend)
 	stmfd	sp!, {r4 - r7, lr}
-- 
1.7.4.4


^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [PATCH 02/11] ARM: pm: arm920/926: fix number of registers saved
@ 2011-09-01 12:48   ` Russell King - ARM Linux
  0 siblings, 0 replies; 56+ messages in thread
From: Russell King - ARM Linux @ 2011-09-01 12:48 UTC (permalink / raw)
  To: linux-arm-kernel

ARM920 and ARM926 save four registers, not three.  Fix the size of
the suspend region required.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/mm/proc-arm920.S |    2 +-
 arch/arm/mm/proc-arm926.S |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mm/proc-arm920.S b/arch/arm/mm/proc-arm920.S
index 92bd102..2e6849b 100644
--- a/arch/arm/mm/proc-arm920.S
+++ b/arch/arm/mm/proc-arm920.S
@@ -379,7 +379,7 @@ ENTRY(cpu_arm920_set_pte_ext)
 
 /* Suspend/resume support: taken from arch/arm/plat-s3c24xx/sleep.S */
 .globl	cpu_arm920_suspend_size
-.equ	cpu_arm920_suspend_size, 4 * 3
+.equ	cpu_arm920_suspend_size, 4 * 4
 #ifdef CONFIG_PM_SLEEP
 ENTRY(cpu_arm920_do_suspend)
 	stmfd	sp!, {r4 - r7, lr}
diff --git a/arch/arm/mm/proc-arm926.S b/arch/arm/mm/proc-arm926.S
index 2bbcf05..cd8f79c 100644
--- a/arch/arm/mm/proc-arm926.S
+++ b/arch/arm/mm/proc-arm926.S
@@ -394,7 +394,7 @@ ENTRY(cpu_arm926_set_pte_ext)
 
 /* Suspend/resume support: taken from arch/arm/plat-s3c24xx/sleep.S */
 .globl	cpu_arm926_suspend_size
-.equ	cpu_arm926_suspend_size, 4 * 3
+.equ	cpu_arm926_suspend_size, 4 * 4
 #ifdef CONFIG_PM_SLEEP
 ENTRY(cpu_arm926_do_suspend)
 	stmfd	sp!, {r4 - r7, lr}
-- 
1.7.4.4

^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [PATCH 03/11] ARM: pm: some ARMv7 requires a dsb in resume to ensure correctness
  2011-09-01 12:47 ` Russell King - ARM Linux
@ 2011-09-01 12:49   ` Russell King - ARM Linux
  -1 siblings, 0 replies; 56+ messages in thread
From: Russell King - ARM Linux @ 2011-09-01 12:49 UTC (permalink / raw)
  To: Santosh Shilimkar; +Cc: linux-arm-kernel, linux-omap

Add a dsb after the isb to ensure that the previous writes to the
CP15 registers take effect before we enable the MMU.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/mm/proc-v7.S |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index dec72ee..a773f4e 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -255,6 +255,7 @@ ENTRY(cpu_v7_do_resume)
 	mcr	p15, 0, r4, c10, c2, 0	@ write PRRR
 	mcr	p15, 0, r5, c10, c2, 1	@ write NMRR
 	isb
+	dsb
 	mov	r0, r9			@ control register
 	mov	r2, r7, lsr #14		@ get TTB0 base
 	mov	r2, r2, lsl #14
-- 
1.7.4.4


^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [PATCH 03/11] ARM: pm: some ARMv7 requires a dsb in resume to ensure correctness
@ 2011-09-01 12:49   ` Russell King - ARM Linux
  0 siblings, 0 replies; 56+ messages in thread
From: Russell King - ARM Linux @ 2011-09-01 12:49 UTC (permalink / raw)
  To: linux-arm-kernel

Add a dsb after the isb to ensure that the previous writes to the
CP15 registers take effect before we enable the MMU.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/mm/proc-v7.S |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index dec72ee..a773f4e 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -255,6 +255,7 @@ ENTRY(cpu_v7_do_resume)
 	mcr	p15, 0, r4, c10, c2, 0	@ write PRRR
 	mcr	p15, 0, r5, c10, c2, 1	@ write NMRR
 	isb
+	dsb
 	mov	r0, r9			@ control register
 	mov	r2, r7, lsr #14		@ get TTB0 base
 	mov	r2, r2, lsl #14
-- 
1.7.4.4

^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [PATCH 04/11] ARM: pm: avoid writing the auxillary control register for ARMv7
  2011-09-01 12:47 ` Russell King - ARM Linux
@ 2011-09-01 12:49   ` Russell King - ARM Linux
  -1 siblings, 0 replies; 56+ messages in thread
From: Russell King - ARM Linux @ 2011-09-01 12:49 UTC (permalink / raw)
  To: Santosh Shilimkar; +Cc: linux-arm-kernel, linux-omap

For ARMv7 kernels running in the non-secure world, writing to the
auxillary control register causes an abort, so we must avoid directly
writing the auxillary control register.  If the ACR has already been
reinitialized by SoC code, don't try to restore it.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/mm/proc-v7.S |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index a773f4e..9049c07 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -248,7 +248,9 @@ ENTRY(cpu_v7_do_resume)
 	mcr	p15, 0, r7, c2, c0, 0	@ TTB 0
 	mcr	p15, 0, r8, c2, c0, 1	@ TTB 1
 	mcr	p15, 0, ip, c2, c0, 2	@ TTB control register
-	mcr	p15, 0, r10, c1, c0, 1	@ Auxiliary control register
+	mrc	p15, 0, r4, c1, c0, 1	@ Read Auxiliary control register
+	teq	r4, r10			@ Is it already set?
+	mcrne	p15, 0, r10, c1, c0, 1	@ No, so write it
 	mcr	p15, 0, r11, c1, c0, 2	@ Co-processor access control
 	ldr	r4, =PRRR		@ PRRR
 	ldr	r5, =NMRR		@ NMRR
-- 
1.7.4.4


^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [PATCH 04/11] ARM: pm: avoid writing the auxillary control register for ARMv7
@ 2011-09-01 12:49   ` Russell King - ARM Linux
  0 siblings, 0 replies; 56+ messages in thread
From: Russell King - ARM Linux @ 2011-09-01 12:49 UTC (permalink / raw)
  To: linux-arm-kernel

For ARMv7 kernels running in the non-secure world, writing to the
auxillary control register causes an abort, so we must avoid directly
writing the auxillary control register.  If the ACR has already been
reinitialized by SoC code, don't try to restore it.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/mm/proc-v7.S |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index a773f4e..9049c07 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -248,7 +248,9 @@ ENTRY(cpu_v7_do_resume)
 	mcr	p15, 0, r7, c2, c0, 0	@ TTB 0
 	mcr	p15, 0, r8, c2, c0, 1	@ TTB 1
 	mcr	p15, 0, ip, c2, c0, 2	@ TTB control register
-	mcr	p15, 0, r10, c1, c0, 1	@ Auxiliary control register
+	mrc	p15, 0, r4, c1, c0, 1	@ Read Auxiliary control register
+	teq	r4, r10			@ Is it already set?
+	mcrne	p15, 0, r10, c1, c0, 1	@ No, so write it
 	mcr	p15, 0, r11, c1, c0, 2	@ Co-processor access control
 	ldr	r4, =PRRR		@ PRRR
 	ldr	r5, =NMRR		@ NMRR
-- 
1.7.4.4

^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [PATCH 05/11] ARM: pm: force non-zero return value from __cpu_suspend when aborting
  2011-09-01 12:47 ` Russell King - ARM Linux
@ 2011-09-01 12:49   ` Russell King - ARM Linux
  -1 siblings, 0 replies; 56+ messages in thread
From: Russell King - ARM Linux @ 2011-09-01 12:49 UTC (permalink / raw)
  To: Santosh Shilimkar; +Cc: linux-arm-kernel, linux-omap

Ensure that the return value from __cpu_suspend is non-zero when
aborting.  Zero indicates a successful suspend occurred.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/kernel/sleep.S |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S
index dc902f2..46a9f46 100644
--- a/arch/arm/kernel/sleep.S
+++ b/arch/arm/kernel/sleep.S
@@ -61,6 +61,8 @@ ENDPROC(__cpu_suspend)
 
 cpu_suspend_abort:
 	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
 	ldmfd	sp!, {r4 - r11, pc}
 ENDPROC(cpu_suspend_abort)
-- 
1.7.4.4


^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [PATCH 05/11] ARM: pm: force non-zero return value from __cpu_suspend when aborting
@ 2011-09-01 12:49   ` Russell King - ARM Linux
  0 siblings, 0 replies; 56+ messages in thread
From: Russell King - ARM Linux @ 2011-09-01 12:49 UTC (permalink / raw)
  To: linux-arm-kernel

Ensure that the return value from __cpu_suspend is non-zero when
aborting.  Zero indicates a successful suspend occurred.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/kernel/sleep.S |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S
index dc902f2..46a9f46 100644
--- a/arch/arm/kernel/sleep.S
+++ b/arch/arm/kernel/sleep.S
@@ -61,6 +61,8 @@ ENDPROC(__cpu_suspend)
 
 cpu_suspend_abort:
 	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
 	ldmfd	sp!, {r4 - r11, pc}
 ENDPROC(cpu_suspend_abort)
-- 
1.7.4.4

^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [PATCH 06/11] ARM: pm: preallocate a page table for suspend/resume
  2011-09-01 12:47 ` Russell King - ARM Linux
@ 2011-09-01 12:50   ` Russell King - ARM Linux
  -1 siblings, 0 replies; 56+ messages in thread
From: Russell King - ARM Linux @ 2011-09-01 12:50 UTC (permalink / raw)
  To: Santosh Shilimkar; +Cc: linux-omap, linux-arm-kernel

Preallocate a page table and setup an identity mapping for the MMU
enable code.  This means we don't have to "borrow" a page table to
do this, avoiding complexities with L2 cache coherency.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/include/asm/suspend.h |   17 +-------------
 arch/arm/kernel/Makefile       |    2 +-
 arch/arm/kernel/sleep.S        |   33 ++++++++++-----------------
 arch/arm/kernel/suspend.c      |   47 ++++++++++++++++++++++++++++++++++++++++
 arch/arm/mm/proc-arm920.S      |    4 ---
 arch/arm/mm/proc-arm926.S      |    4 ---
 arch/arm/mm/proc-sa1100.S      |    4 ---
 arch/arm/mm/proc-v6.S          |    6 -----
 arch/arm/mm/proc-v7.S          |    6 -----
 arch/arm/mm/proc-xsc3.S        |    6 -----
 arch/arm/mm/proc-xscale.S      |    4 ---
 11 files changed, 61 insertions(+), 72 deletions(-)
 create mode 100644 arch/arm/kernel/suspend.c

diff --git a/arch/arm/include/asm/suspend.h b/arch/arm/include/asm/suspend.h
index b0e4e1a..1c0a551 100644
--- a/arch/arm/include/asm/suspend.h
+++ b/arch/arm/include/asm/suspend.h
@@ -1,22 +1,7 @@
 #ifndef __ASM_ARM_SUSPEND_H
 #define __ASM_ARM_SUSPEND_H
 
-#include <asm/memory.h>
-#include <asm/tlbflush.h>
-
 extern void cpu_resume(void);
-
-/*
- * 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;
-}
+extern int cpu_suspend(unsigned long, int (*)(unsigned long));
 
 #endif
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index f7887dc..787b888 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
+obj-$(CONFIG_PM_SLEEP)		+= sleep.o suspend.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 46a9f46..8cf13de 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!, {r1, r6, ip}	@ save v:p, virt SP, phys resume fn
+	stmfd	sp!, {r6, ip}		@ save 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!, {r1 - r3}		@ pop v:p, virt SP, phys resume fn
+	ldmia	sp!, {r2 - r3}		@ pop virt SP, phys resume fn
 	teq	r0, #0
 	moveq	r0, #1			@ force non-zero value
 	mov	sp, r2
@@ -74,28 +74,19 @@ 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
-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
+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
 	mov	pc, r3			@ jump to virtual address
 ENDPROC(cpu_resume_turn_mmu_on)
 cpu_resume_after_mmu:
-	str	r5, [r2, r4, lsl #2]	@ restore old mapping
-	mcr	p15, 0, r0, c1, c0, 0	@ turn on D-cache
 	bl	cpu_init		@ restore the und/abt/irq banked regs
 	mov	r0, #0			@ return zero on success
 	ldmfd	sp!, {r4 - r11, pc}
@@ -121,11 +112,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 v:p, stack, resume fn
-  ARM(	ldmia	r0!, {r1, sp, pc}	)
-THUMB(	ldmia	r0!, {r1, r2, r3}	)
-THUMB(	mov	sp, r2			)
-THUMB(	bx	r3			)
+	@ load stack, resume fn
+  ARM(	ldmia	r0!, {sp, pc}	)
+THUMB(	ldmia	r0!, {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
new file mode 100644
index 0000000..4d9ac3d
--- /dev/null
+++ b/arch/arm/kernel/suspend.c
@@ -0,0 +1,47 @@
+#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);
+
+	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 2e6849b..035d57b 100644
--- a/arch/arm/mm/proc-arm920.S
+++ b/arch/arm/mm/proc-arm920.S
@@ -400,10 +400,6 @@ 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 cd8f79c..48add84 100644
--- a/arch/arm/mm/proc-arm926.S
+++ b/arch/arm/mm/proc-arm926.S
@@ -415,10 +415,6 @@ 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 69e7f2e..52f73fb 100644
--- a/arch/arm/mm/proc-sa1100.S
+++ b/arch/arm/mm/proc-sa1100.S
@@ -192,10 +192,6 @@ 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 a923aa0..414e369 100644
--- a/arch/arm/mm/proc-v6.S
+++ b/arch/arm/mm/proc-v6.S
@@ -161,14 +161,8 @@ 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 9049c07..21d6910 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -259,14 +259,8 @@ ENTRY(cpu_v7_do_resume)
 	isb
 	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 755e1bf..efd4949 100644
--- a/arch/arm/mm/proc-xsc3.S
+++ b/arch/arm/mm/proc-xsc3.S
@@ -435,13 +435,7 @@ 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 fbc06e5..37dbada 100644
--- a/arch/arm/mm/proc-xscale.S
+++ b/arch/arm/mm/proc-xscale.S
@@ -548,10 +548,6 @@ 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
-- 
1.7.4.4

^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [PATCH 06/11] ARM: pm: preallocate a page table for suspend/resume
@ 2011-09-01 12:50   ` Russell King - ARM Linux
  0 siblings, 0 replies; 56+ messages in thread
From: Russell King - ARM Linux @ 2011-09-01 12:50 UTC (permalink / raw)
  To: linux-arm-kernel

Preallocate a page table and setup an identity mapping for the MMU
enable code.  This means we don't have to "borrow" a page table to
do this, avoiding complexities with L2 cache coherency.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/include/asm/suspend.h |   17 +-------------
 arch/arm/kernel/Makefile       |    2 +-
 arch/arm/kernel/sleep.S        |   33 ++++++++++-----------------
 arch/arm/kernel/suspend.c      |   47 ++++++++++++++++++++++++++++++++++++++++
 arch/arm/mm/proc-arm920.S      |    4 ---
 arch/arm/mm/proc-arm926.S      |    4 ---
 arch/arm/mm/proc-sa1100.S      |    4 ---
 arch/arm/mm/proc-v6.S          |    6 -----
 arch/arm/mm/proc-v7.S          |    6 -----
 arch/arm/mm/proc-xsc3.S        |    6 -----
 arch/arm/mm/proc-xscale.S      |    4 ---
 11 files changed, 61 insertions(+), 72 deletions(-)
 create mode 100644 arch/arm/kernel/suspend.c

diff --git a/arch/arm/include/asm/suspend.h b/arch/arm/include/asm/suspend.h
index b0e4e1a..1c0a551 100644
--- a/arch/arm/include/asm/suspend.h
+++ b/arch/arm/include/asm/suspend.h
@@ -1,22 +1,7 @@
 #ifndef __ASM_ARM_SUSPEND_H
 #define __ASM_ARM_SUSPEND_H
 
-#include <asm/memory.h>
-#include <asm/tlbflush.h>
-
 extern void cpu_resume(void);
-
-/*
- * 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;
-}
+extern int cpu_suspend(unsigned long, int (*)(unsigned long));
 
 #endif
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index f7887dc..787b888 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
+obj-$(CONFIG_PM_SLEEP)		+= sleep.o suspend.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 46a9f46..8cf13de 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!, {r1, r6, ip}	@ save v:p, virt SP, phys resume fn
+	stmfd	sp!, {r6, ip}		@ save 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!, {r1 - r3}		@ pop v:p, virt SP, phys resume fn
+	ldmia	sp!, {r2 - r3}		@ pop virt SP, phys resume fn
 	teq	r0, #0
 	moveq	r0, #1			@ force non-zero value
 	mov	sp, r2
@@ -74,28 +74,19 @@ 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
-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
+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
 	mov	pc, r3			@ jump to virtual address
 ENDPROC(cpu_resume_turn_mmu_on)
 cpu_resume_after_mmu:
-	str	r5, [r2, r4, lsl #2]	@ restore old mapping
-	mcr	p15, 0, r0, c1, c0, 0	@ turn on D-cache
 	bl	cpu_init		@ restore the und/abt/irq banked regs
 	mov	r0, #0			@ return zero on success
 	ldmfd	sp!, {r4 - r11, pc}
@@ -121,11 +112,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 v:p, stack, resume fn
-  ARM(	ldmia	r0!, {r1, sp, pc}	)
-THUMB(	ldmia	r0!, {r1, r2, r3}	)
-THUMB(	mov	sp, r2			)
-THUMB(	bx	r3			)
+	@ load stack, resume fn
+  ARM(	ldmia	r0!, {sp, pc}	)
+THUMB(	ldmia	r0!, {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
new file mode 100644
index 0000000..4d9ac3d
--- /dev/null
+++ b/arch/arm/kernel/suspend.c
@@ -0,0 +1,47 @@
+#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);
+
+	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 2e6849b..035d57b 100644
--- a/arch/arm/mm/proc-arm920.S
+++ b/arch/arm/mm/proc-arm920.S
@@ -400,10 +400,6 @@ 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 cd8f79c..48add84 100644
--- a/arch/arm/mm/proc-arm926.S
+++ b/arch/arm/mm/proc-arm926.S
@@ -415,10 +415,6 @@ 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 69e7f2e..52f73fb 100644
--- a/arch/arm/mm/proc-sa1100.S
+++ b/arch/arm/mm/proc-sa1100.S
@@ -192,10 +192,6 @@ 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 a923aa0..414e369 100644
--- a/arch/arm/mm/proc-v6.S
+++ b/arch/arm/mm/proc-v6.S
@@ -161,14 +161,8 @@ 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 9049c07..21d6910 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -259,14 +259,8 @@ ENTRY(cpu_v7_do_resume)
 	isb
 	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 755e1bf..efd4949 100644
--- a/arch/arm/mm/proc-xsc3.S
+++ b/arch/arm/mm/proc-xsc3.S
@@ -435,13 +435,7 @@ 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 fbc06e5..37dbada 100644
--- a/arch/arm/mm/proc-xscale.S
+++ b/arch/arm/mm/proc-xscale.S
@@ -548,10 +548,6 @@ 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
-- 
1.7.4.4

^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [PATCH 07/11] ARM: pm: only use preallocated page table during resume
  2011-09-01 12:47 ` Russell King - ARM Linux
@ 2011-09-01 12:50   ` Russell King - ARM Linux
  -1 siblings, 0 replies; 56+ messages in thread
From: Russell King - ARM Linux @ 2011-09-01 12:50 UTC (permalink / raw)
  To: Santosh Shilimkar; +Cc: linux-arm-kernel, linux-omap

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.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/kernel/sleep.S   |   19 +++++++++----------
 arch/arm/kernel/suspend.c |   14 ++++++++------
 arch/arm/mm/proc-arm920.S |   17 ++++++++---------
 arch/arm/mm/proc-arm926.S |   17 ++++++++---------
 arch/arm/mm/proc-sa1100.S |   21 ++++++++++-----------
 arch/arm/mm/proc-v6.S     |   31 ++++++++++++++++---------------
 arch/arm/mm/proc-v7.S     |   33 +++++++++++++++++----------------
 arch/arm/mm/proc-xsc3.S   |   22 +++++++++++-----------
 arch/arm/mm/proc-xscale.S |   21 ++++++++++-----------
 9 files changed, 97 insertions(+), 98 deletions(-)

diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S
index 8cf13de..25d42df 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 4d9ac3d..7606122 100644
--- a/arch/arm/kernel/suspend.c
+++ b/arch/arm/kernel/suspend.c
@@ -24,13 +24,15 @@ 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);
+	ret = __cpu_suspend(virt_to_phys(suspend_pgd),
+			    PHYS_OFFSET - PAGE_OFFSET, arg, fn);
+	if (ret == 0)
+		cpu_switch_mm(mm->pgd, mm);
 
 	return ret;
 }
diff --git a/arch/arm/mm/proc-arm920.S b/arch/arm/mm/proc-arm920.S
index 035d57b..88fb3d9 100644
--- a/arch/arm/mm/proc-arm920.S
+++ b/arch/arm/mm/proc-arm920.S
@@ -379,27 +379,26 @@ ENTRY(cpu_arm920_set_pte_ext)
 
 /* Suspend/resume support: taken from arch/arm/plat-s3c24xx/sleep.S */
 .globl	cpu_arm920_suspend_size
-.equ	cpu_arm920_suspend_size, 4 * 4
+.equ	cpu_arm920_suspend_size, 4 * 3
 #ifdef CONFIG_PM_SLEEP
 ENTRY(cpu_arm920_do_suspend)
-	stmfd	sp!, {r4 - r7, lr}
+	stmfd	sp!, {r4 - r6, lr}
 	mrc	p15, 0, r4, c13, c0, 0	@ PID
 	mrc	p15, 0, r5, c3, c0, 0	@ Domain ID
-	mrc	p15, 0, r6, c2, c0, 0	@ TTB address
-	mrc	p15, 0, r7, c1, c0, 0	@ Control register
-	stmia	r0, {r4 - r7}
-	ldmfd	sp!, {r4 - r7, pc}
+	mrc	p15, 0, r6, c1, c0, 0	@ Control register
+	stmia	r0, {r4 - r6}
+	ldmfd	sp!, {r4 - r6, pc}
 ENDPROC(cpu_arm920_do_suspend)
 
 ENTRY(cpu_arm920_do_resume)
 	mov	ip, #0
 	mcr	p15, 0, ip, c8, c7, 0	@ invalidate I+D TLBs
 	mcr	p15, 0, ip, c7, c7, 0	@ invalidate I+D caches
-	ldmia	r0, {r4 - r7}
+	ldmia	r0, {r4 - r6}
 	mcr	p15, 0, r4, c13, c0, 0	@ PID
 	mcr	p15, 0, r5, c3, c0, 0	@ Domain ID
-	mcr	p15, 0, r6, c2, c0, 0	@ TTB address
-	mov	r0, r7			@ control register
+	mcr	p15, 0, r1, c2, c0, 0	@ TTB address
+	mov	r0, r6			@ control register
 	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 48add84..9f8fd91 100644
--- a/arch/arm/mm/proc-arm926.S
+++ b/arch/arm/mm/proc-arm926.S
@@ -394,27 +394,26 @@ ENTRY(cpu_arm926_set_pte_ext)
 
 /* Suspend/resume support: taken from arch/arm/plat-s3c24xx/sleep.S */
 .globl	cpu_arm926_suspend_size
-.equ	cpu_arm926_suspend_size, 4 * 4
+.equ	cpu_arm926_suspend_size, 4 * 3
 #ifdef CONFIG_PM_SLEEP
 ENTRY(cpu_arm926_do_suspend)
-	stmfd	sp!, {r4 - r7, lr}
+	stmfd	sp!, {r4 - r6, lr}
 	mrc	p15, 0, r4, c13, c0, 0	@ PID
 	mrc	p15, 0, r5, c3, c0, 0	@ Domain ID
-	mrc	p15, 0, r6, c2, c0, 0	@ TTB address
-	mrc	p15, 0, r7, c1, c0, 0	@ Control register
-	stmia	r0, {r4 - r7}
-	ldmfd	sp!, {r4 - r7, pc}
+	mrc	p15, 0, r6, c1, c0, 0	@ Control register
+	stmia	r0, {r4 - r6}
+	ldmfd	sp!, {r4 - r6, pc}
 ENDPROC(cpu_arm926_do_suspend)
 
 ENTRY(cpu_arm926_do_resume)
 	mov	ip, #0
 	mcr	p15, 0, ip, c8, c7, 0	@ invalidate I+D TLBs
 	mcr	p15, 0, ip, c7, c7, 0	@ invalidate I+D caches
-	ldmia	r0, {r4 - r7}
+	ldmia	r0, {r4 - r6}
 	mcr	p15, 0, r4, c13, c0, 0	@ PID
 	mcr	p15, 0, r5, c3, c0, 0	@ Domain ID
-	mcr	p15, 0, r6, c2, c0, 0	@ TTB address
-	mov	r0, r7			@ control register
+	mcr	p15, 0, r1, c2, c0, 0	@ TTB address
+	mov	r0, r6			@ control register
 	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 52f73fb..7d91545 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)
 	mov	pc, lr
 
 .globl	cpu_sa1100_suspend_size
-.equ	cpu_sa1100_suspend_size, 4*4
+.equ	cpu_sa1100_suspend_size, 4 * 3
 #ifdef CONFIG_PM_SLEEP
 ENTRY(cpu_sa1100_do_suspend)
-	stmfd	sp!, {r4 - r7, lr}
+	stmfd	sp!, {r4 - r6, lr}
 	mrc	p15, 0, r4, c3, c0, 0		@ domain ID
-	mrc	p15, 0, r5, c2, c0, 0		@ translation table base addr
-	mrc	p15, 0, r6, c13, c0, 0		@ PID
-	mrc	p15, 0, r7, c1, c0, 0		@ control reg
-	stmia	r0, {r4 - r7}			@ store cp regs
-	ldmfd	sp!, {r4 - r7, pc}
+	mrc	p15, 0, r5, c13, c0, 0		@ PID
+	mrc	p15, 0, r6, c1, c0, 0		@ control reg
+	stmia	r0, {r4 - r6}			@ store cp regs
+	ldmfd	sp!, {r4 - r6, pc}
 ENDPROC(cpu_sa1100_do_suspend)
 
 ENTRY(cpu_sa1100_do_resume)
-	ldmia	r0, {r4 - r7}			@ load cp regs
+	ldmia	r0, {r4 - r6}			@ load cp regs
 	mov	ip, #0
 	mcr	p15, 0, ip, c8, c7, 0		@ flush I+D TLBs
 	mcr	p15, 0, ip, c7, c7, 0		@ flush I&D cache
@@ -189,9 +188,9 @@ ENTRY(cpu_sa1100_do_resume)
 	mcr	p15, 0, ip, c9, c0, 5		@ allow user space to use RB
 
 	mcr	p15, 0, r4, c3, c0, 0		@ domain ID
-	mcr	p15, 0, r5, c2, c0, 0		@ translation table base addr
-	mcr	p15, 0, r6, c13, c0, 0		@ PID
-	mov	r0, r7				@ control register
+	mcr	p15, 0, r1, c2, c0, 0		@ translation table base addr
+	mcr	p15, 0, r5, c13, c0, 0		@ PID
+	mov	r0, r6				@ control register
 	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 414e369..2e27b46 100644
--- a/arch/arm/mm/proc-v6.S
+++ b/arch/arm/mm/proc-v6.S
@@ -128,20 +128,19 @@ ENTRY(cpu_v6_set_pte_ext)
 
 /* Suspend/resume support: taken from arch/arm/mach-s3c64xx/sleep.S */
 .globl	cpu_v6_suspend_size
-.equ	cpu_v6_suspend_size, 4 * 8
+.equ	cpu_v6_suspend_size, 4 * 7
 #ifdef CONFIG_PM_SLEEP
 ENTRY(cpu_v6_do_suspend)
-	stmfd	sp!, {r4 - r11, lr}
+	stmfd	sp!, {r4 - r10, lr}
 	mrc	p15, 0, r4, c13, c0, 0	@ FCSE/PID
 	mrc	p15, 0, r5, c13, c0, 1	@ Context ID
 	mrc	p15, 0, r6, c3, c0, 0	@ Domain ID
-	mrc	p15, 0, r7, c2, c0, 0	@ Translation table base 0
-	mrc	p15, 0, r8, c2, c0, 1	@ Translation table base 1
-	mrc	p15, 0, r9, c1, c0, 1	@ auxiliary control register
-	mrc	p15, 0, r10, c1, c0, 2	@ co-processor access control
-	mrc	p15, 0, r11, c1, c0, 0	@ control register
-	stmia	r0, {r4 - r11}
-	ldmfd	sp!, {r4- r11, pc}
+	mrc	p15, 0, r7, c2, c0, 1	@ Translation table base 1
+	mrc	p15, 0, r8, c1, c0, 1	@ auxiliary control register
+	mrc	p15, 0, r9, c1, c0, 2	@ co-processor access control
+	mrc	p15, 0, r10, c1, c0, 0	@ control register
+	stmia	r0, {r4 - r10}
+	ldmfd	sp!, {r4- r10, pc}
 ENDPROC(cpu_v6_do_suspend)
 
 ENTRY(cpu_v6_do_resume)
@@ -150,17 +149,19 @@ ENTRY(cpu_v6_do_resume)
 	mcr	p15, 0, ip, c7, c5, 0	@ invalidate I cache
 	mcr	p15, 0, ip, c7, c15, 0	@ clean+invalidate cache
 	mcr	p15, 0, ip, c7, c10, 4	@ drain write buffer
-	ldmia	r0, {r4 - r11}
+	ldmia	r0, {r4 - r10}
 	mcr	p15, 0, r4, c13, c0, 0	@ FCSE/PID
 	mcr	p15, 0, r5, c13, c0, 1	@ Context ID
 	mcr	p15, 0, r6, c3, c0, 0	@ Domain ID
-	mcr	p15, 0, r7, c2, c0, 0	@ Translation table base 0
-	mcr	p15, 0, r8, c2, c0, 1	@ Translation table base 1
-	mcr	p15, 0, r9, c1, c0, 1	@ auxiliary control register
-	mcr	p15, 0, r10, c1, c0, 2	@ co-processor access control
+	ALT_SMP(orr	r1, r1, #TTB_FLAGS_SMP)
+	ALT_UP(orr	r1, r1, #TTB_FLAGS_UP)
+	mcr	p15, 0, r1, c2, c0, 0	@ Translation table base 0
+	mcr	p15, 0, r7, c2, c0, 1	@ Translation table base 1
+	mcr	p15, 0, r8, c1, c0, 1	@ auxiliary control register
+	mcr	p15, 0, r9, c1, c0, 2	@ co-processor access control
 	mcr	p15, 0, ip, c2, c0, 2	@ TTB control register
 	mcr	p15, 0, ip, c7, c5, 4	@ ISB
-	mov	r0, r11			@ control register
+	mov	r0, r10			@ control register
 	b	cpu_resume_mmu
 ENDPROC(cpu_v6_do_resume)
 #endif
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index 21d6910..b56004f 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -217,22 +217,21 @@ ENDPROC(cpu_v7_set_pte_ext)
 
 /* Suspend/resume support: derived from arch/arm/mach-s5pv210/sleep.S */
 .globl	cpu_v7_suspend_size
-.equ	cpu_v7_suspend_size, 4 * 9
+.equ	cpu_v7_suspend_size, 4 * 8
 #ifdef CONFIG_PM_SLEEP
 ENTRY(cpu_v7_do_suspend)
-	stmfd	sp!, {r4 - r11, lr}
+	stmfd	sp!, {r4 - r10, lr}
 	mrc	p15, 0, r4, c13, c0, 0	@ FCSE/PID
 	mrc	p15, 0, r5, c13, c0, 1	@ Context ID
 	mrc	p15, 0, r6, c13, c0, 3	@ User r/o thread ID
 	stmia	r0!, {r4 - r6}
 	mrc	p15, 0, r6, c3, c0, 0	@ Domain ID
-	mrc	p15, 0, r7, c2, c0, 0	@ TTB 0
-	mrc	p15, 0, r8, c2, c0, 1	@ TTB 1
-	mrc	p15, 0, r9, c1, c0, 0	@ Control register
-	mrc	p15, 0, r10, c1, c0, 1	@ Auxiliary control register
-	mrc	p15, 0, r11, c1, c0, 2	@ Co-processor access control
-	stmia	r0, {r6 - r11}
-	ldmfd	sp!, {r4 - r11, pc}
+	mrc	p15, 0, r7, c2, c0, 1	@ TTB 1
+	mrc	p15, 0, r8, c1, c0, 0	@ Control register
+	mrc	p15, 0, r9, c1, c0, 1	@ Auxiliary control register
+	mrc	p15, 0, r10, c1, c0, 2	@ Co-processor access control
+	stmia	r0, {r6 - r10}
+	ldmfd	sp!, {r4 - r10, pc}
 ENDPROC(cpu_v7_do_suspend)
 
 ENTRY(cpu_v7_do_resume)
@@ -243,22 +242,24 @@ ENTRY(cpu_v7_do_resume)
 	mcr	p15, 0, r4, c13, c0, 0	@ FCSE/PID
 	mcr	p15, 0, r5, c13, c0, 1	@ Context ID
 	mcr	p15, 0, r6, c13, c0, 3	@ User r/o thread ID
-	ldmia	r0, {r6 - r11}
+	ldmia	r0, {r6 - r10}
 	mcr	p15, 0, r6, c3, c0, 0	@ Domain ID
-	mcr	p15, 0, r7, c2, c0, 0	@ TTB 0
-	mcr	p15, 0, r8, c2, c0, 1	@ TTB 1
+	ALT_SMP(orr	r1, r1, #TTB_FLAGS_SMP)
+	ALT_UP(orr	r1, r1, #TTB_FLAGS_UP)
+	mcr	p15, 0, r1, c2, c0, 0	@ TTB 0
+	mcr	p15, 0, r7, c2, c0, 1	@ TTB 1
 	mcr	p15, 0, ip, c2, c0, 2	@ TTB control register
 	mrc	p15, 0, r4, c1, c0, 1	@ Read Auxiliary control register
-	teq	r4, r10			@ Is it already set?
-	mcrne	p15, 0, r10, c1, c0, 1	@ No, so write it
-	mcr	p15, 0, r11, c1, c0, 2	@ Co-processor access control
+	teq	r4, r9			@ Is it already set?
+	mcrne	p15, 0, r9, c1, c0, 1	@ No, so write it
+	mcr	p15, 0, r10, c1, c0, 2	@ Co-processor access control
 	ldr	r4, =PRRR		@ PRRR
 	ldr	r5, =NMRR		@ NMRR
 	mcr	p15, 0, r4, c10, c2, 0	@ write PRRR
 	mcr	p15, 0, r5, c10, c2, 1	@ write NMRR
 	isb
 	dsb
-	mov	r0, r9			@ control register
+	mov	r0, r8			@ control register
 	b	cpu_resume_mmu
 ENDPROC(cpu_v7_do_resume)
 #endif
diff --git a/arch/arm/mm/proc-xsc3.S b/arch/arm/mm/proc-xsc3.S
index efd4949..abf0507 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)
 	.align
 
 .globl	cpu_xsc3_suspend_size
-.equ	cpu_xsc3_suspend_size, 4 * 7
+.equ	cpu_xsc3_suspend_size, 4 * 6
 #ifdef CONFIG_PM_SLEEP
 ENTRY(cpu_xsc3_do_suspend)
-	stmfd	sp!, {r4 - r10, lr}
+	stmfd	sp!, {r4 - r9, lr}
 	mrc	p14, 0, r4, c6, c0, 0	@ clock configuration, for turbo mode
 	mrc	p15, 0, r5, c15, c1, 0	@ CP access reg
 	mrc	p15, 0, r6, c13, c0, 0	@ PID
 	mrc 	p15, 0, r7, c3, c0, 0	@ domain ID
-	mrc 	p15, 0, r8, c2, c0, 0	@ translation table base addr
-	mrc	p15, 0, r9, c1, c0, 1	@ auxiliary control reg
-	mrc 	p15, 0, r10, c1, c0, 0	@ control reg
+	mrc	p15, 0, r8, c1, c0, 1	@ auxiliary control reg
+	mrc 	p15, 0, r9, c1, c0, 0	@ control reg
 	bic	r4, r4, #2		@ clear frequency change bit
-	stmia	r0, {r4 - r10}		@ store cp regs
-	ldmia	sp!, {r4 - r10, pc}
+	stmia	r0, {r4 - r9}		@ store cp regs
+	ldmia	sp!, {r4 - r9, pc}
 ENDPROC(cpu_xsc3_do_suspend)
 
 ENTRY(cpu_xsc3_do_resume)
-	ldmia	r0, {r4 - r10}		@ load cp regs
+	ldmia	r0, {r4 - r9}		@ load cp regs
 	mov	ip, #0
 	mcr	p15, 0, ip, c7, c7, 0	@ invalidate I & D caches, BTB
 	mcr	p15, 0, ip, c7, c10, 4	@ drain write (&fill) buffer
@@ -433,9 +432,10 @@ ENTRY(cpu_xsc3_do_resume)
 	mcr	p15, 0, r5, c15, c1, 0	@ CP access reg
 	mcr	p15, 0, r6, c13, c0, 0	@ PID
 	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
-	mov	r0, r10			@ control register
+	orr	r1, r1, #0x18		@ cache the page table in L2
+	mcr	p15, 0, r1, c2, c0, 0	@ translation table base addr
+	mcr	p15, 0, r8, c1, c0, 1	@ auxiliary control reg
+	mov	r0, r9			@ control register
 	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 37dbada..3277904 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)
 	.align
 
 .globl	cpu_xscale_suspend_size
-.equ	cpu_xscale_suspend_size, 4 * 7
+.equ	cpu_xscale_suspend_size, 4 * 6
 #ifdef CONFIG_PM_SLEEP
 ENTRY(cpu_xscale_do_suspend)
-	stmfd	sp!, {r4 - r10, lr}
+	stmfd	sp!, {r4 - r9, lr}
 	mrc	p14, 0, r4, c6, c0, 0	@ clock configuration, for turbo mode
 	mrc	p15, 0, r5, c15, c1, 0	@ CP access reg
 	mrc	p15, 0, r6, c13, c0, 0	@ PID
 	mrc	p15, 0, r7, c3, c0, 0	@ domain ID
-	mrc	p15, 0, r8, c2, c0, 0	@ translation table base addr
-	mrc	p15, 0, r9, c1, c1, 0	@ auxiliary control reg
-	mrc	p15, 0, r10, c1, c0, 0	@ control reg
+	mrc	p15, 0, r8, c1, c1, 0	@ auxiliary control reg
+	mrc	p15, 0, r9, c1, c0, 0	@ control reg
 	bic	r4, r4, #2		@ clear frequency change bit
-	stmia	r0, {r4 - r10}		@ store cp regs
-	ldmfd	sp!, {r4 - r10, pc}
+	stmia	r0, {r4 - r9}		@ store cp regs
+	ldmfd	sp!, {r4 - r9, pc}
 ENDPROC(cpu_xscale_do_suspend)
 
 ENTRY(cpu_xscale_do_resume)
-	ldmia	r0, {r4 - r10}		@ load cp regs
+	ldmia	r0, {r4 - r9}		@ load cp regs
 	mov	ip, #0
 	mcr	p15, 0, ip, c8, c7, 0	@ invalidate I & D TLBs
 	mcr	p15, 0, ip, c7, c7, 0	@ invalidate I & D caches, BTB
@@ -545,9 +544,9 @@ ENTRY(cpu_xscale_do_resume)
 	mcr	p15, 0, r5, c15, c1, 0	@ CP access reg
 	mcr	p15, 0, r6, c13, c0, 0	@ PID
 	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, c1, 0	@ auxiliary control reg
-	mov	r0, r10			@ control register
+	mcr	p15, 0, r1, c2, c0, 0	@ translation table base addr
+	mcr	p15, 0, r8, c1, c1, 0	@ auxiliary control reg
+	mov	r0, r9			@ control register
 	b	cpu_resume_mmu
 ENDPROC(cpu_xscale_do_resume)
 #endif
-- 
1.7.4.4


^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [PATCH 07/11] ARM: pm: only use preallocated page table during resume
@ 2011-09-01 12:50   ` Russell King - ARM Linux
  0 siblings, 0 replies; 56+ messages in thread
From: Russell King - ARM Linux @ 2011-09-01 12:50 UTC (permalink / raw)
  To: linux-arm-kernel

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.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/kernel/sleep.S   |   19 +++++++++----------
 arch/arm/kernel/suspend.c |   14 ++++++++------
 arch/arm/mm/proc-arm920.S |   17 ++++++++---------
 arch/arm/mm/proc-arm926.S |   17 ++++++++---------
 arch/arm/mm/proc-sa1100.S |   21 ++++++++++-----------
 arch/arm/mm/proc-v6.S     |   31 ++++++++++++++++---------------
 arch/arm/mm/proc-v7.S     |   33 +++++++++++++++++----------------
 arch/arm/mm/proc-xsc3.S   |   22 +++++++++++-----------
 arch/arm/mm/proc-xscale.S |   21 ++++++++++-----------
 9 files changed, 97 insertions(+), 98 deletions(-)

diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S
index 8cf13de..25d42df 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 4d9ac3d..7606122 100644
--- a/arch/arm/kernel/suspend.c
+++ b/arch/arm/kernel/suspend.c
@@ -24,13 +24,15 @@ 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);
+	ret = __cpu_suspend(virt_to_phys(suspend_pgd),
+			    PHYS_OFFSET - PAGE_OFFSET, arg, fn);
+	if (ret == 0)
+		cpu_switch_mm(mm->pgd, mm);
 
 	return ret;
 }
diff --git a/arch/arm/mm/proc-arm920.S b/arch/arm/mm/proc-arm920.S
index 035d57b..88fb3d9 100644
--- a/arch/arm/mm/proc-arm920.S
+++ b/arch/arm/mm/proc-arm920.S
@@ -379,27 +379,26 @@ ENTRY(cpu_arm920_set_pte_ext)
 
 /* Suspend/resume support: taken from arch/arm/plat-s3c24xx/sleep.S */
 .globl	cpu_arm920_suspend_size
-.equ	cpu_arm920_suspend_size, 4 * 4
+.equ	cpu_arm920_suspend_size, 4 * 3
 #ifdef CONFIG_PM_SLEEP
 ENTRY(cpu_arm920_do_suspend)
-	stmfd	sp!, {r4 - r7, lr}
+	stmfd	sp!, {r4 - r6, lr}
 	mrc	p15, 0, r4, c13, c0, 0	@ PID
 	mrc	p15, 0, r5, c3, c0, 0	@ Domain ID
-	mrc	p15, 0, r6, c2, c0, 0	@ TTB address
-	mrc	p15, 0, r7, c1, c0, 0	@ Control register
-	stmia	r0, {r4 - r7}
-	ldmfd	sp!, {r4 - r7, pc}
+	mrc	p15, 0, r6, c1, c0, 0	@ Control register
+	stmia	r0, {r4 - r6}
+	ldmfd	sp!, {r4 - r6, pc}
 ENDPROC(cpu_arm920_do_suspend)
 
 ENTRY(cpu_arm920_do_resume)
 	mov	ip, #0
 	mcr	p15, 0, ip, c8, c7, 0	@ invalidate I+D TLBs
 	mcr	p15, 0, ip, c7, c7, 0	@ invalidate I+D caches
-	ldmia	r0, {r4 - r7}
+	ldmia	r0, {r4 - r6}
 	mcr	p15, 0, r4, c13, c0, 0	@ PID
 	mcr	p15, 0, r5, c3, c0, 0	@ Domain ID
-	mcr	p15, 0, r6, c2, c0, 0	@ TTB address
-	mov	r0, r7			@ control register
+	mcr	p15, 0, r1, c2, c0, 0	@ TTB address
+	mov	r0, r6			@ control register
 	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 48add84..9f8fd91 100644
--- a/arch/arm/mm/proc-arm926.S
+++ b/arch/arm/mm/proc-arm926.S
@@ -394,27 +394,26 @@ ENTRY(cpu_arm926_set_pte_ext)
 
 /* Suspend/resume support: taken from arch/arm/plat-s3c24xx/sleep.S */
 .globl	cpu_arm926_suspend_size
-.equ	cpu_arm926_suspend_size, 4 * 4
+.equ	cpu_arm926_suspend_size, 4 * 3
 #ifdef CONFIG_PM_SLEEP
 ENTRY(cpu_arm926_do_suspend)
-	stmfd	sp!, {r4 - r7, lr}
+	stmfd	sp!, {r4 - r6, lr}
 	mrc	p15, 0, r4, c13, c0, 0	@ PID
 	mrc	p15, 0, r5, c3, c0, 0	@ Domain ID
-	mrc	p15, 0, r6, c2, c0, 0	@ TTB address
-	mrc	p15, 0, r7, c1, c0, 0	@ Control register
-	stmia	r0, {r4 - r7}
-	ldmfd	sp!, {r4 - r7, pc}
+	mrc	p15, 0, r6, c1, c0, 0	@ Control register
+	stmia	r0, {r4 - r6}
+	ldmfd	sp!, {r4 - r6, pc}
 ENDPROC(cpu_arm926_do_suspend)
 
 ENTRY(cpu_arm926_do_resume)
 	mov	ip, #0
 	mcr	p15, 0, ip, c8, c7, 0	@ invalidate I+D TLBs
 	mcr	p15, 0, ip, c7, c7, 0	@ invalidate I+D caches
-	ldmia	r0, {r4 - r7}
+	ldmia	r0, {r4 - r6}
 	mcr	p15, 0, r4, c13, c0, 0	@ PID
 	mcr	p15, 0, r5, c3, c0, 0	@ Domain ID
-	mcr	p15, 0, r6, c2, c0, 0	@ TTB address
-	mov	r0, r7			@ control register
+	mcr	p15, 0, r1, c2, c0, 0	@ TTB address
+	mov	r0, r6			@ control register
 	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 52f73fb..7d91545 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)
 	mov	pc, lr
 
 .globl	cpu_sa1100_suspend_size
-.equ	cpu_sa1100_suspend_size, 4*4
+.equ	cpu_sa1100_suspend_size, 4 * 3
 #ifdef CONFIG_PM_SLEEP
 ENTRY(cpu_sa1100_do_suspend)
-	stmfd	sp!, {r4 - r7, lr}
+	stmfd	sp!, {r4 - r6, lr}
 	mrc	p15, 0, r4, c3, c0, 0		@ domain ID
-	mrc	p15, 0, r5, c2, c0, 0		@ translation table base addr
-	mrc	p15, 0, r6, c13, c0, 0		@ PID
-	mrc	p15, 0, r7, c1, c0, 0		@ control reg
-	stmia	r0, {r4 - r7}			@ store cp regs
-	ldmfd	sp!, {r4 - r7, pc}
+	mrc	p15, 0, r5, c13, c0, 0		@ PID
+	mrc	p15, 0, r6, c1, c0, 0		@ control reg
+	stmia	r0, {r4 - r6}			@ store cp regs
+	ldmfd	sp!, {r4 - r6, pc}
 ENDPROC(cpu_sa1100_do_suspend)
 
 ENTRY(cpu_sa1100_do_resume)
-	ldmia	r0, {r4 - r7}			@ load cp regs
+	ldmia	r0, {r4 - r6}			@ load cp regs
 	mov	ip, #0
 	mcr	p15, 0, ip, c8, c7, 0		@ flush I+D TLBs
 	mcr	p15, 0, ip, c7, c7, 0		@ flush I&D cache
@@ -189,9 +188,9 @@ ENTRY(cpu_sa1100_do_resume)
 	mcr	p15, 0, ip, c9, c0, 5		@ allow user space to use RB
 
 	mcr	p15, 0, r4, c3, c0, 0		@ domain ID
-	mcr	p15, 0, r5, c2, c0, 0		@ translation table base addr
-	mcr	p15, 0, r6, c13, c0, 0		@ PID
-	mov	r0, r7				@ control register
+	mcr	p15, 0, r1, c2, c0, 0		@ translation table base addr
+	mcr	p15, 0, r5, c13, c0, 0		@ PID
+	mov	r0, r6				@ control register
 	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 414e369..2e27b46 100644
--- a/arch/arm/mm/proc-v6.S
+++ b/arch/arm/mm/proc-v6.S
@@ -128,20 +128,19 @@ ENTRY(cpu_v6_set_pte_ext)
 
 /* Suspend/resume support: taken from arch/arm/mach-s3c64xx/sleep.S */
 .globl	cpu_v6_suspend_size
-.equ	cpu_v6_suspend_size, 4 * 8
+.equ	cpu_v6_suspend_size, 4 * 7
 #ifdef CONFIG_PM_SLEEP
 ENTRY(cpu_v6_do_suspend)
-	stmfd	sp!, {r4 - r11, lr}
+	stmfd	sp!, {r4 - r10, lr}
 	mrc	p15, 0, r4, c13, c0, 0	@ FCSE/PID
 	mrc	p15, 0, r5, c13, c0, 1	@ Context ID
 	mrc	p15, 0, r6, c3, c0, 0	@ Domain ID
-	mrc	p15, 0, r7, c2, c0, 0	@ Translation table base 0
-	mrc	p15, 0, r8, c2, c0, 1	@ Translation table base 1
-	mrc	p15, 0, r9, c1, c0, 1	@ auxiliary control register
-	mrc	p15, 0, r10, c1, c0, 2	@ co-processor access control
-	mrc	p15, 0, r11, c1, c0, 0	@ control register
-	stmia	r0, {r4 - r11}
-	ldmfd	sp!, {r4- r11, pc}
+	mrc	p15, 0, r7, c2, c0, 1	@ Translation table base 1
+	mrc	p15, 0, r8, c1, c0, 1	@ auxiliary control register
+	mrc	p15, 0, r9, c1, c0, 2	@ co-processor access control
+	mrc	p15, 0, r10, c1, c0, 0	@ control register
+	stmia	r0, {r4 - r10}
+	ldmfd	sp!, {r4- r10, pc}
 ENDPROC(cpu_v6_do_suspend)
 
 ENTRY(cpu_v6_do_resume)
@@ -150,17 +149,19 @@ ENTRY(cpu_v6_do_resume)
 	mcr	p15, 0, ip, c7, c5, 0	@ invalidate I cache
 	mcr	p15, 0, ip, c7, c15, 0	@ clean+invalidate cache
 	mcr	p15, 0, ip, c7, c10, 4	@ drain write buffer
-	ldmia	r0, {r4 - r11}
+	ldmia	r0, {r4 - r10}
 	mcr	p15, 0, r4, c13, c0, 0	@ FCSE/PID
 	mcr	p15, 0, r5, c13, c0, 1	@ Context ID
 	mcr	p15, 0, r6, c3, c0, 0	@ Domain ID
-	mcr	p15, 0, r7, c2, c0, 0	@ Translation table base 0
-	mcr	p15, 0, r8, c2, c0, 1	@ Translation table base 1
-	mcr	p15, 0, r9, c1, c0, 1	@ auxiliary control register
-	mcr	p15, 0, r10, c1, c0, 2	@ co-processor access control
+	ALT_SMP(orr	r1, r1, #TTB_FLAGS_SMP)
+	ALT_UP(orr	r1, r1, #TTB_FLAGS_UP)
+	mcr	p15, 0, r1, c2, c0, 0	@ Translation table base 0
+	mcr	p15, 0, r7, c2, c0, 1	@ Translation table base 1
+	mcr	p15, 0, r8, c1, c0, 1	@ auxiliary control register
+	mcr	p15, 0, r9, c1, c0, 2	@ co-processor access control
 	mcr	p15, 0, ip, c2, c0, 2	@ TTB control register
 	mcr	p15, 0, ip, c7, c5, 4	@ ISB
-	mov	r0, r11			@ control register
+	mov	r0, r10			@ control register
 	b	cpu_resume_mmu
 ENDPROC(cpu_v6_do_resume)
 #endif
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index 21d6910..b56004f 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -217,22 +217,21 @@ ENDPROC(cpu_v7_set_pte_ext)
 
 /* Suspend/resume support: derived from arch/arm/mach-s5pv210/sleep.S */
 .globl	cpu_v7_suspend_size
-.equ	cpu_v7_suspend_size, 4 * 9
+.equ	cpu_v7_suspend_size, 4 * 8
 #ifdef CONFIG_PM_SLEEP
 ENTRY(cpu_v7_do_suspend)
-	stmfd	sp!, {r4 - r11, lr}
+	stmfd	sp!, {r4 - r10, lr}
 	mrc	p15, 0, r4, c13, c0, 0	@ FCSE/PID
 	mrc	p15, 0, r5, c13, c0, 1	@ Context ID
 	mrc	p15, 0, r6, c13, c0, 3	@ User r/o thread ID
 	stmia	r0!, {r4 - r6}
 	mrc	p15, 0, r6, c3, c0, 0	@ Domain ID
-	mrc	p15, 0, r7, c2, c0, 0	@ TTB 0
-	mrc	p15, 0, r8, c2, c0, 1	@ TTB 1
-	mrc	p15, 0, r9, c1, c0, 0	@ Control register
-	mrc	p15, 0, r10, c1, c0, 1	@ Auxiliary control register
-	mrc	p15, 0, r11, c1, c0, 2	@ Co-processor access control
-	stmia	r0, {r6 - r11}
-	ldmfd	sp!, {r4 - r11, pc}
+	mrc	p15, 0, r7, c2, c0, 1	@ TTB 1
+	mrc	p15, 0, r8, c1, c0, 0	@ Control register
+	mrc	p15, 0, r9, c1, c0, 1	@ Auxiliary control register
+	mrc	p15, 0, r10, c1, c0, 2	@ Co-processor access control
+	stmia	r0, {r6 - r10}
+	ldmfd	sp!, {r4 - r10, pc}
 ENDPROC(cpu_v7_do_suspend)
 
 ENTRY(cpu_v7_do_resume)
@@ -243,22 +242,24 @@ ENTRY(cpu_v7_do_resume)
 	mcr	p15, 0, r4, c13, c0, 0	@ FCSE/PID
 	mcr	p15, 0, r5, c13, c0, 1	@ Context ID
 	mcr	p15, 0, r6, c13, c0, 3	@ User r/o thread ID
-	ldmia	r0, {r6 - r11}
+	ldmia	r0, {r6 - r10}
 	mcr	p15, 0, r6, c3, c0, 0	@ Domain ID
-	mcr	p15, 0, r7, c2, c0, 0	@ TTB 0
-	mcr	p15, 0, r8, c2, c0, 1	@ TTB 1
+	ALT_SMP(orr	r1, r1, #TTB_FLAGS_SMP)
+	ALT_UP(orr	r1, r1, #TTB_FLAGS_UP)
+	mcr	p15, 0, r1, c2, c0, 0	@ TTB 0
+	mcr	p15, 0, r7, c2, c0, 1	@ TTB 1
 	mcr	p15, 0, ip, c2, c0, 2	@ TTB control register
 	mrc	p15, 0, r4, c1, c0, 1	@ Read Auxiliary control register
-	teq	r4, r10			@ Is it already set?
-	mcrne	p15, 0, r10, c1, c0, 1	@ No, so write it
-	mcr	p15, 0, r11, c1, c0, 2	@ Co-processor access control
+	teq	r4, r9			@ Is it already set?
+	mcrne	p15, 0, r9, c1, c0, 1	@ No, so write it
+	mcr	p15, 0, r10, c1, c0, 2	@ Co-processor access control
 	ldr	r4, =PRRR		@ PRRR
 	ldr	r5, =NMRR		@ NMRR
 	mcr	p15, 0, r4, c10, c2, 0	@ write PRRR
 	mcr	p15, 0, r5, c10, c2, 1	@ write NMRR
 	isb
 	dsb
-	mov	r0, r9			@ control register
+	mov	r0, r8			@ control register
 	b	cpu_resume_mmu
 ENDPROC(cpu_v7_do_resume)
 #endif
diff --git a/arch/arm/mm/proc-xsc3.S b/arch/arm/mm/proc-xsc3.S
index efd4949..abf0507 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)
 	.align
 
 .globl	cpu_xsc3_suspend_size
-.equ	cpu_xsc3_suspend_size, 4 * 7
+.equ	cpu_xsc3_suspend_size, 4 * 6
 #ifdef CONFIG_PM_SLEEP
 ENTRY(cpu_xsc3_do_suspend)
-	stmfd	sp!, {r4 - r10, lr}
+	stmfd	sp!, {r4 - r9, lr}
 	mrc	p14, 0, r4, c6, c0, 0	@ clock configuration, for turbo mode
 	mrc	p15, 0, r5, c15, c1, 0	@ CP access reg
 	mrc	p15, 0, r6, c13, c0, 0	@ PID
 	mrc 	p15, 0, r7, c3, c0, 0	@ domain ID
-	mrc 	p15, 0, r8, c2, c0, 0	@ translation table base addr
-	mrc	p15, 0, r9, c1, c0, 1	@ auxiliary control reg
-	mrc 	p15, 0, r10, c1, c0, 0	@ control reg
+	mrc	p15, 0, r8, c1, c0, 1	@ auxiliary control reg
+	mrc 	p15, 0, r9, c1, c0, 0	@ control reg
 	bic	r4, r4, #2		@ clear frequency change bit
-	stmia	r0, {r4 - r10}		@ store cp regs
-	ldmia	sp!, {r4 - r10, pc}
+	stmia	r0, {r4 - r9}		@ store cp regs
+	ldmia	sp!, {r4 - r9, pc}
 ENDPROC(cpu_xsc3_do_suspend)
 
 ENTRY(cpu_xsc3_do_resume)
-	ldmia	r0, {r4 - r10}		@ load cp regs
+	ldmia	r0, {r4 - r9}		@ load cp regs
 	mov	ip, #0
 	mcr	p15, 0, ip, c7, c7, 0	@ invalidate I & D caches, BTB
 	mcr	p15, 0, ip, c7, c10, 4	@ drain write (&fill) buffer
@@ -433,9 +432,10 @@ ENTRY(cpu_xsc3_do_resume)
 	mcr	p15, 0, r5, c15, c1, 0	@ CP access reg
 	mcr	p15, 0, r6, c13, c0, 0	@ PID
 	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
-	mov	r0, r10			@ control register
+	orr	r1, r1, #0x18		@ cache the page table in L2
+	mcr	p15, 0, r1, c2, c0, 0	@ translation table base addr
+	mcr	p15, 0, r8, c1, c0, 1	@ auxiliary control reg
+	mov	r0, r9			@ control register
 	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 37dbada..3277904 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)
 	.align
 
 .globl	cpu_xscale_suspend_size
-.equ	cpu_xscale_suspend_size, 4 * 7
+.equ	cpu_xscale_suspend_size, 4 * 6
 #ifdef CONFIG_PM_SLEEP
 ENTRY(cpu_xscale_do_suspend)
-	stmfd	sp!, {r4 - r10, lr}
+	stmfd	sp!, {r4 - r9, lr}
 	mrc	p14, 0, r4, c6, c0, 0	@ clock configuration, for turbo mode
 	mrc	p15, 0, r5, c15, c1, 0	@ CP access reg
 	mrc	p15, 0, r6, c13, c0, 0	@ PID
 	mrc	p15, 0, r7, c3, c0, 0	@ domain ID
-	mrc	p15, 0, r8, c2, c0, 0	@ translation table base addr
-	mrc	p15, 0, r9, c1, c1, 0	@ auxiliary control reg
-	mrc	p15, 0, r10, c1, c0, 0	@ control reg
+	mrc	p15, 0, r8, c1, c1, 0	@ auxiliary control reg
+	mrc	p15, 0, r9, c1, c0, 0	@ control reg
 	bic	r4, r4, #2		@ clear frequency change bit
-	stmia	r0, {r4 - r10}		@ store cp regs
-	ldmfd	sp!, {r4 - r10, pc}
+	stmia	r0, {r4 - r9}		@ store cp regs
+	ldmfd	sp!, {r4 - r9, pc}
 ENDPROC(cpu_xscale_do_suspend)
 
 ENTRY(cpu_xscale_do_resume)
-	ldmia	r0, {r4 - r10}		@ load cp regs
+	ldmia	r0, {r4 - r9}		@ load cp regs
 	mov	ip, #0
 	mcr	p15, 0, ip, c8, c7, 0	@ invalidate I & D TLBs
 	mcr	p15, 0, ip, c7, c7, 0	@ invalidate I & D caches, BTB
@@ -545,9 +544,9 @@ ENTRY(cpu_xscale_do_resume)
 	mcr	p15, 0, r5, c15, c1, 0	@ CP access reg
 	mcr	p15, 0, r6, c13, c0, 0	@ PID
 	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, c1, 0	@ auxiliary control reg
-	mov	r0, r10			@ control register
+	mcr	p15, 0, r1, c2, c0, 0	@ translation table base addr
+	mcr	p15, 0, r8, c1, c1, 0	@ auxiliary control reg
+	mov	r0, r9			@ control register
 	b	cpu_resume_mmu
 ENDPROC(cpu_xscale_do_resume)
 #endif
-- 
1.7.4.4

^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [PATCH 08/11] ARM: pm: no need to save/restore context ID register
  2011-09-01 12:47 ` Russell King - ARM Linux
@ 2011-09-01 12:50   ` Russell King - ARM Linux
  -1 siblings, 0 replies; 56+ messages in thread
From: Russell King - ARM Linux @ 2011-09-01 12:50 UTC (permalink / raw)
  To: Santosh Shilimkar; +Cc: linux-arm-kernel, linux-omap

There is no need to save and restore the context ID register on ARMv6
and ARMv7 with a temporary page table as we write the context ID
register when we switch back to the real page tables for the thread.

Moreover, the temporary page tables do not contain any non-global
mappings, so the context ID value should not be used.  To be safe,
initialize the register to a reserved context ID value.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/mm/proc-v6.S |   33 ++++++++++++++++-----------------
 arch/arm/mm/proc-v7.S |   13 ++++++-------
 2 files changed, 22 insertions(+), 24 deletions(-)

diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S
index 2e27b46..a92c3c3 100644
--- a/arch/arm/mm/proc-v6.S
+++ b/arch/arm/mm/proc-v6.S
@@ -128,19 +128,18 @@ ENTRY(cpu_v6_set_pte_ext)
 
 /* Suspend/resume support: taken from arch/arm/mach-s3c64xx/sleep.S */
 .globl	cpu_v6_suspend_size
-.equ	cpu_v6_suspend_size, 4 * 7
+.equ	cpu_v6_suspend_size, 4 * 6
 #ifdef CONFIG_PM_SLEEP
 ENTRY(cpu_v6_do_suspend)
-	stmfd	sp!, {r4 - r10, lr}
+	stmfd	sp!, {r4 - r9, lr}
 	mrc	p15, 0, r4, c13, c0, 0	@ FCSE/PID
-	mrc	p15, 0, r5, c13, c0, 1	@ Context ID
-	mrc	p15, 0, r6, c3, c0, 0	@ Domain ID
-	mrc	p15, 0, r7, c2, c0, 1	@ Translation table base 1
-	mrc	p15, 0, r8, c1, c0, 1	@ auxiliary control register
-	mrc	p15, 0, r9, c1, c0, 2	@ co-processor access control
-	mrc	p15, 0, r10, c1, c0, 0	@ control register
-	stmia	r0, {r4 - r10}
-	ldmfd	sp!, {r4- r10, pc}
+	mrc	p15, 0, r5, c3, c0, 0	@ Domain ID
+	mrc	p15, 0, r6, c2, c0, 1	@ Translation table base 1
+	mrc	p15, 0, r7, c1, c0, 1	@ auxiliary control register
+	mrc	p15, 0, r8, c1, c0, 2	@ co-processor access control
+	mrc	p15, 0, r9, c1, c0, 0	@ control register
+	stmia	r0, {r4 - r9}
+	ldmfd	sp!, {r4- r9, pc}
 ENDPROC(cpu_v6_do_suspend)
 
 ENTRY(cpu_v6_do_resume)
@@ -149,19 +148,19 @@ ENTRY(cpu_v6_do_resume)
 	mcr	p15, 0, ip, c7, c5, 0	@ invalidate I cache
 	mcr	p15, 0, ip, c7, c15, 0	@ clean+invalidate cache
 	mcr	p15, 0, ip, c7, c10, 4	@ drain write buffer
-	ldmia	r0, {r4 - r10}
+	mcr	p15, 0, ip, c13, 0, 1	@ set reserved context ID
+	ldmia	r0, {r4 - r9}
 	mcr	p15, 0, r4, c13, c0, 0	@ FCSE/PID
-	mcr	p15, 0, r5, c13, c0, 1	@ Context ID
-	mcr	p15, 0, r6, c3, c0, 0	@ Domain ID
+	mcr	p15, 0, r5, c3, c0, 0	@ Domain ID
 	ALT_SMP(orr	r1, r1, #TTB_FLAGS_SMP)
 	ALT_UP(orr	r1, r1, #TTB_FLAGS_UP)
 	mcr	p15, 0, r1, c2, c0, 0	@ Translation table base 0
-	mcr	p15, 0, r7, c2, c0, 1	@ Translation table base 1
-	mcr	p15, 0, r8, c1, c0, 1	@ auxiliary control register
-	mcr	p15, 0, r9, c1, c0, 2	@ co-processor access control
+	mcr	p15, 0, r6, c2, c0, 1	@ Translation table base 1
+	mcr	p15, 0, r7, c1, c0, 1	@ auxiliary control register
+	mcr	p15, 0, r8, c1, c0, 2	@ co-processor access control
 	mcr	p15, 0, ip, c2, c0, 2	@ TTB control register
 	mcr	p15, 0, ip, c7, c5, 4	@ ISB
-	mov	r0, r10			@ control register
+	mov	r0, r9			@ control register
 	b	cpu_resume_mmu
 ENDPROC(cpu_v6_do_resume)
 #endif
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index b56004f..6af366c 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -217,14 +217,13 @@ ENDPROC(cpu_v7_set_pte_ext)
 
 /* Suspend/resume support: derived from arch/arm/mach-s5pv210/sleep.S */
 .globl	cpu_v7_suspend_size
-.equ	cpu_v7_suspend_size, 4 * 8
+.equ	cpu_v7_suspend_size, 4 * 7
 #ifdef CONFIG_PM_SLEEP
 ENTRY(cpu_v7_do_suspend)
 	stmfd	sp!, {r4 - r10, lr}
 	mrc	p15, 0, r4, c13, c0, 0	@ FCSE/PID
-	mrc	p15, 0, r5, c13, c0, 1	@ Context ID
-	mrc	p15, 0, r6, c13, c0, 3	@ User r/o thread ID
-	stmia	r0!, {r4 - r6}
+	mrc	p15, 0, r5, c13, c0, 3	@ User r/o thread ID
+	stmia	r0!, {r4 - r5}
 	mrc	p15, 0, r6, c3, c0, 0	@ Domain ID
 	mrc	p15, 0, r7, c2, c0, 1	@ TTB 1
 	mrc	p15, 0, r8, c1, c0, 0	@ Control register
@@ -238,10 +237,10 @@ ENTRY(cpu_v7_do_resume)
 	mov	ip, #0
 	mcr	p15, 0, ip, c8, c7, 0	@ invalidate TLBs
 	mcr	p15, 0, ip, c7, c5, 0	@ invalidate I cache
-	ldmia	r0!, {r4 - r6}
+	mcr	p15, 0, ip, c13, c0, 1	@ set reserved context ID
+	ldmia	r0!, {r4 - r5}
 	mcr	p15, 0, r4, c13, c0, 0	@ FCSE/PID
-	mcr	p15, 0, r5, c13, c0, 1	@ Context ID
-	mcr	p15, 0, r6, c13, c0, 3	@ User r/o thread ID
+	mcr	p15, 0, r5, c13, c0, 3	@ User r/o thread ID
 	ldmia	r0, {r6 - r10}
 	mcr	p15, 0, r6, c3, c0, 0	@ Domain ID
 	ALT_SMP(orr	r1, r1, #TTB_FLAGS_SMP)
-- 
1.7.4.4


^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [PATCH 08/11] ARM: pm: no need to save/restore context ID register
@ 2011-09-01 12:50   ` Russell King - ARM Linux
  0 siblings, 0 replies; 56+ messages in thread
From: Russell King - ARM Linux @ 2011-09-01 12:50 UTC (permalink / raw)
  To: linux-arm-kernel

There is no need to save and restore the context ID register on ARMv6
and ARMv7 with a temporary page table as we write the context ID
register when we switch back to the real page tables for the thread.

Moreover, the temporary page tables do not contain any non-global
mappings, so the context ID value should not be used.  To be safe,
initialize the register to a reserved context ID value.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/mm/proc-v6.S |   33 ++++++++++++++++-----------------
 arch/arm/mm/proc-v7.S |   13 ++++++-------
 2 files changed, 22 insertions(+), 24 deletions(-)

diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S
index 2e27b46..a92c3c3 100644
--- a/arch/arm/mm/proc-v6.S
+++ b/arch/arm/mm/proc-v6.S
@@ -128,19 +128,18 @@ ENTRY(cpu_v6_set_pte_ext)
 
 /* Suspend/resume support: taken from arch/arm/mach-s3c64xx/sleep.S */
 .globl	cpu_v6_suspend_size
-.equ	cpu_v6_suspend_size, 4 * 7
+.equ	cpu_v6_suspend_size, 4 * 6
 #ifdef CONFIG_PM_SLEEP
 ENTRY(cpu_v6_do_suspend)
-	stmfd	sp!, {r4 - r10, lr}
+	stmfd	sp!, {r4 - r9, lr}
 	mrc	p15, 0, r4, c13, c0, 0	@ FCSE/PID
-	mrc	p15, 0, r5, c13, c0, 1	@ Context ID
-	mrc	p15, 0, r6, c3, c0, 0	@ Domain ID
-	mrc	p15, 0, r7, c2, c0, 1	@ Translation table base 1
-	mrc	p15, 0, r8, c1, c0, 1	@ auxiliary control register
-	mrc	p15, 0, r9, c1, c0, 2	@ co-processor access control
-	mrc	p15, 0, r10, c1, c0, 0	@ control register
-	stmia	r0, {r4 - r10}
-	ldmfd	sp!, {r4- r10, pc}
+	mrc	p15, 0, r5, c3, c0, 0	@ Domain ID
+	mrc	p15, 0, r6, c2, c0, 1	@ Translation table base 1
+	mrc	p15, 0, r7, c1, c0, 1	@ auxiliary control register
+	mrc	p15, 0, r8, c1, c0, 2	@ co-processor access control
+	mrc	p15, 0, r9, c1, c0, 0	@ control register
+	stmia	r0, {r4 - r9}
+	ldmfd	sp!, {r4- r9, pc}
 ENDPROC(cpu_v6_do_suspend)
 
 ENTRY(cpu_v6_do_resume)
@@ -149,19 +148,19 @@ ENTRY(cpu_v6_do_resume)
 	mcr	p15, 0, ip, c7, c5, 0	@ invalidate I cache
 	mcr	p15, 0, ip, c7, c15, 0	@ clean+invalidate cache
 	mcr	p15, 0, ip, c7, c10, 4	@ drain write buffer
-	ldmia	r0, {r4 - r10}
+	mcr	p15, 0, ip, c13, 0, 1	@ set reserved context ID
+	ldmia	r0, {r4 - r9}
 	mcr	p15, 0, r4, c13, c0, 0	@ FCSE/PID
-	mcr	p15, 0, r5, c13, c0, 1	@ Context ID
-	mcr	p15, 0, r6, c3, c0, 0	@ Domain ID
+	mcr	p15, 0, r5, c3, c0, 0	@ Domain ID
 	ALT_SMP(orr	r1, r1, #TTB_FLAGS_SMP)
 	ALT_UP(orr	r1, r1, #TTB_FLAGS_UP)
 	mcr	p15, 0, r1, c2, c0, 0	@ Translation table base 0
-	mcr	p15, 0, r7, c2, c0, 1	@ Translation table base 1
-	mcr	p15, 0, r8, c1, c0, 1	@ auxiliary control register
-	mcr	p15, 0, r9, c1, c0, 2	@ co-processor access control
+	mcr	p15, 0, r6, c2, c0, 1	@ Translation table base 1
+	mcr	p15, 0, r7, c1, c0, 1	@ auxiliary control register
+	mcr	p15, 0, r8, c1, c0, 2	@ co-processor access control
 	mcr	p15, 0, ip, c2, c0, 2	@ TTB control register
 	mcr	p15, 0, ip, c7, c5, 4	@ ISB
-	mov	r0, r10			@ control register
+	mov	r0, r9			@ control register
 	b	cpu_resume_mmu
 ENDPROC(cpu_v6_do_resume)
 #endif
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index b56004f..6af366c 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -217,14 +217,13 @@ ENDPROC(cpu_v7_set_pte_ext)
 
 /* Suspend/resume support: derived from arch/arm/mach-s5pv210/sleep.S */
 .globl	cpu_v7_suspend_size
-.equ	cpu_v7_suspend_size, 4 * 8
+.equ	cpu_v7_suspend_size, 4 * 7
 #ifdef CONFIG_PM_SLEEP
 ENTRY(cpu_v7_do_suspend)
 	stmfd	sp!, {r4 - r10, lr}
 	mrc	p15, 0, r4, c13, c0, 0	@ FCSE/PID
-	mrc	p15, 0, r5, c13, c0, 1	@ Context ID
-	mrc	p15, 0, r6, c13, c0, 3	@ User r/o thread ID
-	stmia	r0!, {r4 - r6}
+	mrc	p15, 0, r5, c13, c0, 3	@ User r/o thread ID
+	stmia	r0!, {r4 - r5}
 	mrc	p15, 0, r6, c3, c0, 0	@ Domain ID
 	mrc	p15, 0, r7, c2, c0, 1	@ TTB 1
 	mrc	p15, 0, r8, c1, c0, 0	@ Control register
@@ -238,10 +237,10 @@ ENTRY(cpu_v7_do_resume)
 	mov	ip, #0
 	mcr	p15, 0, ip, c8, c7, 0	@ invalidate TLBs
 	mcr	p15, 0, ip, c7, c5, 0	@ invalidate I cache
-	ldmia	r0!, {r4 - r6}
+	mcr	p15, 0, ip, c13, c0, 1	@ set reserved context ID
+	ldmia	r0!, {r4 - r5}
 	mcr	p15, 0, r4, c13, c0, 0	@ FCSE/PID
-	mcr	p15, 0, r5, c13, c0, 1	@ Context ID
-	mcr	p15, 0, r6, c13, c0, 3	@ User r/o thread ID
+	mcr	p15, 0, r5, c13, c0, 3	@ User r/o thread ID
 	ldmia	r0, {r6 - r10}
 	mcr	p15, 0, r6, c3, c0, 0	@ Domain ID
 	ALT_SMP(orr	r1, r1, #TTB_FLAGS_SMP)
-- 
1.7.4.4

^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [PATCH 09/11] ARM: pm: get rid of cpu_resume_turn_mmu_on
  2011-09-01 12:47 ` Russell King - ARM Linux
@ 2011-09-01 12:51   ` Russell King - ARM Linux
  -1 siblings, 0 replies; 56+ messages in thread
From: Russell King - ARM Linux @ 2011-09-01 12:51 UTC (permalink / raw)
  To: Santosh Shilimkar; +Cc: linux-arm-kernel, linux-omap

We don't require cpu_resume_turn_mmu_on as we can combine the ldr
instruction with the following code provided we ensure that
cpu_resume_mmu is aligned for older CPUs.  Note that we also align
to a 32-byte boundary to ensure that the code can't cross a section
boundary.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/kernel/sleep.S   |    8 ++------
 arch/arm/kernel/suspend.c |    4 ++--
 2 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S
index 25d42df..c9a43ca 100644
--- a/arch/arm/kernel/sleep.S
+++ b/arch/arm/kernel/sleep.S
@@ -72,19 +72,15 @@ ENDPROC(cpu_suspend_abort)
 /*
  * r0 = control register value
  */
+	.align	5
 ENTRY(cpu_resume_mmu)
 	ldr	r3, =cpu_resume_after_mmu
-	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
 	mov	pc, r3			@ jump to virtual address
-ENDPROC(cpu_resume_turn_mmu_on)
+ENDPROC(cpu_resume_mmu)
 cpu_resume_after_mmu:
 	bl	cpu_init		@ restore the und/abt/irq banked regs
 	mov	r0, #0			@ return zero on success
diff --git a/arch/arm/kernel/suspend.c b/arch/arm/kernel/suspend.c
index 7606122..115736a 100644
--- a/arch/arm/kernel/suspend.c
+++ b/arch/arm/kernel/suspend.c
@@ -9,7 +9,7 @@
 static pgd_t *suspend_pgd;
 
 extern int __cpu_suspend(int, long, unsigned long, int (*)(unsigned long));
-extern void cpu_resume_turn_mmu_on(void);
+extern void cpu_resume_mmu(void);
 
 /*
  * Hide the first two arguments to __cpu_suspend - these are an implementation
@@ -41,7 +41,7 @@ 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);
+		unsigned long addr = virt_to_phys(cpu_resume_mmu);
 		identity_mapping_add(suspend_pgd, addr, addr + SECTION_SIZE);
 	}
 	return suspend_pgd ? 0 : -ENOMEM;
-- 
1.7.4.4


^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [PATCH 09/11] ARM: pm: get rid of cpu_resume_turn_mmu_on
@ 2011-09-01 12:51   ` Russell King - ARM Linux
  0 siblings, 0 replies; 56+ messages in thread
From: Russell King - ARM Linux @ 2011-09-01 12:51 UTC (permalink / raw)
  To: linux-arm-kernel

We don't require cpu_resume_turn_mmu_on as we can combine the ldr
instruction with the following code provided we ensure that
cpu_resume_mmu is aligned for older CPUs.  Note that we also align
to a 32-byte boundary to ensure that the code can't cross a section
boundary.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/kernel/sleep.S   |    8 ++------
 arch/arm/kernel/suspend.c |    4 ++--
 2 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S
index 25d42df..c9a43ca 100644
--- a/arch/arm/kernel/sleep.S
+++ b/arch/arm/kernel/sleep.S
@@ -72,19 +72,15 @@ ENDPROC(cpu_suspend_abort)
 /*
  * r0 = control register value
  */
+	.align	5
 ENTRY(cpu_resume_mmu)
 	ldr	r3, =cpu_resume_after_mmu
-	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
 	mov	pc, r3			@ jump to virtual address
-ENDPROC(cpu_resume_turn_mmu_on)
+ENDPROC(cpu_resume_mmu)
 cpu_resume_after_mmu:
 	bl	cpu_init		@ restore the und/abt/irq banked regs
 	mov	r0, #0			@ return zero on success
diff --git a/arch/arm/kernel/suspend.c b/arch/arm/kernel/suspend.c
index 7606122..115736a 100644
--- a/arch/arm/kernel/suspend.c
+++ b/arch/arm/kernel/suspend.c
@@ -9,7 +9,7 @@
 static pgd_t *suspend_pgd;
 
 extern int __cpu_suspend(int, long, unsigned long, int (*)(unsigned long));
-extern void cpu_resume_turn_mmu_on(void);
+extern void cpu_resume_mmu(void);
 
 /*
  * Hide the first two arguments to __cpu_suspend - these are an implementation
@@ -41,7 +41,7 @@ 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);
+		unsigned long addr = virt_to_phys(cpu_resume_mmu);
 		identity_mapping_add(suspend_pgd, addr, addr + SECTION_SIZE);
 	}
 	return suspend_pgd ? 0 : -ENOMEM;
-- 
1.7.4.4

^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [PATCH 10/11] ARM: pm: convert some assembly to C
  2011-09-01 12:47 ` Russell King - ARM Linux
@ 2011-09-01 12:51   ` Russell King - ARM Linux
  -1 siblings, 0 replies; 56+ messages in thread
From: Russell King - ARM Linux @ 2011-09-01 12:51 UTC (permalink / raw)
  To: Santosh Shilimkar; +Cc: linux-arm-kernel, linux-omap

Convert some of the sleep.S guts to C code, which makes it easier to
use our macros and to add L2 cache handling.  We provide a helper
function, __cpu_suspend_save(), which deals with saving the common
state, setting up for resume, and flushing caches.

The remainder left as assembly code is the saving of the CPU general
purpose registers, and allocating space on the stack to save the CPU
specific registers and resume state.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/include/asm/proc-fns.h |    8 ++++++
 arch/arm/kernel/sleep.S         |   53 ++++++++++++--------------------------
 arch/arm/kernel/suspend.c       |   24 +++++++++++++++--
 3 files changed, 46 insertions(+), 39 deletions(-)

diff --git a/arch/arm/include/asm/proc-fns.h b/arch/arm/include/asm/proc-fns.h
index 633d1cb..9e92cb2 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);
 extern void cpu_do_switch_mm(unsigned long pgd_phys, struct mm_struct *mm);
 extern void cpu_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext);
 extern void cpu_reset(unsigned long addr) __attribute__((noreturn));
+
+/* These three are private to arch/arm/kernel/suspend.c */
+extern void cpu_do_suspend(void *);
+extern void cpu_do_resume(void *);
 #else
 #define cpu_proc_init			processor._proc_init
 #define cpu_proc_fin			processor._proc_fin
@@ -89,6 +93,10 @@ extern void cpu_reset(unsigned long addr) __attribute__((noreturn));
 #define cpu_dcache_clean_area		processor.dcache_clean_area
 #define cpu_set_pte_ext			processor.set_pte_ext
 #define cpu_do_switch_mm		processor.switch_mm
+
+/* These three are private to arch/arm/kernel/suspend.c */
+#define cpu_do_suspend			processor.do_suspend
+#define cpu_do_resume			processor.do_resume
 #endif
 
 extern void cpu_resume(void);
diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S
index c9a43ca..020e99c 100644
--- a/arch/arm/kernel/sleep.S
+++ b/arch/arm/kernel/sleep.S
@@ -8,54 +8,35 @@
 	.text
 
 /*
- * Save CPU state for a suspend
- *  r0 = phys addr of temporary page tables
- *  r1 = v:p offset
- *  r2 = suspend function arg0
- *  r3 = suspend function
+ * 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
  */
 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
-	ldr	ip, [r10, #CPU_DO_RESUME] @ virtual resume function
+	ldr	r4, [r10, #CPU_SLEEP_SIZE] @ size of CPU sleep state
 #else
-	ldr	r5, =cpu_suspend_size
-	ldr	ip, =cpu_do_resume
+	ldr	r4, =cpu_suspend_size
 #endif
-	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
+	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
 #ifdef CONFIG_SMP
 	ALT_SMP(mrc p15, 0, lr, c0, c0, 5)
 	ALT_UP(mov lr, #0)
 	and	lr, lr, #15
-	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
+	add	r3, r3, lr, lsl #2
 #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 115736a..c78a88f 100644
--- a/arch/arm/kernel/suspend.c
+++ b/arch/arm/kernel/suspend.c
@@ -8,10 +8,29 @@
 
 static pgd_t *suspend_pgd;
 
-extern int __cpu_suspend(int, long, unsigned long, int (*)(unsigned long));
+extern int __cpu_suspend(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.
  */
@@ -29,8 +48,7 @@ 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(virt_to_phys(suspend_pgd),
-			    PHYS_OFFSET - PAGE_OFFSET, arg, fn);
+	ret = __cpu_suspend(arg, fn);
 	if (ret == 0)
 		cpu_switch_mm(mm->pgd, mm);
 
-- 
1.7.4.4


^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [PATCH 10/11] ARM: pm: convert some assembly to C
@ 2011-09-01 12:51   ` Russell King - ARM Linux
  0 siblings, 0 replies; 56+ messages in thread
From: Russell King - ARM Linux @ 2011-09-01 12:51 UTC (permalink / raw)
  To: linux-arm-kernel

Convert some of the sleep.S guts to C code, which makes it easier to
use our macros and to add L2 cache handling.  We provide a helper
function, __cpu_suspend_save(), which deals with saving the common
state, setting up for resume, and flushing caches.

The remainder left as assembly code is the saving of the CPU general
purpose registers, and allocating space on the stack to save the CPU
specific registers and resume state.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/include/asm/proc-fns.h |    8 ++++++
 arch/arm/kernel/sleep.S         |   53 ++++++++++++--------------------------
 arch/arm/kernel/suspend.c       |   24 +++++++++++++++--
 3 files changed, 46 insertions(+), 39 deletions(-)

diff --git a/arch/arm/include/asm/proc-fns.h b/arch/arm/include/asm/proc-fns.h
index 633d1cb..9e92cb2 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);
 extern void cpu_do_switch_mm(unsigned long pgd_phys, struct mm_struct *mm);
 extern void cpu_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext);
 extern void cpu_reset(unsigned long addr) __attribute__((noreturn));
+
+/* These three are private to arch/arm/kernel/suspend.c */
+extern void cpu_do_suspend(void *);
+extern void cpu_do_resume(void *);
 #else
 #define cpu_proc_init			processor._proc_init
 #define cpu_proc_fin			processor._proc_fin
@@ -89,6 +93,10 @@ extern void cpu_reset(unsigned long addr) __attribute__((noreturn));
 #define cpu_dcache_clean_area		processor.dcache_clean_area
 #define cpu_set_pte_ext			processor.set_pte_ext
 #define cpu_do_switch_mm		processor.switch_mm
+
+/* These three are private to arch/arm/kernel/suspend.c */
+#define cpu_do_suspend			processor.do_suspend
+#define cpu_do_resume			processor.do_resume
 #endif
 
 extern void cpu_resume(void);
diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S
index c9a43ca..020e99c 100644
--- a/arch/arm/kernel/sleep.S
+++ b/arch/arm/kernel/sleep.S
@@ -8,54 +8,35 @@
 	.text
 
 /*
- * Save CPU state for a suspend
- *  r0 = phys addr of temporary page tables
- *  r1 = v:p offset
- *  r2 = suspend function arg0
- *  r3 = suspend function
+ * 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
  */
 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
-	ldr	ip, [r10, #CPU_DO_RESUME] @ virtual resume function
+	ldr	r4, [r10, #CPU_SLEEP_SIZE] @ size of CPU sleep state
 #else
-	ldr	r5, =cpu_suspend_size
-	ldr	ip, =cpu_do_resume
+	ldr	r4, =cpu_suspend_size
 #endif
-	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
+	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
 #ifdef CONFIG_SMP
 	ALT_SMP(mrc p15, 0, lr, c0, c0, 5)
 	ALT_UP(mov lr, #0)
 	and	lr, lr, #15
-	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
+	add	r3, r3, lr, lsl #2
 #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 115736a..c78a88f 100644
--- a/arch/arm/kernel/suspend.c
+++ b/arch/arm/kernel/suspend.c
@@ -8,10 +8,29 @@
 
 static pgd_t *suspend_pgd;
 
-extern int __cpu_suspend(int, long, unsigned long, int (*)(unsigned long));
+extern int __cpu_suspend(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.
  */
@@ -29,8 +48,7 @@ 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(virt_to_phys(suspend_pgd),
-			    PHYS_OFFSET - PAGE_OFFSET, arg, fn);
+	ret = __cpu_suspend(arg, fn);
 	if (ret == 0)
 		cpu_switch_mm(mm->pgd, mm);
 
-- 
1.7.4.4

^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [PATCH 11/11] ARM: pm: add L2 cache cleaning for suspend
  2011-09-01 12:47 ` Russell King - ARM Linux
@ 2011-09-01 12:51   ` Russell King - ARM Linux
  -1 siblings, 0 replies; 56+ messages in thread
From: Russell King - ARM Linux @ 2011-09-01 12:51 UTC (permalink / raw)
  To: Santosh Shilimkar; +Cc: linux-arm-kernel, linux-omap

We need to ensure that state is pushed out from the L2 cache when
suspending so that the resume paths can access their data before the
MMU and caches have been re-initialized.  Add the necessary calls to
__cpu_suspend_save().

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/kernel/suspend.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/arch/arm/kernel/suspend.c b/arch/arm/kernel/suspend.c
index c78a88f..4c95410 100644
--- a/arch/arm/kernel/suspend.c
+++ b/arch/arm/kernel/suspend.c
@@ -28,6 +28,9 @@ void __cpu_suspend_save(u32 *ptr, u32 ptrsz, u32 sp, u32 *save_ptr)
 	cpu_do_suspend(ptr);
 
 	flush_cache_all();
+	outer_clean_range(*save_ptr, *save_ptr + ptrsz);
+	outer_clean_range(virt_to_phys(save_ptr),
+			  virt_to_phys(save_ptr) + sizeof(*save_ptr));
 }
 
 /*
-- 
1.7.4.4


^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [PATCH 11/11] ARM: pm: add L2 cache cleaning for suspend
@ 2011-09-01 12:51   ` Russell King - ARM Linux
  0 siblings, 0 replies; 56+ messages in thread
From: Russell King - ARM Linux @ 2011-09-01 12:51 UTC (permalink / raw)
  To: linux-arm-kernel

We need to ensure that state is pushed out from the L2 cache when
suspending so that the resume paths can access their data before the
MMU and caches have been re-initialized.  Add the necessary calls to
__cpu_suspend_save().

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/kernel/suspend.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/arch/arm/kernel/suspend.c b/arch/arm/kernel/suspend.c
index c78a88f..4c95410 100644
--- a/arch/arm/kernel/suspend.c
+++ b/arch/arm/kernel/suspend.c
@@ -28,6 +28,9 @@ void __cpu_suspend_save(u32 *ptr, u32 ptrsz, u32 sp, u32 *save_ptr)
 	cpu_do_suspend(ptr);
 
 	flush_cache_all();
+	outer_clean_range(*save_ptr, *save_ptr + ptrsz);
+	outer_clean_range(virt_to_phys(save_ptr),
+			  virt_to_phys(save_ptr) + sizeof(*save_ptr));
 }
 
 /*
-- 
1.7.4.4

^ permalink raw reply related	[flat|nested] 56+ messages in thread

* Re: [PATCH 00/11] Add L2 cache cleaning to generic CPU suspend
  2011-09-01 12:47 ` Russell King - ARM Linux
@ 2011-09-01 15:33   ` Shawn Guo
  -1 siblings, 0 replies; 56+ messages in thread
From: Shawn Guo @ 2011-09-01 15:33 UTC (permalink / raw)
  To: Russell King - ARM Linux; +Cc: Santosh Shilimkar, linux-omap, linux-arm-kernel

Hi Russell,

On Thu, Sep 01, 2011 at 01:47:52PM +0100, Russell King - ARM Linux wrote:
> Some systems (such as OMAP) preserve the L2 cache across a suspend/
> resume cycle.  This means they do not perform L2 cache maintanence
> in their suspend finisher function.
> 
> However, the side effect is that the saved CPU state is not readable
> by the resume code because it is sitting in the L2 cache.
> 
> This patch series adds L2 cache cleaning to the generic CPU suspend/
> resume support code, making it possible to use this on systems with
> L2 cache enabled without having to clean/invalidate the entire L2
> cache.
> 
This is also the case on i.MX6Q, which L2 cache is retained during a
suspend/resume cycle.  Currently, I have to call into the following
before calling generic cpu_suspend() to clean/invalidate the entire
L2 cache.

	outer_flush_all();
	outer_disable();

But there is a wired thing on using generic cpu_resume().  I have to
invalidate L1 before calling into cpu_resume() like below.

ENTRY(imx6q_cpu_resume)
        bl      v7_invalidate_l1
        b       cpu_resume
ENDPROC(imx6q_cpu_resume)

ENTRY(imx6q_secondary_startup)
        bl      v7_invalidate_l1
        b       secondary_startup
ENDPROC(imx6q_secondary_startup)

The v7_invalidate_l1() is the function copied from mach-tegra/headsmp.S,
which has to be called before calling secondary_startup to boot
secondary cores (same situation between Tegra and i.MX6Q).

/*
 * Tegra specific entry point for secondary CPUs.
 *   The secondary kernel init calls v7_flush_dcache_all before it enables
 *   the L1; however, the L1 comes out of reset in an undefined state, so
 *   the clean + invalidate performed by v7_flush_dcache_all causes a bunch
 *   of cache lines with uninitialized data and uninitialized tags to get
 *   written out to memory, which does really unpleasant things to the main
 *   processor.  We fix this by performing an invalidate, rather than a
 *   clean + invalidate, before jumping into the kernel.
 */
ENTRY(v7_invalidate_l1)
        mov     r0, #0
        mcr     p15, 2, r0, c0, c0, 0
        mrc     p15, 1, r0, c0, c0, 0

        ldr     r1, =0x7fff
        and     r2, r1, r0, lsr #13

        ldr     r1, =0x3ff

        and     r3, r1, r0, lsr #3  @ NumWays - 1
        add     r2, r2, #1          @ NumSets

        and     r0, r0, #0x7
        add     r0, r0, #4          @ SetShift

        clz     r1, r3              @ WayShift
        add     r4, r3, #1          @ NumWays
1:      sub     r2, r2, #1          @ NumSets--
        mov     r3, r4              @ Temp = NumWays
2:      subs    r3, r3, #1          @ Temp--
        mov     r5, r3, lsl r1
        mov     r6, r2, lsl r0
        orr     r5, r5, r6          @ Reg = (Temp<<WayShift)|(NumSets<<SetShift)
        mcr     p15, 0, r5, c7, c6, 2
        bgt     2b
        cmp     r2, #0
        bgt     1b
        dsb
        isb
        mov     pc, lr
ENDPROC(v7_invalidate_l1)
 
Before applying this patch series, I have something like below actually
working.


	outer_flush_all();
	outer_disable();
	imx_set_cpu_jump(0, imx6q_cpu_resume);
	/* Zzz ... */
	cpu_suspend(0, imx6q_suspend_finish);

I expect with you patches applied, I can still have it work with simply
removing those two lines outer cache codes.  But unfortunately, I'm
running into Oops when resuming back.  And I also have Oops with
imx_set_cpu_jump(0, cpu_resume) which means skipping the
v7_invalidate_l1() and calling generic cpu_resume() only.

I know the key point of the whole thing is that we need to invalidate
L1 before either booting secondary cores or resuming the primary core
on i.MX6Q.  But I really need some help to understand why, and the
best solution to that.

-- 
Regards,
Shawn


^ permalink raw reply	[flat|nested] 56+ messages in thread

* [PATCH 00/11] Add L2 cache cleaning to generic CPU suspend
@ 2011-09-01 15:33   ` Shawn Guo
  0 siblings, 0 replies; 56+ messages in thread
From: Shawn Guo @ 2011-09-01 15:33 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Russell,

On Thu, Sep 01, 2011 at 01:47:52PM +0100, Russell King - ARM Linux wrote:
> Some systems (such as OMAP) preserve the L2 cache across a suspend/
> resume cycle.  This means they do not perform L2 cache maintanence
> in their suspend finisher function.
> 
> However, the side effect is that the saved CPU state is not readable
> by the resume code because it is sitting in the L2 cache.
> 
> This patch series adds L2 cache cleaning to the generic CPU suspend/
> resume support code, making it possible to use this on systems with
> L2 cache enabled without having to clean/invalidate the entire L2
> cache.
> 
This is also the case on i.MX6Q, which L2 cache is retained during a
suspend/resume cycle.  Currently, I have to call into the following
before calling generic cpu_suspend() to clean/invalidate the entire
L2 cache.

	outer_flush_all();
	outer_disable();

But there is a wired thing on using generic cpu_resume().  I have to
invalidate L1 before calling into cpu_resume() like below.

ENTRY(imx6q_cpu_resume)
        bl      v7_invalidate_l1
        b       cpu_resume
ENDPROC(imx6q_cpu_resume)

ENTRY(imx6q_secondary_startup)
        bl      v7_invalidate_l1
        b       secondary_startup
ENDPROC(imx6q_secondary_startup)

The v7_invalidate_l1() is the function copied from mach-tegra/headsmp.S,
which has to be called before calling secondary_startup to boot
secondary cores (same situation between Tegra and i.MX6Q).

/*
 * Tegra specific entry point for secondary CPUs.
 *   The secondary kernel init calls v7_flush_dcache_all before it enables
 *   the L1; however, the L1 comes out of reset in an undefined state, so
 *   the clean + invalidate performed by v7_flush_dcache_all causes a bunch
 *   of cache lines with uninitialized data and uninitialized tags to get
 *   written out to memory, which does really unpleasant things to the main
 *   processor.  We fix this by performing an invalidate, rather than a
 *   clean + invalidate, before jumping into the kernel.
 */
ENTRY(v7_invalidate_l1)
        mov     r0, #0
        mcr     p15, 2, r0, c0, c0, 0
        mrc     p15, 1, r0, c0, c0, 0

        ldr     r1, =0x7fff
        and     r2, r1, r0, lsr #13

        ldr     r1, =0x3ff

        and     r3, r1, r0, lsr #3  @ NumWays - 1
        add     r2, r2, #1          @ NumSets

        and     r0, r0, #0x7
        add     r0, r0, #4          @ SetShift

        clz     r1, r3              @ WayShift
        add     r4, r3, #1          @ NumWays
1:      sub     r2, r2, #1          @ NumSets--
        mov     r3, r4              @ Temp = NumWays
2:      subs    r3, r3, #1          @ Temp--
        mov     r5, r3, lsl r1
        mov     r6, r2, lsl r0
        orr     r5, r5, r6          @ Reg = (Temp<<WayShift)|(NumSets<<SetShift)
        mcr     p15, 0, r5, c7, c6, 2
        bgt     2b
        cmp     r2, #0
        bgt     1b
        dsb
        isb
        mov     pc, lr
ENDPROC(v7_invalidate_l1)
 
Before applying this patch series, I have something like below actually
working.


	outer_flush_all();
	outer_disable();
	imx_set_cpu_jump(0, imx6q_cpu_resume);
	/* Zzz ... */
	cpu_suspend(0, imx6q_suspend_finish);

I expect with you patches applied, I can still have it work with simply
removing those two lines outer cache codes.  But unfortunately, I'm
running into Oops when resuming back.  And I also have Oops with
imx_set_cpu_jump(0, cpu_resume) which means skipping the
v7_invalidate_l1() and calling generic cpu_resume() only.

I know the key point of the whole thing is that we need to invalidate
L1 before either booting secondary cores or resuming the primary core
on i.MX6Q.  But I really need some help to understand why, and the
best solution to that.

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [PATCH 00/11] Add L2 cache cleaning to generic CPU suspend
  2011-09-01 15:33   ` Shawn Guo
@ 2011-09-01 15:34     ` Russell King - ARM Linux
  -1 siblings, 0 replies; 56+ messages in thread
From: Russell King - ARM Linux @ 2011-09-01 15:34 UTC (permalink / raw)
  To: Shawn Guo; +Cc: Santosh Shilimkar, linux-omap, linux-arm-kernel

On Thu, Sep 01, 2011 at 11:33:43PM +0800, Shawn Guo wrote:
> This is also the case on i.MX6Q, which L2 cache is retained during a
> suspend/resume cycle.  Currently, I have to call into the following
> before calling generic cpu_suspend() to clean/invalidate the entire
> L2 cache.
> 
> 	outer_flush_all();
> 	outer_disable();
> 
> But there is a wired thing on using generic cpu_resume().  I have to
> invalidate L1 before calling into cpu_resume() like below.
> 
> ENTRY(imx6q_cpu_resume)
>         bl      v7_invalidate_l1
>         b       cpu_resume
> ENDPROC(imx6q_cpu_resume)
> 
> ENTRY(imx6q_secondary_startup)
>         bl      v7_invalidate_l1
>         b       secondary_startup
> ENDPROC(imx6q_secondary_startup)
> 
> The v7_invalidate_l1() is the function copied from mach-tegra/headsmp.S,
> which has to be called before calling secondary_startup to boot
> secondary cores (same situation between Tegra and i.MX6Q).

Presumably that's because your L1 cache contains randomized data with
random validity (and presumably random dirtyness) at boot time - something
which unfortunately the ARM ARM permits.  I don't think we can go to the
extent of dealing with this in the generic code as it would unnecessarily
perturb those implementations which either the boot loader has already
sorted out that issue, or which don't have the issue at all.

> Before applying this patch series, I have something like below actually
> working.
> 
> 
> 	outer_flush_all();
> 	outer_disable();
> 	imx_set_cpu_jump(0, imx6q_cpu_resume);
> 	/* Zzz ... */
> 	cpu_suspend(0, imx6q_suspend_finish);
> 
> I expect with you patches applied, I can still have it work with simply
> removing those two lines outer cache codes.

That should be the case.

> But unfortunately, I'm
> running into Oops when resuming back.  And I also have Oops with
> imx_set_cpu_jump(0, cpu_resume) which means skipping the
> v7_invalidate_l1() and calling generic cpu_resume() only.

Do you have a copy of the oops?

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [PATCH 00/11] Add L2 cache cleaning to generic CPU suspend
@ 2011-09-01 15:34     ` Russell King - ARM Linux
  0 siblings, 0 replies; 56+ messages in thread
From: Russell King - ARM Linux @ 2011-09-01 15:34 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Sep 01, 2011 at 11:33:43PM +0800, Shawn Guo wrote:
> This is also the case on i.MX6Q, which L2 cache is retained during a
> suspend/resume cycle.  Currently, I have to call into the following
> before calling generic cpu_suspend() to clean/invalidate the entire
> L2 cache.
> 
> 	outer_flush_all();
> 	outer_disable();
> 
> But there is a wired thing on using generic cpu_resume().  I have to
> invalidate L1 before calling into cpu_resume() like below.
> 
> ENTRY(imx6q_cpu_resume)
>         bl      v7_invalidate_l1
>         b       cpu_resume
> ENDPROC(imx6q_cpu_resume)
> 
> ENTRY(imx6q_secondary_startup)
>         bl      v7_invalidate_l1
>         b       secondary_startup
> ENDPROC(imx6q_secondary_startup)
> 
> The v7_invalidate_l1() is the function copied from mach-tegra/headsmp.S,
> which has to be called before calling secondary_startup to boot
> secondary cores (same situation between Tegra and i.MX6Q).

Presumably that's because your L1 cache contains randomized data with
random validity (and presumably random dirtyness) at boot time - something
which unfortunately the ARM ARM permits.  I don't think we can go to the
extent of dealing with this in the generic code as it would unnecessarily
perturb those implementations which either the boot loader has already
sorted out that issue, or which don't have the issue at all.

> Before applying this patch series, I have something like below actually
> working.
> 
> 
> 	outer_flush_all();
> 	outer_disable();
> 	imx_set_cpu_jump(0, imx6q_cpu_resume);
> 	/* Zzz ... */
> 	cpu_suspend(0, imx6q_suspend_finish);
> 
> I expect with you patches applied, I can still have it work with simply
> removing those two lines outer cache codes.

That should be the case.

> But unfortunately, I'm
> running into Oops when resuming back.  And I also have Oops with
> imx_set_cpu_jump(0, cpu_resume) which means skipping the
> v7_invalidate_l1() and calling generic cpu_resume() only.

Do you have a copy of the oops?

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [PATCH 00/11] Add L2 cache cleaning to generic CPU suspend
  2011-09-01 15:34     ` Russell King - ARM Linux
@ 2011-09-01 15:57       ` Shawn Guo
  -1 siblings, 0 replies; 56+ messages in thread
From: Shawn Guo @ 2011-09-01 15:57 UTC (permalink / raw)
  To: Russell King - ARM Linux; +Cc: Santosh Shilimkar, linux-omap, linux-arm-kernel

On Thu, Sep 01, 2011 at 04:34:51PM +0100, Russell King - ARM Linux wrote:
> On Thu, Sep 01, 2011 at 11:33:43PM +0800, Shawn Guo wrote:
> > This is also the case on i.MX6Q, which L2 cache is retained during a
> > suspend/resume cycle.  Currently, I have to call into the following
> > before calling generic cpu_suspend() to clean/invalidate the entire
> > L2 cache.
> > 
> > 	outer_flush_all();
> > 	outer_disable();
> > 
> > But there is a wired thing on using generic cpu_resume().  I have to
> > invalidate L1 before calling into cpu_resume() like below.
> > 
> > ENTRY(imx6q_cpu_resume)
> >         bl      v7_invalidate_l1
> >         b       cpu_resume
> > ENDPROC(imx6q_cpu_resume)
> > 
> > ENTRY(imx6q_secondary_startup)
> >         bl      v7_invalidate_l1
> >         b       secondary_startup
> > ENDPROC(imx6q_secondary_startup)
> > 
> > The v7_invalidate_l1() is the function copied from mach-tegra/headsmp.S,
> > which has to be called before calling secondary_startup to boot
> > secondary cores (same situation between Tegra and i.MX6Q).
> 
> Presumably that's because your L1 cache contains randomized data with
> random validity (and presumably random dirtyness) at boot time - something
> which unfortunately the ARM ARM permits.  I don't think we can go to the
> extent of dealing with this in the generic code as it would unnecessarily
> perturb those implementations which either the boot loader has already
> sorted out that issue, or which don't have the issue at all.
> 
Yes, agreed.  It seems that Tegra and i.MX6Q are the only two CA9MP
cases here.  But is it possible to maintain this v7_invalidate_l1()
function in cache-v7.S, so that we do not need to duplicate it in
platform codes?

> > Before applying this patch series, I have something like below actually
> > working.
> > 
> > 
> > 	outer_flush_all();
> > 	outer_disable();
> > 	imx_set_cpu_jump(0, imx6q_cpu_resume);
> > 	/* Zzz ... */
> > 	cpu_suspend(0, imx6q_suspend_finish);
> > 
> > I expect with you patches applied, I can still have it work with simply
> > removing those two lines outer cache codes.
> 
> That should be the case.
> 
> > But unfortunately, I'm
> > running into Oops when resuming back.  And I also have Oops with
> > imx_set_cpu_jump(0, cpu_resume) which means skipping the
> > v7_invalidate_l1() and calling generic cpu_resume() only.
> 
> Do you have a copy of the oops?
> 

root@freescale ~$ echo mem > /sys/power/state
PM: Syncing filesystems ... done.
PM: Preparing system for mem sleep
Freezing user space processes ... (elapsed 0.01 seconds) done.
Freezing remaining freezable tasks ... (elapsed 0.01 seconds) done.
PM: Entering mem sleep
PM: suspend of devices complete after 0.402 msecs
PM: suspend devices took 0.000 seconds
PM: late suspend of devices complete after 0.276 msecs
Disabling non-boot CPUs ...
CPU1: shutdown
CPU2: shutdown
CPU3: shutdown
Unable to handle kernel NULL pointer dereference at virtual address 00000000
pgd = eb308000
[00000000] *pgd=7b11d831, *pte=00000000, *ppte=00000000
Internal error: Oops: 80000005 [#1] SMP
Modules linked in:
CPU: 0    Not tainted  (3.1.0-rc4+ #319)
PC is at 0x0
LR is at cpu_init+0x28/0x74
pc : [<00000000>]    lr : [<80010544>]    psr: 800001f3
sp : eb3dbe70  ip : eb3dbe4c  fp : eb2b2560
r10: 8001d8dc  r9 : 8001ef68  r8 : 00000004
r7 : 00000003  r6 : 00000000  r5 : eb0b8b60  r4 : 804865d0
r3 : 80012758  r2 : eb3dbe34  r1 : 7b8f806a  r0 : 00000000
Flags: Nzcv  IRQs off  FIQs off  Mode SVC_32  ISA Thumb  Segment user
Control: 10c53c7d  Table: 7b8f804a  DAC: 00000015
Process login (pid: 445, stack limit = 0xeb3da2f0)
Stack: (0xeb3dbe70 to 0xeb3dc000)
be60:                                     ffffffff 00000000 eb3dbeac eb3dbe88
be80: 8008adc8 8008a5f8 eb3dbeb4 eb3dbe98 801dbec0 eb0a01e0 eb406600 00000000
bea0: 00000000 00000003 eb3dbed4 eb3dbeb8 80063ffc 80063c78 0000006d eb321000
bec0: 8000e34c 8004d730 eb3dbee4 00000b04 800bc9e4 eb868140 ffffffff 00000000
bee0: eb3dbf70 eb8286c0 00000004 eb806bc0 eb3dbf0c eb3dbf00 801d7344 800633a8
bf00: eb3dbf2c 00000003 2aad7000 00000000 eb3da000 eb0b91e0 00000007 00001000
bf20: eb3dbf64 eb3dbf30 801dbff4 80311644 80000013 eb0b8b9c eb3da000 2aaeb000
bf40: 800a71ec 80025538 800aae40 eb181000 eb3dbfb0 00000000 eb3dbfb0 eb0df000
bf60: 00020000 00000000 00000024 00000100 02012080 00000008 02012080 00000005
bf80: 8000e504 00000000 eb3dbfa4 eb3dbf98 8009fb74 8009f9d8 00000000 eb3dbfa8
bfa0: 8000e380 8002f8a8 7e837d90 00000000 00000000 00000000 00a69008 00000000
bfc0: 00000004 2ab06000 2acb95f8 00000004 00000004 0201029c 00000001 00000000
bfe0: 00000004 7ebc0478 2ac0798c 2ac53e6c 60000010 00000001 00000000 00000000
Backtrace: frame pointer underflow
[<eb2b02d4>] (0xeb2b02d4) from [<2571140e>] (0x2571140e)
Backtrace aborted due to bad frame pointer <2551140e>
Code: bad PC value
---[ end trace b4510fc09c2ffbd1 ]---
Fixing recursive fault but reboot is needed!
Unable to handle kernel NULL pointer dereference at virtual address 00000010
pgd = eb308000
[00000010] *pgd=7b11d831, *pte=00000000, *ppte=00000000
Internal error: Oops: 5 [#2] SMP
Modules linked in:
CPU: 0    Tainted: G      D      (3.1.0-rc4+ #319)
PC is at find_busiest_group+0xd0/0xa4c
LR is at 0x0
pc : [<80023810>]    lr : [<00000000>]    psr: 600001d3
sp : eb3dba58  ip : 00000000  fp : eb3dbb44
r10: 80415ba0  r9 : eb346000  r8 : 80427b3c
r7 : 80427d10  r6 : 00000010  r5 : 80415ba0  r4 : 00000000
r3 : 00000000  r2 : 00000000  r1 : 00000024  r0 : eb3dbaf4
Flags: nZCv  IRQs off  FIQs off  Mode SVC_32  ISA ARM  Segment user
Control: 10c53c7d  Table: 7b8f804a  DAC: 00000015
Process login (pid: 445, stack limit = 0xeb3da2f0)
Stack: (0xeb3dba58 to 0xeb3dc000)
ba40:                                                       eb926500 0000000a
ba60: eb3dba84 eb3dba70 eb3dbb90 00000002 00000000 00000000 00000000 00000000
ba80: 00000000 8020475c eb346000 eb3dba98 80017d90 00000000 80415ba0 80427ab0
baa0: 80415ba0 eb3dbab0 802048a4 00000000 00000000 00000000 00000000 00000000
bac0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
bae0: 00000000 00000000 00000000 00000000 00000000 00001f61 8042d8b4 8042d8b4
bb00: 00001f61 80443ae0 eb3dbb34 eb3dbb18 8004d4b0 80311644 8002b684 8166e0e4
bb20: eb2b2560 eb3da000 80427d10 eb2b26dc eb346000 00000000 eb3dbbc4 eb3dbb48
bb40: 80024240 8002374c 8166e0e4 eb3dbc0c eb3da000 00000002 eb3dbb8c 8166eba0
bb60: eb346000 80415ba0 8166e0e4 80427b3c 80427d10 80427d10 80415ba0 00000020
bb80: eb3dbbac 00000000 8001e5f0 8001ef20 ffffffb5 00000000 eb2b2560 8166eba0
bba0: eb2b2560 eb3da000 80427d10 eb2b26dc eb346000 00000000 eb3dbc3c eb3dbbc8
bbc0: 8030f5ac 80024198 eb3dbc0c 8042d8b4 eb2b2560 eb2b02d8 000bc20f 00000000
bbe0: 00000001 8041a080 80415ba0 80415ba0 ffff9442 00000006 fffffffc 80415ba0
bc00: 80415ba0 804150c0 eb3dbc2c 00000001 8030ed50 eb2b2560 0000000b 00000000
bc20: fffffffc eb3dbc9b 00000020 eb3da000 eb3dbc74 eb3dbc40 8002f534 8030ef88
bc40: eb3da000 00000000 fffffffc eb3dbc9b 00000020 fffffff8 eb3dbc74 eb3dbc68
bc60: 8002b50c fffffffc eb3dbcfc eb3dbc78 80011c88 8002ee9c eb3da2f0 0000000b
bc80: 00000004 7f000000 00000000 00000004 8039a080 8039a088 62000005 50206461
bca0: 61762043 0065756c eb3dbccc eb3dbcb8 8030ed50 8002bdd0 80000005 eb3dbcd4
bcc0: eb3dbcfc eb3dbce0 800147cc 8030ed38 803ad880 eb3dbe28 00000000 00000000
bce0: 80000005 eb0b8b60 eb0b8b98 eb2b2560 eb3dbd24 eb3dbd00 8001485c 800119fc
bd00: eb3dbe28 eb0b8b60 eb3dbe28 00000000 00010000 80000005 eb3dbd5c eb3dbd28
bd20: 800149c0 800147ec eb922d80 eb44fd30 00000000 80000005 8042af98 00000000
bd40: eb3dbe28 00000004 8001ef68 8001d8dc eb3dbd7c eb3dbd60 80014b74 80014878
bd60: 00000005 8042af98 00000000 eb3dbe28 eb3dbe24 eb3dbd80 800085c4 80014adc
bd80: 8032433c 00000000 eb3dbdac eb3dbd98 80074b6c 80074ad8 80074b48 fffffffa
bda0: eb90d9e0 00000000 eb3dbdec eb3dbdb8 80027170 80311644 00000001 40000093
bdc0: 800401b4 80027408 eb3dbdec eb3dbdd8 80040248 80040198 80415ba0 80415ba0
bde0: 8020add0 8020ad10 00000000 8048d5c0 0000003f 0000003e eb93a000 8048dee4
be00: eb8295a0 eb3da000 00000000 800001f3 ffffffff eb3dbe5c eb2b2560 eb3dbe28
be20: 8000e018 80008590 00000000 7b8f806a eb3dbe34 80012758 804865d0 eb0b8b60
be40: 00000000 00000003 00000004 8001ef68 8001d8dc eb2b2560 eb3dbe4c eb3dbe70
be60: 80010544 00000000 800001f3 ffffffff ffffffff 00000000 eb3dbeac eb3dbe88
be80: 8008adc8 8008a5f8 eb3dbeb4 eb3dbe98 801dbec0 eb0a01e0 eb406600 00000000
bea0: 00000000 00000003 eb3dbed4 eb3dbeb8 80063ffc 80063c78 0000006d eb321000
bec0: 8000e34c 8004d730 eb3dbee4 00000b04 800bc9e4 eb868140 ffffffff 00000000
bee0: eb3dbf70 eb8286c0 00000004 eb806bc0 eb3dbf0c eb3dbf00 801d7344 800633a8
bf00: eb3dbf2c 00000003 2aad7000 00000000 eb3da000 eb0b91e0 00000007 00001000
bf20: eb3dbf64 eb3dbf30 801dbff4 80311644 80000013 eb0b8b9c eb3da000 2aaeb000
bf40: 800a71ec 80025538 800aae40 eb181000 eb3dbfb0 00000000 eb3dbfb0 eb0df000
bf60: 00020000 00000000 00000024 00000100 02012080 00000008 02012080 00000005
bf80: 8000e504 00000000 eb3dbfa4 eb3dbf98 8009fb74 8009f9d8 00000000 eb3dbfa8
bfa0: 8000e380 8002f8a8 7e837d90 00000000 00000000 00000000 00a69008 00000000
bfc0: 00000004 2ab06000 2acb95f8 00000004 00000004 0201029c 00000001 00000000
bfe0: 00000004 7ebc0478 2ac0798c 2ac53e6c 60000010 00000001 00000000 00000000
Backtrace:
[<80023740>] (find_busiest_group+0x0/0xa4c) from [<80024240>] (load_balance+0xb4
/0x5ac)
[<8002418c>] (load_balance+0x0/0x5ac) from [<8030f5ac>] (schedule+0x630/0x6a8)
[<8030ef7c>] (schedule+0x0/0x6a8) from [<8002f534>] (do_exit+0x6a4/0x6f0)
[<8002ee90>] (do_exit+0x0/0x6f0) from [<80011c88>] (die+0x298/0x2ec)
 r7:fffffffc
[<800119f0>] (die+0x0/0x2ec) from [<8001485c>] (__do_kernel_fault+0x7c/0x8c)
[<800147e0>] (__do_kernel_fault+0x0/0x8c) from [<800149c0>] (do_page_fault+0x154
/0x1f8)
 r8:80000005 r7:00010000 r6:00000000 r5:eb3dbe28 r4:eb0b8b60
r3:eb3dbe28
[<8001486c>] (do_page_fault+0x0/0x1f8) from [<80014b74>] (do_translation_fault+0
xa4/0xa8)
[<80014ad0>] (do_translation_fault+0x0/0xa8) from [<800085c4>] (do_PrefetchAbort
+0x40/0xa4)
 r7:eb3dbe28 r6:00000000 r5:8042af98 r4:00000005
[<80008584>] (do_PrefetchAbort+0x0/0xa4) from [<8000e018>] (__pabt_svc+0x38/0x80
)
Exception stack(0xeb3dbe28 to 0xeb3dbe70)
be20:                   00000000 7b8f806a eb3dbe34 80012758 804865d0 eb0b8b60
be40: 00000000 00000003 00000004 8001ef68 8001d8dc eb2b2560 eb3dbe4c eb3dbe70
be60: 80010544 00000000 800001f3 ffffffff
 r7:eb3dbe5c r6:ffffffff r5:800001f3 r4:00000000
Backtrace aborted due to bad frame pointer <eb2b2560>
Code: e51b20c8 e3a01024 e28e6010 e51b30cc (e7965002)
---[ end trace b4510fc09c2ffbd2 ]---
Fixing recursive fault but reboot is needed!
Unable to handle kernel NULL pointer dereference at virtual address 00000008
pgd = eb308000
[00000008] *pgd=7b11d831, *pte=00000000, *ppte=00000000
Internal error: Oops: 5 [#3] SMP
Modules linked in:
CPU: 0    Tainted: G      D      (3.1.0-rc4+ #319)
PC is at rb_next+0xc/0x74
LR is at pick_next_task_fair+0xd8/0x114
pc : [<801dbb18>]    lr : [<80022230>]    psr: 600001d3
sp : eb3db778  ip : eb3db788  fp : eb3db784
r10: 00000000  r9 : 80313ac0  r8 : eb2b26dc
r7 : 80427d10  r6 : 00000000  r5 : 8166eba0  r4 : 00000000
r3 : 80022158  r2 : ffffffff  r1 : 00000000  r0 : 00000008
Flags: nZCv  IRQs off  FIQs off  Mode SVC_32  ISA ARM  Segment user
Control: 10c53c7d  Table: 7b8f804a  DAC: 00000015
Process login (pid: 445, stack limit = 0xeb3da2f0)
Stack: (0xeb3db778 to 0xeb3dc000)
b760:                                                       eb3db7a4 eb3db788
b780: 80022230 801dbb18 8166eba0 eb2b2560 eb3da000 80427d10 eb3db81c eb3db7a8
b7a0: 8030f450 80022164 00000000 8042d8b4 8039a085 ffffffff ffffffff 8039a087
b7c0: 00000001 0039a085 80415ba0 80415ba0 0000000b 00000000 00000001 80415ba0
b7e0: 80415ba0 804150c0 eb3db80c eb3db7f8 8030ed50 eb2b2560 0000000b 00000000
b800: 00000001 eb3db8aa 00000000 eb3da000 eb3db854 eb3db820 8002f534 8030ef88
b820: eb3da000 00000000 00000001 eb3db8aa 00000000 80023812 eb3db854 eb3db848
b840: 8002b50c 00000001 eb3db8dc eb3db858 80011c88 8002ee9c eb3da2f0 0000000b
b860: 00000004 7f000000 00000000 00000008 8039a080 8039a088 65000005 32623135
b880: 20386330 30613365 34323031 38326520 31303665 35652030 30336231 28206363
b8a0: 36393765 32303035 80002029 8030ed38 803ad880 eb3dba10 00000010 00000000
b8c0: 00000005 eb0b8b60 eb0b8b98 eb2b2560 eb3db904 eb3db8e0 8001485c 800119fc
b8e0: eb3dba10 eb0b8b60 eb3dba10 00000010 00010000 00000005 eb3db93c eb3db908
b900: 800149c0 800147ec eb3db930 eb3db918 801df694 00000005 00000010 8042af48
b920: 00000005 eb3dba10 eb346000 80415ba0 eb3db95c eb3db940 80014b74 80014878
b940: 00000005 00000010 8042af48 00000005 eb3dba0c eb3db960 80008520 80014adc
b960: 00000000 eb3db991 80443f0c 80443b39 00000000 ffffffff eb3dba94 eb3db988
b980: 801de75c 801de3d0 ffffffff ffffffff 327830f8 31313735 00653034 00001831
b9a0: 0000001c 80427afc eb3dba0c 0000184d 8042d8b4 8042d8b4 0000184d 80443ae0
b9c0: eb3db9ec eb3db9d0 8004d4b0 80311644 8002b684 8002b51c 0000184d 0000184d
b9e0: eb3dba24 eb3db9f0 eb3dba0c 80023810 600001d3 ffffffff eb3dba44 80427b3c
ba00: eb3dbb44 eb3dba10 8000de98 800084f0 eb3dbaf4 00000024 00000000 00000000
ba20: 00000000 80415ba0 00000010 80427d10 80427b3c eb346000 80415ba0 eb3dbb44
ba40: 00000000 eb3dba58 00000000 80023810 600001d3 ffffffff eb926500 0000000a
ba60: eb3dba84 eb3dba70 eb3dbb90 00000002 00000000 00000000 00000000 00000000
ba80: 00000000 8020475c eb346000 eb3dba98 80017d90 00000000 80415ba0 80427ab0
baa0: 80415ba0 eb3dbab0 802048a4 00000000 00000000 00000000 00000000 00000000
bac0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
bae0: 00000000 00000000 00000000 00000000 00000000 00001f61 8042d8b4 8042d8b4
bb00: 00001f61 80443ae0 eb3dbb34 eb3dbb18 8004d4b0 80311644 8002b684 8166e0e4
bb20: eb2b2560 eb3da000 80427d10 eb2b26dc eb346000 00000000 eb3dbbc4 eb3dbb48
bb40: 80024240 8002374c 8166e0e4 eb3dbc0c eb3da000 00000002 eb3dbb8c 8166eba0
bb60: eb346000 80415ba0 8166e0e4 80427b3c 80427d10 80427d10 80415ba0 00000020
bb80: eb3dbbac 00000000 8001e5f0 8001ef20 ffffffb5 00000000 eb2b2560 8166eba0
bba0: eb2b2560 eb3da000 80427d10 eb2b26dc eb346000 00000000 eb3dbc3c eb3dbbc8
bbc0: 8030f5ac 80024198 eb3dbc0c 8042d8b4 eb2b2560 eb2b02d8 000bc20f 00000000
bbe0: 00000001 8041a080 80415ba0 80415ba0 ffff9442 00000006 fffffffc 80415ba0
bc00: 80415ba0 804150c0 eb3dbc2c 00000001 8030ed50 eb2b2560 0000000b 00000000
bc20: fffffffc eb3dbc9b 00000020 eb3da000 eb3dbc74 eb3dbc40 8002f534 8030ef88
bc40: eb3da000 00000000 fffffffc eb3dbc9b 00000020 fffffff8 eb3dbc74 eb3dbc68
bc60: 8002b50c fffffffc eb3dbcfc eb3dbc78 80011c88 8002ee9c eb3da2f0 0000000b
bc80: 00000004 7f000000 00000000 00000004 8039a080 8039a088 62000005 50206461
bca0: 61762043 0065756c eb3dbccc eb3dbcb8 8030ed50 8002bdd0 80000005 eb3dbcd4
bcc0: eb3dbcfc eb3dbce0 800147cc 8030ed38 803ad880 eb3dbe28 00000000 00000000
bce0: 80000005 eb0b8b60 eb0b8b98 eb2b2560 eb3dbd24 eb3dbd00 8001485c 800119fc
bd00: eb3dbe28 eb0b8b60 eb3dbe28 00000000 00010000 80000005 eb3dbd5c eb3dbd28
bd20: 800149c0 800147ec eb922d80 eb44fd30 00000000 80000005 8042af98 00000000
bd40: eb3dbe28 00000004 8001ef68 8001d8dc eb3dbd7c eb3dbd60 80014b74 80014878
bd60: 00000005 8042af98 00000000 eb3dbe28 eb3dbe24 eb3dbd80 800085c4 80014adc
bd80: 8032433c 00000000 eb3dbdac eb3dbd98 80074b6c 80074ad8 80074b48 fffffffa
bda0: eb90d9e0 00000000 eb3dbdec eb3dbdb8 80027170 80311644 00000001 40000093
bdc0: 800401b4 80027408 eb3dbdec eb3dbdd8 80040248 80040198 80415ba0 80415ba0
bde0: 8020add0 8020ad10 00000000 8048d5c0 0000003f 0000003e eb93a000 8048dee4
be00: eb8295a0 eb3da000 00000000 800001f3 ffffffff eb3dbe5c eb2b2560 eb3dbe28
be20: 8000e018 80008590 00000000 7b8f806a eb3dbe34 80012758 804865d0 eb0b8b60
be40: 00000000 00000003 00000004 8001ef68 8001d8dc eb2b2560 eb3dbe4c eb3dbe70
be60: 80010544 00000000 800001f3 ffffffff ffffffff 00000000 eb3dbeac eb3dbe88
be80: 8008adc8 8008a5f8 eb3dbeb4 eb3dbe98 801dbec0 eb0a01e0 eb406600 00000000
bea0: 00000000 00000003 eb3dbed4 eb3dbeb8 80063ffc 80063c78 0000006d eb321000
bec0: 8000e34c 8004d730 eb3dbee4 00000b04 800bc9e4 eb868140 ffffffff 00000000
bee0: eb3dbf70 eb8286c0 00000004 eb806bc0 eb3dbf0c eb3dbf00 801d7344 800633a8
bf00: eb3dbf2c 00000003 2aad7000 00000000 eb3da000 eb0b91e0 00000007 00001000
bf20: eb3dbf64 eb3dbf30 801dbff4 80311644 80000013 eb0b8b9c eb3da000 2aaeb000
bf40: 800a71ec 80025538 800aae40 eb181000 eb3dbfb0 00000000 eb3dbfb0 eb0df000
bf60: 00020000 00000000 00000024 00000100 02012080 00000008 02012080 00000005
bf80: 8000e504 00000000 eb3dbfa4 eb3dbf98 8009fb74 8009f9d8 00000000 eb3dbfa8
bfa0: 8000e380 8002f8a8 7e837d90 00000000 00000000 00000000 00a69008 00000000
bfc0: 00000004 2ab06000 2acb95f8 00000004 00000004 0201029c 00000001 00000000
bfe0: 00000004 7ebc0478 2ac0798c 2ac53e6c 60000010 00000001 00000000 00000000
Backtrace:
[<801dbb0c>] (rb_next+0x0/0x74) from [<80022230>] (pick_next_task_fair+0xd8/0x11
4)
[<80022158>] (pick_next_task_fair+0x0/0x114) from [<8030f450>] (schedule+0x4d4/0
x6a8)
 r7:80427d10 r6:eb3da000 r5:eb2b2560 r4:8166eba0
[<8030ef7c>] (schedule+0x0/0x6a8) from [<8002f534>] (do_exit+0x6a4/0x6f0)
[<8002ee90>] (do_exit+0x0/0x6f0) from [<80011c88>] (die+0x298/0x2ec)
 r7:00000001
[<800119f0>] (die+0x0/0x2ec) from [<8001485c>] (__do_kernel_fault+0x7c/0x8c)
[<800147e0>] (__do_kernel_fault+0x0/0x8c) from [<800149c0>] (do_page_fault+0x154
/0x1f8)
 r8:00000005 r7:00010000 r6:00000010 r5:eb3dba10 r4:eb0b8b60
r3:eb3dba10
[<8001486c>] (do_page_fault+0x0/0x1f8) from [<80014b74>] (do_translation_fault+0
xa4/0xa8)
[<80014ad0>] (do_translation_fault+0x0/0xa8) from [<80008520>] (do_DataAbort+0x3
c/0xa0)
 r7:00000005 r6:8042af48 r5:00000010 r4:00000005
[<800084e4>] (do_DataAbort+0x0/0xa0) from [<8000de98>] (__dabt_svc+0x38/0x60)
Exception stack(0xeb3dba10 to 0xeb3dba58)
ba00:                                     eb3dbaf4 00000024 00000000 00000000
ba20: 00000000 80415ba0 00000010 80427d10 80427b3c eb346000 80415ba0 eb3dbb44
ba40: 00000000 eb3dba58 00000000 80023810 600001d3 ffffffff
 r8:80427b3c r7:eb3dba44 r6:ffffffff r5:600001d3 r4:80023810
[<80023740>] (find_busiest_group+0x0/0xa4c) from [<80024240>] (load_balance+0xb4
/0x5ac)
[<8002418c>] (load_balance+0x0/0x5ac) from [<8030f5ac>] (schedule+0x630/0x6a8)
[<8030ef7c>] (schedule+0x0/0x6a8) from [<8002f534>] (do_exit+0x6a4/0x6f0)
[<8002ee90>] (do_exit+0x0/0x6f0) from [<80011c88>] (die+0x298/0x2ec)
 r7:fffffffc
[<800119f0>] (die+0x0/0x2ec) from [<8001485c>] (__do_kernel_fault+0x7c/0x8c)
[<800147e0>] (__do_kernel_fault+0x0/0x8c) from [<800149c0>] (do_page_fault+0x154
/0x1f8)
 r8:80000005 r7:00010000 r6:00000000 r5:eb3dbe28 r4:eb0b8b60
r3:eb3dbe28
[<8001486c>] (do_page_fault+0x0/0x1f8) from [<80014b74>] (do_translation_fault+0
xa4/0xa8)
[<80014ad0>] (do_translation_fault+0x0/0xa8) from [<800085c4>] (do_PrefetchAbort
+0x40/0xa4)
 r7:eb3dbe28 r6:00000000 r5:8042af98 r4:00000005
[<80008584>] (do_PrefetchAbort+0x0/0xa4) from [<8000e018>] (__pabt_svc+0x38/0x80
)
Exception stack(0xeb3dbe28 to 0xeb3dbe70)
be20:                   00000000 7b8f806a eb3dbe34 80012758 804865d0 eb0b8b60
be40: 00000000 00000003 00000004 8001ef68 8001d8dc eb2b2560 eb3dbe4c eb3dbe70
be60: 80010544 00000000 800001f3 ffffffff
 r7:eb3dbe5c r6:ffffffff r5:800001f3 r4:00000000
Backtrace aborted due to bad frame pointer <eb2b2560>
Code: e89da800 e1a0c00d e92dd800 e24cb004 (e5903000)
---[ end trace b4510fc09c2ffbd3 ]---
Fixing recursive fault but reboot is needed!

-- 
Regards,
Shawn


^ permalink raw reply	[flat|nested] 56+ messages in thread

* [PATCH 00/11] Add L2 cache cleaning to generic CPU suspend
@ 2011-09-01 15:57       ` Shawn Guo
  0 siblings, 0 replies; 56+ messages in thread
From: Shawn Guo @ 2011-09-01 15:57 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Sep 01, 2011 at 04:34:51PM +0100, Russell King - ARM Linux wrote:
> On Thu, Sep 01, 2011 at 11:33:43PM +0800, Shawn Guo wrote:
> > This is also the case on i.MX6Q, which L2 cache is retained during a
> > suspend/resume cycle.  Currently, I have to call into the following
> > before calling generic cpu_suspend() to clean/invalidate the entire
> > L2 cache.
> > 
> > 	outer_flush_all();
> > 	outer_disable();
> > 
> > But there is a wired thing on using generic cpu_resume().  I have to
> > invalidate L1 before calling into cpu_resume() like below.
> > 
> > ENTRY(imx6q_cpu_resume)
> >         bl      v7_invalidate_l1
> >         b       cpu_resume
> > ENDPROC(imx6q_cpu_resume)
> > 
> > ENTRY(imx6q_secondary_startup)
> >         bl      v7_invalidate_l1
> >         b       secondary_startup
> > ENDPROC(imx6q_secondary_startup)
> > 
> > The v7_invalidate_l1() is the function copied from mach-tegra/headsmp.S,
> > which has to be called before calling secondary_startup to boot
> > secondary cores (same situation between Tegra and i.MX6Q).
> 
> Presumably that's because your L1 cache contains randomized data with
> random validity (and presumably random dirtyness) at boot time - something
> which unfortunately the ARM ARM permits.  I don't think we can go to the
> extent of dealing with this in the generic code as it would unnecessarily
> perturb those implementations which either the boot loader has already
> sorted out that issue, or which don't have the issue at all.
> 
Yes, agreed.  It seems that Tegra and i.MX6Q are the only two CA9MP
cases here.  But is it possible to maintain this v7_invalidate_l1()
function in cache-v7.S, so that we do not need to duplicate it in
platform codes?

> > Before applying this patch series, I have something like below actually
> > working.
> > 
> > 
> > 	outer_flush_all();
> > 	outer_disable();
> > 	imx_set_cpu_jump(0, imx6q_cpu_resume);
> > 	/* Zzz ... */
> > 	cpu_suspend(0, imx6q_suspend_finish);
> > 
> > I expect with you patches applied, I can still have it work with simply
> > removing those two lines outer cache codes.
> 
> That should be the case.
> 
> > But unfortunately, I'm
> > running into Oops when resuming back.  And I also have Oops with
> > imx_set_cpu_jump(0, cpu_resume) which means skipping the
> > v7_invalidate_l1() and calling generic cpu_resume() only.
> 
> Do you have a copy of the oops?
> 

root at freescale ~$ echo mem > /sys/power/state
PM: Syncing filesystems ... done.
PM: Preparing system for mem sleep
Freezing user space processes ... (elapsed 0.01 seconds) done.
Freezing remaining freezable tasks ... (elapsed 0.01 seconds) done.
PM: Entering mem sleep
PM: suspend of devices complete after 0.402 msecs
PM: suspend devices took 0.000 seconds
PM: late suspend of devices complete after 0.276 msecs
Disabling non-boot CPUs ...
CPU1: shutdown
CPU2: shutdown
CPU3: shutdown
Unable to handle kernel NULL pointer dereference at virtual address 00000000
pgd = eb308000
[00000000] *pgd=7b11d831, *pte=00000000, *ppte=00000000
Internal error: Oops: 80000005 [#1] SMP
Modules linked in:
CPU: 0    Not tainted  (3.1.0-rc4+ #319)
PC is at 0x0
LR is at cpu_init+0x28/0x74
pc : [<00000000>]    lr : [<80010544>]    psr: 800001f3
sp : eb3dbe70  ip : eb3dbe4c  fp : eb2b2560
r10: 8001d8dc  r9 : 8001ef68  r8 : 00000004
r7 : 00000003  r6 : 00000000  r5 : eb0b8b60  r4 : 804865d0
r3 : 80012758  r2 : eb3dbe34  r1 : 7b8f806a  r0 : 00000000
Flags: Nzcv  IRQs off  FIQs off  Mode SVC_32  ISA Thumb  Segment user
Control: 10c53c7d  Table: 7b8f804a  DAC: 00000015
Process login (pid: 445, stack limit = 0xeb3da2f0)
Stack: (0xeb3dbe70 to 0xeb3dc000)
be60:                                     ffffffff 00000000 eb3dbeac eb3dbe88
be80: 8008adc8 8008a5f8 eb3dbeb4 eb3dbe98 801dbec0 eb0a01e0 eb406600 00000000
bea0: 00000000 00000003 eb3dbed4 eb3dbeb8 80063ffc 80063c78 0000006d eb321000
bec0: 8000e34c 8004d730 eb3dbee4 00000b04 800bc9e4 eb868140 ffffffff 00000000
bee0: eb3dbf70 eb8286c0 00000004 eb806bc0 eb3dbf0c eb3dbf00 801d7344 800633a8
bf00: eb3dbf2c 00000003 2aad7000 00000000 eb3da000 eb0b91e0 00000007 00001000
bf20: eb3dbf64 eb3dbf30 801dbff4 80311644 80000013 eb0b8b9c eb3da000 2aaeb000
bf40: 800a71ec 80025538 800aae40 eb181000 eb3dbfb0 00000000 eb3dbfb0 eb0df000
bf60: 00020000 00000000 00000024 00000100 02012080 00000008 02012080 00000005
bf80: 8000e504 00000000 eb3dbfa4 eb3dbf98 8009fb74 8009f9d8 00000000 eb3dbfa8
bfa0: 8000e380 8002f8a8 7e837d90 00000000 00000000 00000000 00a69008 00000000
bfc0: 00000004 2ab06000 2acb95f8 00000004 00000004 0201029c 00000001 00000000
bfe0: 00000004 7ebc0478 2ac0798c 2ac53e6c 60000010 00000001 00000000 00000000
Backtrace: frame pointer underflow
[<eb2b02d4>] (0xeb2b02d4) from [<2571140e>] (0x2571140e)
Backtrace aborted due to bad frame pointer <2551140e>
Code: bad PC value
---[ end trace b4510fc09c2ffbd1 ]---
Fixing recursive fault but reboot is needed!
Unable to handle kernel NULL pointer dereference at virtual address 00000010
pgd = eb308000
[00000010] *pgd=7b11d831, *pte=00000000, *ppte=00000000
Internal error: Oops: 5 [#2] SMP
Modules linked in:
CPU: 0    Tainted: G      D      (3.1.0-rc4+ #319)
PC is at find_busiest_group+0xd0/0xa4c
LR is at 0x0
pc : [<80023810>]    lr : [<00000000>]    psr: 600001d3
sp : eb3dba58  ip : 00000000  fp : eb3dbb44
r10: 80415ba0  r9 : eb346000  r8 : 80427b3c
r7 : 80427d10  r6 : 00000010  r5 : 80415ba0  r4 : 00000000
r3 : 00000000  r2 : 00000000  r1 : 00000024  r0 : eb3dbaf4
Flags: nZCv  IRQs off  FIQs off  Mode SVC_32  ISA ARM  Segment user
Control: 10c53c7d  Table: 7b8f804a  DAC: 00000015
Process login (pid: 445, stack limit = 0xeb3da2f0)
Stack: (0xeb3dba58 to 0xeb3dc000)
ba40:                                                       eb926500 0000000a
ba60: eb3dba84 eb3dba70 eb3dbb90 00000002 00000000 00000000 00000000 00000000
ba80: 00000000 8020475c eb346000 eb3dba98 80017d90 00000000 80415ba0 80427ab0
baa0: 80415ba0 eb3dbab0 802048a4 00000000 00000000 00000000 00000000 00000000
bac0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
bae0: 00000000 00000000 00000000 00000000 00000000 00001f61 8042d8b4 8042d8b4
bb00: 00001f61 80443ae0 eb3dbb34 eb3dbb18 8004d4b0 80311644 8002b684 8166e0e4
bb20: eb2b2560 eb3da000 80427d10 eb2b26dc eb346000 00000000 eb3dbbc4 eb3dbb48
bb40: 80024240 8002374c 8166e0e4 eb3dbc0c eb3da000 00000002 eb3dbb8c 8166eba0
bb60: eb346000 80415ba0 8166e0e4 80427b3c 80427d10 80427d10 80415ba0 00000020
bb80: eb3dbbac 00000000 8001e5f0 8001ef20 ffffffb5 00000000 eb2b2560 8166eba0
bba0: eb2b2560 eb3da000 80427d10 eb2b26dc eb346000 00000000 eb3dbc3c eb3dbbc8
bbc0: 8030f5ac 80024198 eb3dbc0c 8042d8b4 eb2b2560 eb2b02d8 000bc20f 00000000
bbe0: 00000001 8041a080 80415ba0 80415ba0 ffff9442 00000006 fffffffc 80415ba0
bc00: 80415ba0 804150c0 eb3dbc2c 00000001 8030ed50 eb2b2560 0000000b 00000000
bc20: fffffffc eb3dbc9b 00000020 eb3da000 eb3dbc74 eb3dbc40 8002f534 8030ef88
bc40: eb3da000 00000000 fffffffc eb3dbc9b 00000020 fffffff8 eb3dbc74 eb3dbc68
bc60: 8002b50c fffffffc eb3dbcfc eb3dbc78 80011c88 8002ee9c eb3da2f0 0000000b
bc80: 00000004 7f000000 00000000 00000004 8039a080 8039a088 62000005 50206461
bca0: 61762043 0065756c eb3dbccc eb3dbcb8 8030ed50 8002bdd0 80000005 eb3dbcd4
bcc0: eb3dbcfc eb3dbce0 800147cc 8030ed38 803ad880 eb3dbe28 00000000 00000000
bce0: 80000005 eb0b8b60 eb0b8b98 eb2b2560 eb3dbd24 eb3dbd00 8001485c 800119fc
bd00: eb3dbe28 eb0b8b60 eb3dbe28 00000000 00010000 80000005 eb3dbd5c eb3dbd28
bd20: 800149c0 800147ec eb922d80 eb44fd30 00000000 80000005 8042af98 00000000
bd40: eb3dbe28 00000004 8001ef68 8001d8dc eb3dbd7c eb3dbd60 80014b74 80014878
bd60: 00000005 8042af98 00000000 eb3dbe28 eb3dbe24 eb3dbd80 800085c4 80014adc
bd80: 8032433c 00000000 eb3dbdac eb3dbd98 80074b6c 80074ad8 80074b48 fffffffa
bda0: eb90d9e0 00000000 eb3dbdec eb3dbdb8 80027170 80311644 00000001 40000093
bdc0: 800401b4 80027408 eb3dbdec eb3dbdd8 80040248 80040198 80415ba0 80415ba0
bde0: 8020add0 8020ad10 00000000 8048d5c0 0000003f 0000003e eb93a000 8048dee4
be00: eb8295a0 eb3da000 00000000 800001f3 ffffffff eb3dbe5c eb2b2560 eb3dbe28
be20: 8000e018 80008590 00000000 7b8f806a eb3dbe34 80012758 804865d0 eb0b8b60
be40: 00000000 00000003 00000004 8001ef68 8001d8dc eb2b2560 eb3dbe4c eb3dbe70
be60: 80010544 00000000 800001f3 ffffffff ffffffff 00000000 eb3dbeac eb3dbe88
be80: 8008adc8 8008a5f8 eb3dbeb4 eb3dbe98 801dbec0 eb0a01e0 eb406600 00000000
bea0: 00000000 00000003 eb3dbed4 eb3dbeb8 80063ffc 80063c78 0000006d eb321000
bec0: 8000e34c 8004d730 eb3dbee4 00000b04 800bc9e4 eb868140 ffffffff 00000000
bee0: eb3dbf70 eb8286c0 00000004 eb806bc0 eb3dbf0c eb3dbf00 801d7344 800633a8
bf00: eb3dbf2c 00000003 2aad7000 00000000 eb3da000 eb0b91e0 00000007 00001000
bf20: eb3dbf64 eb3dbf30 801dbff4 80311644 80000013 eb0b8b9c eb3da000 2aaeb000
bf40: 800a71ec 80025538 800aae40 eb181000 eb3dbfb0 00000000 eb3dbfb0 eb0df000
bf60: 00020000 00000000 00000024 00000100 02012080 00000008 02012080 00000005
bf80: 8000e504 00000000 eb3dbfa4 eb3dbf98 8009fb74 8009f9d8 00000000 eb3dbfa8
bfa0: 8000e380 8002f8a8 7e837d90 00000000 00000000 00000000 00a69008 00000000
bfc0: 00000004 2ab06000 2acb95f8 00000004 00000004 0201029c 00000001 00000000
bfe0: 00000004 7ebc0478 2ac0798c 2ac53e6c 60000010 00000001 00000000 00000000
Backtrace:
[<80023740>] (find_busiest_group+0x0/0xa4c) from [<80024240>] (load_balance+0xb4
/0x5ac)
[<8002418c>] (load_balance+0x0/0x5ac) from [<8030f5ac>] (schedule+0x630/0x6a8)
[<8030ef7c>] (schedule+0x0/0x6a8) from [<8002f534>] (do_exit+0x6a4/0x6f0)
[<8002ee90>] (do_exit+0x0/0x6f0) from [<80011c88>] (die+0x298/0x2ec)
 r7:fffffffc
[<800119f0>] (die+0x0/0x2ec) from [<8001485c>] (__do_kernel_fault+0x7c/0x8c)
[<800147e0>] (__do_kernel_fault+0x0/0x8c) from [<800149c0>] (do_page_fault+0x154
/0x1f8)
 r8:80000005 r7:00010000 r6:00000000 r5:eb3dbe28 r4:eb0b8b60
r3:eb3dbe28
[<8001486c>] (do_page_fault+0x0/0x1f8) from [<80014b74>] (do_translation_fault+0
xa4/0xa8)
[<80014ad0>] (do_translation_fault+0x0/0xa8) from [<800085c4>] (do_PrefetchAbort
+0x40/0xa4)
 r7:eb3dbe28 r6:00000000 r5:8042af98 r4:00000005
[<80008584>] (do_PrefetchAbort+0x0/0xa4) from [<8000e018>] (__pabt_svc+0x38/0x80
)
Exception stack(0xeb3dbe28 to 0xeb3dbe70)
be20:                   00000000 7b8f806a eb3dbe34 80012758 804865d0 eb0b8b60
be40: 00000000 00000003 00000004 8001ef68 8001d8dc eb2b2560 eb3dbe4c eb3dbe70
be60: 80010544 00000000 800001f3 ffffffff
 r7:eb3dbe5c r6:ffffffff r5:800001f3 r4:00000000
Backtrace aborted due to bad frame pointer <eb2b2560>
Code: e51b20c8 e3a01024 e28e6010 e51b30cc (e7965002)
---[ end trace b4510fc09c2ffbd2 ]---
Fixing recursive fault but reboot is needed!
Unable to handle kernel NULL pointer dereference at virtual address 00000008
pgd = eb308000
[00000008] *pgd=7b11d831, *pte=00000000, *ppte=00000000
Internal error: Oops: 5 [#3] SMP
Modules linked in:
CPU: 0    Tainted: G      D      (3.1.0-rc4+ #319)
PC is at rb_next+0xc/0x74
LR is at pick_next_task_fair+0xd8/0x114
pc : [<801dbb18>]    lr : [<80022230>]    psr: 600001d3
sp : eb3db778  ip : eb3db788  fp : eb3db784
r10: 00000000  r9 : 80313ac0  r8 : eb2b26dc
r7 : 80427d10  r6 : 00000000  r5 : 8166eba0  r4 : 00000000
r3 : 80022158  r2 : ffffffff  r1 : 00000000  r0 : 00000008
Flags: nZCv  IRQs off  FIQs off  Mode SVC_32  ISA ARM  Segment user
Control: 10c53c7d  Table: 7b8f804a  DAC: 00000015
Process login (pid: 445, stack limit = 0xeb3da2f0)
Stack: (0xeb3db778 to 0xeb3dc000)
b760:                                                       eb3db7a4 eb3db788
b780: 80022230 801dbb18 8166eba0 eb2b2560 eb3da000 80427d10 eb3db81c eb3db7a8
b7a0: 8030f450 80022164 00000000 8042d8b4 8039a085 ffffffff ffffffff 8039a087
b7c0: 00000001 0039a085 80415ba0 80415ba0 0000000b 00000000 00000001 80415ba0
b7e0: 80415ba0 804150c0 eb3db80c eb3db7f8 8030ed50 eb2b2560 0000000b 00000000
b800: 00000001 eb3db8aa 00000000 eb3da000 eb3db854 eb3db820 8002f534 8030ef88
b820: eb3da000 00000000 00000001 eb3db8aa 00000000 80023812 eb3db854 eb3db848
b840: 8002b50c 00000001 eb3db8dc eb3db858 80011c88 8002ee9c eb3da2f0 0000000b
b860: 00000004 7f000000 00000000 00000008 8039a080 8039a088 65000005 32623135
b880: 20386330 30613365 34323031 38326520 31303665 35652030 30336231 28206363
b8a0: 36393765 32303035 80002029 8030ed38 803ad880 eb3dba10 00000010 00000000
b8c0: 00000005 eb0b8b60 eb0b8b98 eb2b2560 eb3db904 eb3db8e0 8001485c 800119fc
b8e0: eb3dba10 eb0b8b60 eb3dba10 00000010 00010000 00000005 eb3db93c eb3db908
b900: 800149c0 800147ec eb3db930 eb3db918 801df694 00000005 00000010 8042af48
b920: 00000005 eb3dba10 eb346000 80415ba0 eb3db95c eb3db940 80014b74 80014878
b940: 00000005 00000010 8042af48 00000005 eb3dba0c eb3db960 80008520 80014adc
b960: 00000000 eb3db991 80443f0c 80443b39 00000000 ffffffff eb3dba94 eb3db988
b980: 801de75c 801de3d0 ffffffff ffffffff 327830f8 31313735 00653034 00001831
b9a0: 0000001c 80427afc eb3dba0c 0000184d 8042d8b4 8042d8b4 0000184d 80443ae0
b9c0: eb3db9ec eb3db9d0 8004d4b0 80311644 8002b684 8002b51c 0000184d 0000184d
b9e0: eb3dba24 eb3db9f0 eb3dba0c 80023810 600001d3 ffffffff eb3dba44 80427b3c
ba00: eb3dbb44 eb3dba10 8000de98 800084f0 eb3dbaf4 00000024 00000000 00000000
ba20: 00000000 80415ba0 00000010 80427d10 80427b3c eb346000 80415ba0 eb3dbb44
ba40: 00000000 eb3dba58 00000000 80023810 600001d3 ffffffff eb926500 0000000a
ba60: eb3dba84 eb3dba70 eb3dbb90 00000002 00000000 00000000 00000000 00000000
ba80: 00000000 8020475c eb346000 eb3dba98 80017d90 00000000 80415ba0 80427ab0
baa0: 80415ba0 eb3dbab0 802048a4 00000000 00000000 00000000 00000000 00000000
bac0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
bae0: 00000000 00000000 00000000 00000000 00000000 00001f61 8042d8b4 8042d8b4
bb00: 00001f61 80443ae0 eb3dbb34 eb3dbb18 8004d4b0 80311644 8002b684 8166e0e4
bb20: eb2b2560 eb3da000 80427d10 eb2b26dc eb346000 00000000 eb3dbbc4 eb3dbb48
bb40: 80024240 8002374c 8166e0e4 eb3dbc0c eb3da000 00000002 eb3dbb8c 8166eba0
bb60: eb346000 80415ba0 8166e0e4 80427b3c 80427d10 80427d10 80415ba0 00000020
bb80: eb3dbbac 00000000 8001e5f0 8001ef20 ffffffb5 00000000 eb2b2560 8166eba0
bba0: eb2b2560 eb3da000 80427d10 eb2b26dc eb346000 00000000 eb3dbc3c eb3dbbc8
bbc0: 8030f5ac 80024198 eb3dbc0c 8042d8b4 eb2b2560 eb2b02d8 000bc20f 00000000
bbe0: 00000001 8041a080 80415ba0 80415ba0 ffff9442 00000006 fffffffc 80415ba0
bc00: 80415ba0 804150c0 eb3dbc2c 00000001 8030ed50 eb2b2560 0000000b 00000000
bc20: fffffffc eb3dbc9b 00000020 eb3da000 eb3dbc74 eb3dbc40 8002f534 8030ef88
bc40: eb3da000 00000000 fffffffc eb3dbc9b 00000020 fffffff8 eb3dbc74 eb3dbc68
bc60: 8002b50c fffffffc eb3dbcfc eb3dbc78 80011c88 8002ee9c eb3da2f0 0000000b
bc80: 00000004 7f000000 00000000 00000004 8039a080 8039a088 62000005 50206461
bca0: 61762043 0065756c eb3dbccc eb3dbcb8 8030ed50 8002bdd0 80000005 eb3dbcd4
bcc0: eb3dbcfc eb3dbce0 800147cc 8030ed38 803ad880 eb3dbe28 00000000 00000000
bce0: 80000005 eb0b8b60 eb0b8b98 eb2b2560 eb3dbd24 eb3dbd00 8001485c 800119fc
bd00: eb3dbe28 eb0b8b60 eb3dbe28 00000000 00010000 80000005 eb3dbd5c eb3dbd28
bd20: 800149c0 800147ec eb922d80 eb44fd30 00000000 80000005 8042af98 00000000
bd40: eb3dbe28 00000004 8001ef68 8001d8dc eb3dbd7c eb3dbd60 80014b74 80014878
bd60: 00000005 8042af98 00000000 eb3dbe28 eb3dbe24 eb3dbd80 800085c4 80014adc
bd80: 8032433c 00000000 eb3dbdac eb3dbd98 80074b6c 80074ad8 80074b48 fffffffa
bda0: eb90d9e0 00000000 eb3dbdec eb3dbdb8 80027170 80311644 00000001 40000093
bdc0: 800401b4 80027408 eb3dbdec eb3dbdd8 80040248 80040198 80415ba0 80415ba0
bde0: 8020add0 8020ad10 00000000 8048d5c0 0000003f 0000003e eb93a000 8048dee4
be00: eb8295a0 eb3da000 00000000 800001f3 ffffffff eb3dbe5c eb2b2560 eb3dbe28
be20: 8000e018 80008590 00000000 7b8f806a eb3dbe34 80012758 804865d0 eb0b8b60
be40: 00000000 00000003 00000004 8001ef68 8001d8dc eb2b2560 eb3dbe4c eb3dbe70
be60: 80010544 00000000 800001f3 ffffffff ffffffff 00000000 eb3dbeac eb3dbe88
be80: 8008adc8 8008a5f8 eb3dbeb4 eb3dbe98 801dbec0 eb0a01e0 eb406600 00000000
bea0: 00000000 00000003 eb3dbed4 eb3dbeb8 80063ffc 80063c78 0000006d eb321000
bec0: 8000e34c 8004d730 eb3dbee4 00000b04 800bc9e4 eb868140 ffffffff 00000000
bee0: eb3dbf70 eb8286c0 00000004 eb806bc0 eb3dbf0c eb3dbf00 801d7344 800633a8
bf00: eb3dbf2c 00000003 2aad7000 00000000 eb3da000 eb0b91e0 00000007 00001000
bf20: eb3dbf64 eb3dbf30 801dbff4 80311644 80000013 eb0b8b9c eb3da000 2aaeb000
bf40: 800a71ec 80025538 800aae40 eb181000 eb3dbfb0 00000000 eb3dbfb0 eb0df000
bf60: 00020000 00000000 00000024 00000100 02012080 00000008 02012080 00000005
bf80: 8000e504 00000000 eb3dbfa4 eb3dbf98 8009fb74 8009f9d8 00000000 eb3dbfa8
bfa0: 8000e380 8002f8a8 7e837d90 00000000 00000000 00000000 00a69008 00000000
bfc0: 00000004 2ab06000 2acb95f8 00000004 00000004 0201029c 00000001 00000000
bfe0: 00000004 7ebc0478 2ac0798c 2ac53e6c 60000010 00000001 00000000 00000000
Backtrace:
[<801dbb0c>] (rb_next+0x0/0x74) from [<80022230>] (pick_next_task_fair+0xd8/0x11
4)
[<80022158>] (pick_next_task_fair+0x0/0x114) from [<8030f450>] (schedule+0x4d4/0
x6a8)
 r7:80427d10 r6:eb3da000 r5:eb2b2560 r4:8166eba0
[<8030ef7c>] (schedule+0x0/0x6a8) from [<8002f534>] (do_exit+0x6a4/0x6f0)
[<8002ee90>] (do_exit+0x0/0x6f0) from [<80011c88>] (die+0x298/0x2ec)
 r7:00000001
[<800119f0>] (die+0x0/0x2ec) from [<8001485c>] (__do_kernel_fault+0x7c/0x8c)
[<800147e0>] (__do_kernel_fault+0x0/0x8c) from [<800149c0>] (do_page_fault+0x154
/0x1f8)
 r8:00000005 r7:00010000 r6:00000010 r5:eb3dba10 r4:eb0b8b60
r3:eb3dba10
[<8001486c>] (do_page_fault+0x0/0x1f8) from [<80014b74>] (do_translation_fault+0
xa4/0xa8)
[<80014ad0>] (do_translation_fault+0x0/0xa8) from [<80008520>] (do_DataAbort+0x3
c/0xa0)
 r7:00000005 r6:8042af48 r5:00000010 r4:00000005
[<800084e4>] (do_DataAbort+0x0/0xa0) from [<8000de98>] (__dabt_svc+0x38/0x60)
Exception stack(0xeb3dba10 to 0xeb3dba58)
ba00:                                     eb3dbaf4 00000024 00000000 00000000
ba20: 00000000 80415ba0 00000010 80427d10 80427b3c eb346000 80415ba0 eb3dbb44
ba40: 00000000 eb3dba58 00000000 80023810 600001d3 ffffffff
 r8:80427b3c r7:eb3dba44 r6:ffffffff r5:600001d3 r4:80023810
[<80023740>] (find_busiest_group+0x0/0xa4c) from [<80024240>] (load_balance+0xb4
/0x5ac)
[<8002418c>] (load_balance+0x0/0x5ac) from [<8030f5ac>] (schedule+0x630/0x6a8)
[<8030ef7c>] (schedule+0x0/0x6a8) from [<8002f534>] (do_exit+0x6a4/0x6f0)
[<8002ee90>] (do_exit+0x0/0x6f0) from [<80011c88>] (die+0x298/0x2ec)
 r7:fffffffc
[<800119f0>] (die+0x0/0x2ec) from [<8001485c>] (__do_kernel_fault+0x7c/0x8c)
[<800147e0>] (__do_kernel_fault+0x0/0x8c) from [<800149c0>] (do_page_fault+0x154
/0x1f8)
 r8:80000005 r7:00010000 r6:00000000 r5:eb3dbe28 r4:eb0b8b60
r3:eb3dbe28
[<8001486c>] (do_page_fault+0x0/0x1f8) from [<80014b74>] (do_translation_fault+0
xa4/0xa8)
[<80014ad0>] (do_translation_fault+0x0/0xa8) from [<800085c4>] (do_PrefetchAbort
+0x40/0xa4)
 r7:eb3dbe28 r6:00000000 r5:8042af98 r4:00000005
[<80008584>] (do_PrefetchAbort+0x0/0xa4) from [<8000e018>] (__pabt_svc+0x38/0x80
)
Exception stack(0xeb3dbe28 to 0xeb3dbe70)
be20:                   00000000 7b8f806a eb3dbe34 80012758 804865d0 eb0b8b60
be40: 00000000 00000003 00000004 8001ef68 8001d8dc eb2b2560 eb3dbe4c eb3dbe70
be60: 80010544 00000000 800001f3 ffffffff
 r7:eb3dbe5c r6:ffffffff r5:800001f3 r4:00000000
Backtrace aborted due to bad frame pointer <eb2b2560>
Code: e89da800 e1a0c00d e92dd800 e24cb004 (e5903000)
---[ end trace b4510fc09c2ffbd3 ]---
Fixing recursive fault but reboot is needed!

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [PATCH 08/11] ARM: pm: no need to save/restore context ID register
  2011-09-01 12:50   ` Russell King - ARM Linux
@ 2011-09-03 16:33     ` Santosh
  -1 siblings, 0 replies; 56+ messages in thread
From: Santosh @ 2011-09-03 16:33 UTC (permalink / raw)
  To: Russell King - ARM Linux; +Cc: linux-omap, linux-arm-kernel

On Thursday 01 September 2011 06:20 PM, Russell King - ARM Linux wrote:
> There is no need to save and restore the context ID register on ARMv6
> and ARMv7 with a temporary page table as we write the context ID
> register when we switch back to the real page tables for the thread.
>
> Moreover, the temporary page tables do not contain any non-global
> mappings, so the context ID value should not be used.  To be safe,
> initialize the register to a reserved context ID value.
>
> Signed-off-by: Russell King<rmk+kernel@arm.linux.org.uk>
> ---
>   arch/arm/mm/proc-v6.S |   33 ++++++++++++++++-----------------
>   arch/arm/mm/proc-v7.S |   13 ++++++-------
>   2 files changed, 22 insertions(+), 24 deletions(-)
>
> diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S
> index 2e27b46..a92c3c3 100644
> --- a/arch/arm/mm/proc-v6.S
> +++ b/arch/arm/mm/proc-v6.S
> @@ -128,19 +128,18 @@ ENTRY(cpu_v6_set_pte_ext)
>
>   /* Suspend/resume support: taken from arch/arm/mach-s3c64xx/sleep.S */
>   .globl	cpu_v6_suspend_size
> -.equ	cpu_v6_suspend_size, 4 * 7
> +.equ	cpu_v6_suspend_size, 4 * 6
>   #ifdef CONFIG_PM_SLEEP
>   ENTRY(cpu_v6_do_suspend)
> -	stmfd	sp!, {r4 - r10, lr}
> +	stmfd	sp!, {r4 - r9, lr}
>   	mrc	p15, 0, r4, c13, c0, 0	@ FCSE/PID
> -	mrc	p15, 0, r5, c13, c0, 1	@ Context ID
> -	mrc	p15, 0, r6, c3, c0, 0	@ Domain ID
> -	mrc	p15, 0, r7, c2, c0, 1	@ Translation table base 1
> -	mrc	p15, 0, r8, c1, c0, 1	@ auxiliary control register
> -	mrc	p15, 0, r9, c1, c0, 2	@ co-processor access control
> -	mrc	p15, 0, r10, c1, c0, 0	@ control register
> -	stmia	r0, {r4 - r10}
> -	ldmfd	sp!, {r4- r10, pc}
> +	mrc	p15, 0, r5, c3, c0, 0	@ Domain ID
> +	mrc	p15, 0, r6, c2, c0, 1	@ Translation table base 1
> +	mrc	p15, 0, r7, c1, c0, 1	@ auxiliary control register
> +	mrc	p15, 0, r8, c1, c0, 2	@ co-processor access control
> +	mrc	p15, 0, r9, c1, c0, 0	@ control register
> +	stmia	r0, {r4 - r9}
> +	ldmfd	sp!, {r4- r9, pc}
>   ENDPROC(cpu_v6_do_suspend)
>
>   ENTRY(cpu_v6_do_resume)
> @@ -149,19 +148,19 @@ ENTRY(cpu_v6_do_resume)
>   	mcr	p15, 0, ip, c7, c5, 0	@ invalidate I cache
>   	mcr	p15, 0, ip, c7, c15, 0	@ clean+invalidate cache
>   	mcr	p15, 0, ip, c7, c10, 4	@ drain write buffer
> -	ldmia	r0, {r4 - r10}
> +	mcr	p15, 0, ip, c13, 0, 1	@ set reserved context ID
Typo which results in build error.
Error: co-processor register expected -- `mcr p15,0,ip,c13,0,1'

You can fold below fix.

diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S
index 53bba9d..b3455c1 100644
--- a/arch/arm/mm/proc-v6.S
+++ b/arch/arm/mm/proc-v6.S
@@ -148,7 +148,7 @@ ENTRY(cpu_v6_do_resume)
  	mcr	p15, 0, ip, c7, c5, 0	@ invalidate I cache
  	mcr	p15, 0, ip, c7, c15, 0	@ clean+invalidate cache
  	mcr	p15, 0, ip, c7, c10, 4	@ drain write buffer
-	mcr	p15, 0, ip, c13, 0, 1	@ set reserved context ID
+	mcr	p15, 0, ip, c13, c0, 1	@ set reserved context ID
  	ldmia	r0, {r4 - r9}
  	mcr	p15, 0, r4, c13, c0, 0	@ FCSE/PID
  	mcr	p15, 0, r5, c3, c0, 0	@ Domain ID
-- 
1.7.4.1

Regards
Santosh

^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [PATCH 08/11] ARM: pm: no need to save/restore context ID register
@ 2011-09-03 16:33     ` Santosh
  0 siblings, 0 replies; 56+ messages in thread
From: Santosh @ 2011-09-03 16:33 UTC (permalink / raw)
  To: linux-arm-kernel

On Thursday 01 September 2011 06:20 PM, Russell King - ARM Linux wrote:
> There is no need to save and restore the context ID register on ARMv6
> and ARMv7 with a temporary page table as we write the context ID
> register when we switch back to the real page tables for the thread.
>
> Moreover, the temporary page tables do not contain any non-global
> mappings, so the context ID value should not be used.  To be safe,
> initialize the register to a reserved context ID value.
>
> Signed-off-by: Russell King<rmk+kernel@arm.linux.org.uk>
> ---
>   arch/arm/mm/proc-v6.S |   33 ++++++++++++++++-----------------
>   arch/arm/mm/proc-v7.S |   13 ++++++-------
>   2 files changed, 22 insertions(+), 24 deletions(-)
>
> diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S
> index 2e27b46..a92c3c3 100644
> --- a/arch/arm/mm/proc-v6.S
> +++ b/arch/arm/mm/proc-v6.S
> @@ -128,19 +128,18 @@ ENTRY(cpu_v6_set_pte_ext)
>
>   /* Suspend/resume support: taken from arch/arm/mach-s3c64xx/sleep.S */
>   .globl	cpu_v6_suspend_size
> -.equ	cpu_v6_suspend_size, 4 * 7
> +.equ	cpu_v6_suspend_size, 4 * 6
>   #ifdef CONFIG_PM_SLEEP
>   ENTRY(cpu_v6_do_suspend)
> -	stmfd	sp!, {r4 - r10, lr}
> +	stmfd	sp!, {r4 - r9, lr}
>   	mrc	p15, 0, r4, c13, c0, 0	@ FCSE/PID
> -	mrc	p15, 0, r5, c13, c0, 1	@ Context ID
> -	mrc	p15, 0, r6, c3, c0, 0	@ Domain ID
> -	mrc	p15, 0, r7, c2, c0, 1	@ Translation table base 1
> -	mrc	p15, 0, r8, c1, c0, 1	@ auxiliary control register
> -	mrc	p15, 0, r9, c1, c0, 2	@ co-processor access control
> -	mrc	p15, 0, r10, c1, c0, 0	@ control register
> -	stmia	r0, {r4 - r10}
> -	ldmfd	sp!, {r4- r10, pc}
> +	mrc	p15, 0, r5, c3, c0, 0	@ Domain ID
> +	mrc	p15, 0, r6, c2, c0, 1	@ Translation table base 1
> +	mrc	p15, 0, r7, c1, c0, 1	@ auxiliary control register
> +	mrc	p15, 0, r8, c1, c0, 2	@ co-processor access control
> +	mrc	p15, 0, r9, c1, c0, 0	@ control register
> +	stmia	r0, {r4 - r9}
> +	ldmfd	sp!, {r4- r9, pc}
>   ENDPROC(cpu_v6_do_suspend)
>
>   ENTRY(cpu_v6_do_resume)
> @@ -149,19 +148,19 @@ ENTRY(cpu_v6_do_resume)
>   	mcr	p15, 0, ip, c7, c5, 0	@ invalidate I cache
>   	mcr	p15, 0, ip, c7, c15, 0	@ clean+invalidate cache
>   	mcr	p15, 0, ip, c7, c10, 4	@ drain write buffer
> -	ldmia	r0, {r4 - r10}
> +	mcr	p15, 0, ip, c13, 0, 1	@ set reserved context ID
Typo which results in build error.
Error: co-processor register expected -- `mcr p15,0,ip,c13,0,1'

You can fold below fix.

diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S
index 53bba9d..b3455c1 100644
--- a/arch/arm/mm/proc-v6.S
+++ b/arch/arm/mm/proc-v6.S
@@ -148,7 +148,7 @@ ENTRY(cpu_v6_do_resume)
  	mcr	p15, 0, ip, c7, c5, 0	@ invalidate I cache
  	mcr	p15, 0, ip, c7, c15, 0	@ clean+invalidate cache
  	mcr	p15, 0, ip, c7, c10, 4	@ drain write buffer
-	mcr	p15, 0, ip, c13, 0, 1	@ set reserved context ID
+	mcr	p15, 0, ip, c13, c0, 1	@ set reserved context ID
  	ldmia	r0, {r4 - r9}
  	mcr	p15, 0, r4, c13, c0, 0	@ FCSE/PID
  	mcr	p15, 0, r5, c3, c0, 0	@ Domain ID
-- 
1.7.4.1

Regards
Santosh

^ permalink raw reply related	[flat|nested] 56+ messages in thread

* Re: [PATCH 00/11] Add L2 cache cleaning to generic CPU suspend
  2011-09-01 12:47 ` Russell King - ARM Linux
@ 2011-09-03 16:36   ` Santosh
  -1 siblings, 0 replies; 56+ messages in thread
From: Santosh @ 2011-09-03 16:36 UTC (permalink / raw)
  To: Russell King - ARM Linux; +Cc: linux-arm-kernel, linux-omap

On Thursday 01 September 2011 06:17 PM, Russell King - ARM Linux wrote:
> Some systems (such as OMAP) preserve the L2 cache across a suspend/
> resume cycle.  This means they do not perform L2 cache maintanence
> in their suspend finisher function.
>
> However, the side effect is that the saved CPU state is not readable
> by the resume code because it is sitting in the L2 cache.
>
> This patch series adds L2 cache cleaning to the generic CPU suspend/
> resume support code, making it possible to use this on systems with
> L2 cache enabled without having to clean/invalidate the entire L2
> cache.
>
> We also add a separate page table, allocated at boot time, for the
> resume process to use so we don't have to fiddle about with tweaking
> entries in the current processes page table.  Moreover, the current
> processes page table may be in use by another CPU in the system if
> these paths are used from cpuidle or hotplug, so changing the page
> table is technically unsound.
>
> Overall, this makes it possible for OMAP4 systems to use this code.
>
> The first four patches in this set are already merged into Linus' tree
> as bug fixes, and are included here for completeness given that the
> kernel.org infrastructure is currently offline.
>
> This has (so far) only been tested on OMAP4.  Further testing on OMAP3
> and Assabet will follow.

Thanks a lot Russell for this series. I have tested the entire series
with OMAP4 S2R and CPUIDLE and it works great.

Tested-by: Santosh Shilimkar <santosh.shilimkar@ti.com>

Regards
Santosh


^ permalink raw reply	[flat|nested] 56+ messages in thread

* [PATCH 00/11] Add L2 cache cleaning to generic CPU suspend
@ 2011-09-03 16:36   ` Santosh
  0 siblings, 0 replies; 56+ messages in thread
From: Santosh @ 2011-09-03 16:36 UTC (permalink / raw)
  To: linux-arm-kernel

On Thursday 01 September 2011 06:17 PM, Russell King - ARM Linux wrote:
> Some systems (such as OMAP) preserve the L2 cache across a suspend/
> resume cycle.  This means they do not perform L2 cache maintanence
> in their suspend finisher function.
>
> However, the side effect is that the saved CPU state is not readable
> by the resume code because it is sitting in the L2 cache.
>
> This patch series adds L2 cache cleaning to the generic CPU suspend/
> resume support code, making it possible to use this on systems with
> L2 cache enabled without having to clean/invalidate the entire L2
> cache.
>
> We also add a separate page table, allocated at boot time, for the
> resume process to use so we don't have to fiddle about with tweaking
> entries in the current processes page table.  Moreover, the current
> processes page table may be in use by another CPU in the system if
> these paths are used from cpuidle or hotplug, so changing the page
> table is technically unsound.
>
> Overall, this makes it possible for OMAP4 systems to use this code.
>
> The first four patches in this set are already merged into Linus' tree
> as bug fixes, and are included here for completeness given that the
> kernel.org infrastructure is currently offline.
>
> This has (so far) only been tested on OMAP4.  Further testing on OMAP3
> and Assabet will follow.

Thanks a lot Russell for this series. I have tested the entire series
with OMAP4 S2R and CPUIDLE and it works great.

Tested-by: Santosh Shilimkar <santosh.shilimkar@ti.com>

Regards
Santosh

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [PATCH 08/11] ARM: pm: no need to save/restore context ID register
  2011-09-03 16:33     ` Santosh
@ 2011-09-04 10:08       ` Russell King - ARM Linux
  -1 siblings, 0 replies; 56+ messages in thread
From: Russell King - ARM Linux @ 2011-09-04 10:08 UTC (permalink / raw)
  To: Santosh; +Cc: linux-omap, linux-arm-kernel

On Sat, Sep 03, 2011 at 10:03:00PM +0530, Santosh wrote:
> Typo which results in build error.
> Error: co-processor register expected -- `mcr p15,0,ip,c13,0,1'
>
> You can fold below fix.

Kevin already reported this, and I've already folded this fix in.  Thanks.

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [PATCH 08/11] ARM: pm: no need to save/restore context ID register
@ 2011-09-04 10:08       ` Russell King - ARM Linux
  0 siblings, 0 replies; 56+ messages in thread
From: Russell King - ARM Linux @ 2011-09-04 10:08 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Sep 03, 2011 at 10:03:00PM +0530, Santosh wrote:
> Typo which results in build error.
> Error: co-processor register expected -- `mcr p15,0,ip,c13,0,1'
>
> You can fold below fix.

Kevin already reported this, and I've already folded this fix in.  Thanks.

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [PATCH 00/11] Add L2 cache cleaning to generic CPU suspend
  2011-09-03 16:36   ` Santosh
@ 2011-09-04 10:12     ` Russell King - ARM Linux
  -1 siblings, 0 replies; 56+ messages in thread
From: Russell King - ARM Linux @ 2011-09-04 10:12 UTC (permalink / raw)
  To: Santosh; +Cc: linux-arm-kernel, linux-omap

On Sat, Sep 03, 2011 at 10:06:38PM +0530, Santosh wrote:
> Thanks a lot Russell for this series. I have tested the entire series
> with OMAP4 S2R and CPUIDLE and it works great.
>
> Tested-by: Santosh Shilimkar <santosh.shilimkar@ti.com>

Thanks.  I've merged added that to the non-fixes stuff (which Linus
hasn't pulled) and the series into the for-next branch.

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [PATCH 00/11] Add L2 cache cleaning to generic CPU suspend
@ 2011-09-04 10:12     ` Russell King - ARM Linux
  0 siblings, 0 replies; 56+ messages in thread
From: Russell King - ARM Linux @ 2011-09-04 10:12 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Sep 03, 2011 at 10:06:38PM +0530, Santosh wrote:
> Thanks a lot Russell for this series. I have tested the entire series
> with OMAP4 S2R and CPUIDLE and it works great.
>
> Tested-by: Santosh Shilimkar <santosh.shilimkar@ti.com>

Thanks.  I've merged added that to the non-fixes stuff (which Linus
hasn't pulled) and the series into the for-next branch.

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [PATCH 03/11] ARM: pm: some ARMv7 requires a dsb in resume to ensure correctness
  2011-09-01 12:49   ` Russell King - ARM Linux
@ 2011-09-07 15:41     ` Catalin Marinas
  -1 siblings, 0 replies; 56+ messages in thread
From: Catalin Marinas @ 2011-09-07 15:41 UTC (permalink / raw)
  To: Russell King - ARM Linux; +Cc: linux-omap, Santosh Shilimkar, linux-arm-kernel

On 1 September 2011 13:49, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> Add a dsb after the isb to ensure that the previous writes to the
> CP15 registers take effect before we enable the MMU.
>
> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
> ---
>  arch/arm/mm/proc-v7.S |    1 +
>  1 files changed, 1 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
> index dec72ee..a773f4e 100644
> --- a/arch/arm/mm/proc-v7.S
> +++ b/arch/arm/mm/proc-v7.S
> @@ -255,6 +255,7 @@ ENTRY(cpu_v7_do_resume)
>        mcr     p15, 0, r4, c10, c2, 0  @ write PRRR
>        mcr     p15, 0, r5, c10, c2, 1  @ write NMRR
>        isb
> +       dsb

Isn't an ISB enough here? We usually have the DSB for some background
operations like cache maintenance.

-- 
Catalin

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [PATCH 03/11] ARM: pm: some ARMv7 requires a dsb in resume to ensure correctness
@ 2011-09-07 15:41     ` Catalin Marinas
  0 siblings, 0 replies; 56+ messages in thread
From: Catalin Marinas @ 2011-09-07 15:41 UTC (permalink / raw)
  To: linux-arm-kernel

On 1 September 2011 13:49, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> Add a dsb after the isb to ensure that the previous writes to the
> CP15 registers take effect before we enable the MMU.
>
> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
> ---
> ?arch/arm/mm/proc-v7.S | ? ?1 +
> ?1 files changed, 1 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
> index dec72ee..a773f4e 100644
> --- a/arch/arm/mm/proc-v7.S
> +++ b/arch/arm/mm/proc-v7.S
> @@ -255,6 +255,7 @@ ENTRY(cpu_v7_do_resume)
> ? ? ? ?mcr ? ? p15, 0, r4, c10, c2, 0 ?@ write PRRR
> ? ? ? ?mcr ? ? p15, 0, r5, c10, c2, 1 ?@ write NMRR
> ? ? ? ?isb
> + ? ? ? dsb

Isn't an ISB enough here? We usually have the DSB for some background
operations like cache maintenance.

-- 
Catalin

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [PATCH 10/11] ARM: pm: convert some assembly to C
  2011-09-01 12:51   ` Russell King - ARM Linux
@ 2011-09-07 15:48     ` Lorenzo Pieralisi
  -1 siblings, 0 replies; 56+ messages in thread
From: Lorenzo Pieralisi @ 2011-09-07 15:48 UTC (permalink / raw)
  To: Russell King - ARM Linux; +Cc: linux-omap, Santosh Shilimkar, linux-arm-kernel

Hi Russell,

On Thu, Sep 01, 2011 at 01:51:39PM +0100, Russell King - ARM Linux wrote:
> Convert some of the sleep.S guts to C code, which makes it easier to
> use our macros and to add L2 cache handling.  We provide a helper
> function, __cpu_suspend_save(), which deals with saving the common
> state, setting up for resume, and flushing caches.
> 
> The remainder left as assembly code is the saving of the CPU general
> purpose registers, and allocating space on the stack to save the CPU
> specific registers and resume state.
> 
> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
> ---
>  arch/arm/include/asm/proc-fns.h |    8 ++++++
>  arch/arm/kernel/sleep.S         |   53 ++++++++++++--------------------------
>  arch/arm/kernel/suspend.c       |   24 +++++++++++++++--
>  3 files changed, 46 insertions(+), 39 deletions(-)
> 

[...]

> diff --git a/arch/arm/kernel/suspend.c b/arch/arm/kernel/suspend.c
> index 115736a..c78a88f 100644
> --- a/arch/arm/kernel/suspend.c
> +++ b/arch/arm/kernel/suspend.c
> @@ -8,10 +8,29 @@
>  
>  static pgd_t *suspend_pgd;
>  
> -extern int __cpu_suspend(int, long, unsigned long, int (*)(unsigned long));
> +extern int __cpu_suspend(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.
>   */
> @@ -29,8 +48,7 @@ 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(virt_to_phys(suspend_pgd),
> -			    PHYS_OFFSET - PAGE_OFFSET, arg, fn);
> +	ret = __cpu_suspend(arg, fn);
>  	if (ret == 0)
>  		cpu_switch_mm(mm->pgd, mm);

It is still early testing, but without a local tlb flush here I am getting
random segmentation faults in user space.
My fear is that 1:1 global TLB entries cause issues if user space processes 
happen to map those pages at addresses overlapping 1:1 mapping set-up for 
resume and we do not flush the TLB.

With the tlb flush the whole patchset works with nary a blemish, from cpuidle. 

Still a question mark so please give me the benefit of the doubt.

Many thanks,
Lorenzo

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [PATCH 10/11] ARM: pm: convert some assembly to C
@ 2011-09-07 15:48     ` Lorenzo Pieralisi
  0 siblings, 0 replies; 56+ messages in thread
From: Lorenzo Pieralisi @ 2011-09-07 15:48 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Russell,

On Thu, Sep 01, 2011 at 01:51:39PM +0100, Russell King - ARM Linux wrote:
> Convert some of the sleep.S guts to C code, which makes it easier to
> use our macros and to add L2 cache handling.  We provide a helper
> function, __cpu_suspend_save(), which deals with saving the common
> state, setting up for resume, and flushing caches.
> 
> The remainder left as assembly code is the saving of the CPU general
> purpose registers, and allocating space on the stack to save the CPU
> specific registers and resume state.
> 
> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
> ---
>  arch/arm/include/asm/proc-fns.h |    8 ++++++
>  arch/arm/kernel/sleep.S         |   53 ++++++++++++--------------------------
>  arch/arm/kernel/suspend.c       |   24 +++++++++++++++--
>  3 files changed, 46 insertions(+), 39 deletions(-)
> 

[...]

> diff --git a/arch/arm/kernel/suspend.c b/arch/arm/kernel/suspend.c
> index 115736a..c78a88f 100644
> --- a/arch/arm/kernel/suspend.c
> +++ b/arch/arm/kernel/suspend.c
> @@ -8,10 +8,29 @@
>  
>  static pgd_t *suspend_pgd;
>  
> -extern int __cpu_suspend(int, long, unsigned long, int (*)(unsigned long));
> +extern int __cpu_suspend(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.
>   */
> @@ -29,8 +48,7 @@ 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(virt_to_phys(suspend_pgd),
> -			    PHYS_OFFSET - PAGE_OFFSET, arg, fn);
> +	ret = __cpu_suspend(arg, fn);
>  	if (ret == 0)
>  		cpu_switch_mm(mm->pgd, mm);

It is still early testing, but without a local tlb flush here I am getting
random segmentation faults in user space.
My fear is that 1:1 global TLB entries cause issues if user space processes 
happen to map those pages at addresses overlapping 1:1 mapping set-up for 
resume and we do not flush the TLB.

With the tlb flush the whole patchset works with nary a blemish, from cpuidle. 

Still a question mark so please give me the benefit of the doubt.

Many thanks,
Lorenzo

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [PATCH 03/11] ARM: pm: some ARMv7 requires a dsb in resume to ensure correctness
  2011-09-07 15:41     ` Catalin Marinas
@ 2011-09-07 16:19       ` Russell King - ARM Linux
  -1 siblings, 0 replies; 56+ messages in thread
From: Russell King - ARM Linux @ 2011-09-07 16:19 UTC (permalink / raw)
  To: Catalin Marinas; +Cc: linux-omap, Santosh Shilimkar, linux-arm-kernel

On Wed, Sep 07, 2011 at 04:41:32PM +0100, Catalin Marinas wrote:
> On 1 September 2011 13:49, Russell King - ARM Linux
> <linux@arm.linux.org.uk> wrote:
> > Add a dsb after the isb to ensure that the previous writes to the
> > CP15 registers take effect before we enable the MMU.
> >
> > Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
> > ---
> >  arch/arm/mm/proc-v7.S |    1 +
> >  1 files changed, 1 insertions(+), 0 deletions(-)
> >
> > diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
> > index dec72ee..a773f4e 100644
> > --- a/arch/arm/mm/proc-v7.S
> > +++ b/arch/arm/mm/proc-v7.S
> > @@ -255,6 +255,7 @@ ENTRY(cpu_v7_do_resume)
> >        mcr     p15, 0, r4, c10, c2, 0  @ write PRRR
> >        mcr     p15, 0, r5, c10, c2, 1  @ write NMRR
> >        isb
> > +       dsb
> 
> Isn't an ISB enough here? We usually have the DSB for some background
> operations like cache maintenance.

That depends whether you're including the effects of the cache
maintanence instructions in this.  The ARM ARM tells me that
a DSB is required to ensure that all cache maintanence is issued
before the dsb is complete at the point that the dsb is executed.

So for architectural compliance, yes, a dsb is required.  The isb
is also required to ensure that instruction cache maintanence is
properly visible.

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [PATCH 03/11] ARM: pm: some ARMv7 requires a dsb in resume to ensure correctness
@ 2011-09-07 16:19       ` Russell King - ARM Linux
  0 siblings, 0 replies; 56+ messages in thread
From: Russell King - ARM Linux @ 2011-09-07 16:19 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Sep 07, 2011 at 04:41:32PM +0100, Catalin Marinas wrote:
> On 1 September 2011 13:49, Russell King - ARM Linux
> <linux@arm.linux.org.uk> wrote:
> > Add a dsb after the isb to ensure that the previous writes to the
> > CP15 registers take effect before we enable the MMU.
> >
> > Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
> > ---
> > ?arch/arm/mm/proc-v7.S | ? ?1 +
> > ?1 files changed, 1 insertions(+), 0 deletions(-)
> >
> > diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
> > index dec72ee..a773f4e 100644
> > --- a/arch/arm/mm/proc-v7.S
> > +++ b/arch/arm/mm/proc-v7.S
> > @@ -255,6 +255,7 @@ ENTRY(cpu_v7_do_resume)
> > ? ? ? ?mcr ? ? p15, 0, r4, c10, c2, 0 ?@ write PRRR
> > ? ? ? ?mcr ? ? p15, 0, r5, c10, c2, 1 ?@ write NMRR
> > ? ? ? ?isb
> > + ? ? ? dsb
> 
> Isn't an ISB enough here? We usually have the DSB for some background
> operations like cache maintenance.

That depends whether you're including the effects of the cache
maintanence instructions in this.  The ARM ARM tells me that
a DSB is required to ensure that all cache maintanence is issued
before the dsb is complete at the point that the dsb is executed.

So for architectural compliance, yes, a dsb is required.  The isb
is also required to ensure that instruction cache maintanence is
properly visible.

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [PATCH 03/11] ARM: pm: some ARMv7 requires a dsb in resume to ensure correctness
  2011-09-07 16:19       ` Russell King - ARM Linux
@ 2011-09-07 16:26         ` Catalin Marinas
  -1 siblings, 0 replies; 56+ messages in thread
From: Catalin Marinas @ 2011-09-07 16:26 UTC (permalink / raw)
  To: Russell King - ARM Linux; +Cc: linux-omap, Santosh Shilimkar, linux-arm-kernel

On 7 September 2011 17:19, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> On Wed, Sep 07, 2011 at 04:41:32PM +0100, Catalin Marinas wrote:
>> On 1 September 2011 13:49, Russell King - ARM Linux
>> <linux@arm.linux.org.uk> wrote:
>> > Add a dsb after the isb to ensure that the previous writes to the
>> > CP15 registers take effect before we enable the MMU.
>> >
>> > Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
>> > ---
>> >  arch/arm/mm/proc-v7.S |    1 +
>> >  1 files changed, 1 insertions(+), 0 deletions(-)
>> >
>> > diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
>> > index dec72ee..a773f4e 100644
>> > --- a/arch/arm/mm/proc-v7.S
>> > +++ b/arch/arm/mm/proc-v7.S
>> > @@ -255,6 +255,7 @@ ENTRY(cpu_v7_do_resume)
>> >        mcr     p15, 0, r4, c10, c2, 0  @ write PRRR
>> >        mcr     p15, 0, r5, c10, c2, 1  @ write NMRR
>> >        isb
>> > +       dsb
>>
>> Isn't an ISB enough here? We usually have the DSB for some background
>> operations like cache maintenance.
>
> That depends whether you're including the effects of the cache
> maintanence instructions in this.  The ARM ARM tells me that
> a DSB is required to ensure that all cache maintanence is issued
> before the dsb is complete at the point that the dsb is executed.
>
> So for architectural compliance, yes, a dsb is required.  The isb
> is also required to ensure that instruction cache maintanence is
> properly visible.

That's correct, I got the wrong impression that there was a DSB
earlier in the code after he TLB and cache maintenance, but that's not
the case, so a DSB here is needed.

-- 
Catalin
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [PATCH 03/11] ARM: pm: some ARMv7 requires a dsb in resume to ensure correctness
@ 2011-09-07 16:26         ` Catalin Marinas
  0 siblings, 0 replies; 56+ messages in thread
From: Catalin Marinas @ 2011-09-07 16:26 UTC (permalink / raw)
  To: linux-arm-kernel

On 7 September 2011 17:19, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> On Wed, Sep 07, 2011 at 04:41:32PM +0100, Catalin Marinas wrote:
>> On 1 September 2011 13:49, Russell King - ARM Linux
>> <linux@arm.linux.org.uk> wrote:
>> > Add a dsb after the isb to ensure that the previous writes to the
>> > CP15 registers take effect before we enable the MMU.
>> >
>> > Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
>> > ---
>> > ?arch/arm/mm/proc-v7.S | ? ?1 +
>> > ?1 files changed, 1 insertions(+), 0 deletions(-)
>> >
>> > diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
>> > index dec72ee..a773f4e 100644
>> > --- a/arch/arm/mm/proc-v7.S
>> > +++ b/arch/arm/mm/proc-v7.S
>> > @@ -255,6 +255,7 @@ ENTRY(cpu_v7_do_resume)
>> > ? ? ? ?mcr ? ? p15, 0, r4, c10, c2, 0 ?@ write PRRR
>> > ? ? ? ?mcr ? ? p15, 0, r5, c10, c2, 1 ?@ write NMRR
>> > ? ? ? ?isb
>> > + ? ? ? dsb
>>
>> Isn't an ISB enough here? We usually have the DSB for some background
>> operations like cache maintenance.
>
> That depends whether you're including the effects of the cache
> maintanence instructions in this. ?The ARM ARM tells me that
> a DSB is required to ensure that all cache maintanence is issued
> before the dsb is complete at the point that the dsb is executed.
>
> So for architectural compliance, yes, a dsb is required. ?The isb
> is also required to ensure that instruction cache maintanence is
> properly visible.

That's correct, I got the wrong impression that there was a DSB
earlier in the code after he TLB and cache maintenance, but that's not
the case, so a DSB here is needed.

-- 
Catalin

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [PATCH 03/11] ARM: pm: some ARMv7 requires a dsb in resume to ensure correctness
  2011-09-07 16:19       ` Russell King - ARM Linux
@ 2011-09-07 16:54         ` Catalin Marinas
  -1 siblings, 0 replies; 56+ messages in thread
From: Catalin Marinas @ 2011-09-07 16:54 UTC (permalink / raw)
  To: Russell King - ARM Linux; +Cc: linux-omap, Santosh Shilimkar, linux-arm-kernel

On 7 September 2011 17:19, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> On Wed, Sep 07, 2011 at 04:41:32PM +0100, Catalin Marinas wrote:
>> On 1 September 2011 13:49, Russell King - ARM Linux
>> <linux@arm.linux.org.uk> wrote:
>> > Add a dsb after the isb to ensure that the previous writes to the
>> > CP15 registers take effect before we enable the MMU.
>> >
>> > Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
>> > ---
>> >  arch/arm/mm/proc-v7.S |    1 +
>> >  1 files changed, 1 insertions(+), 0 deletions(-)
>> >
>> > diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
>> > index dec72ee..a773f4e 100644
>> > --- a/arch/arm/mm/proc-v7.S
>> > +++ b/arch/arm/mm/proc-v7.S
>> > @@ -255,6 +255,7 @@ ENTRY(cpu_v7_do_resume)
>> >        mcr     p15, 0, r4, c10, c2, 0  @ write PRRR
>> >        mcr     p15, 0, r5, c10, c2, 1  @ write NMRR
>> >        isb
>> > +       dsb
>>
>> Isn't an ISB enough here? We usually have the DSB for some background
>> operations like cache maintenance.
>
> That depends whether you're including the effects of the cache
> maintanence instructions in this.  The ARM ARM tells me that
> a DSB is required to ensure that all cache maintanence is issued
> before the dsb is complete at the point that the dsb is executed.

Another minor point, in general we would use the DSB before the ISB
(but that's when the I-cache is enabled).

-- 
Catalin
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [PATCH 03/11] ARM: pm: some ARMv7 requires a dsb in resume to ensure correctness
@ 2011-09-07 16:54         ` Catalin Marinas
  0 siblings, 0 replies; 56+ messages in thread
From: Catalin Marinas @ 2011-09-07 16:54 UTC (permalink / raw)
  To: linux-arm-kernel

On 7 September 2011 17:19, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> On Wed, Sep 07, 2011 at 04:41:32PM +0100, Catalin Marinas wrote:
>> On 1 September 2011 13:49, Russell King - ARM Linux
>> <linux@arm.linux.org.uk> wrote:
>> > Add a dsb after the isb to ensure that the previous writes to the
>> > CP15 registers take effect before we enable the MMU.
>> >
>> > Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
>> > ---
>> > ?arch/arm/mm/proc-v7.S | ? ?1 +
>> > ?1 files changed, 1 insertions(+), 0 deletions(-)
>> >
>> > diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
>> > index dec72ee..a773f4e 100644
>> > --- a/arch/arm/mm/proc-v7.S
>> > +++ b/arch/arm/mm/proc-v7.S
>> > @@ -255,6 +255,7 @@ ENTRY(cpu_v7_do_resume)
>> > ? ? ? ?mcr ? ? p15, 0, r4, c10, c2, 0 ?@ write PRRR
>> > ? ? ? ?mcr ? ? p15, 0, r5, c10, c2, 1 ?@ write NMRR
>> > ? ? ? ?isb
>> > + ? ? ? dsb
>>
>> Isn't an ISB enough here? We usually have the DSB for some background
>> operations like cache maintenance.
>
> That depends whether you're including the effects of the cache
> maintanence instructions in this. ?The ARM ARM tells me that
> a DSB is required to ensure that all cache maintanence is issued
> before the dsb is complete at the point that the dsb is executed.

Another minor point, in general we would use the DSB before the ISB
(but that's when the I-cache is enabled).

-- 
Catalin

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [PATCH 00/11] Add L2 cache cleaning to generic CPU suspend
  2011-09-01 15:57       ` Shawn Guo
@ 2011-09-10 16:10         ` Shawn Guo
  -1 siblings, 0 replies; 56+ messages in thread
From: Shawn Guo @ 2011-09-10 16:10 UTC (permalink / raw)
  To: Russell King - ARM Linux; +Cc: linux-omap, Santosh Shilimkar, linux-arm-kernel

On Thu, Sep 01, 2011 at 11:57:54PM +0800, Shawn Guo wrote:
> On Thu, Sep 01, 2011 at 04:34:51PM +0100, Russell King - ARM Linux wrote:
> > On Thu, Sep 01, 2011 at 11:33:43PM +0800, Shawn Guo wrote:
> > > This is also the case on i.MX6Q, which L2 cache is retained during a
> > > suspend/resume cycle.  Currently, I have to call into the following
> > > before calling generic cpu_suspend() to clean/invalidate the entire
> > > L2 cache.
> > > 
> > > 	outer_flush_all();
> > > 	outer_disable();
> > > 
> > > But there is a wired thing on using generic cpu_resume().  I have to
> > > invalidate L1 before calling into cpu_resume() like below.
> > > 
> > > ENTRY(imx6q_cpu_resume)
> > >         bl      v7_invalidate_l1
> > >         b       cpu_resume
> > > ENDPROC(imx6q_cpu_resume)
> > > 
> > > ENTRY(imx6q_secondary_startup)
> > >         bl      v7_invalidate_l1
> > >         b       secondary_startup
> > > ENDPROC(imx6q_secondary_startup)
> > > 
> > > The v7_invalidate_l1() is the function copied from mach-tegra/headsmp.S,
> > > which has to be called before calling secondary_startup to boot
> > > secondary cores (same situation between Tegra and i.MX6Q).
> > 
> > Presumably that's because your L1 cache contains randomized data with
> > random validity (and presumably random dirtyness) at boot time - something
> > which unfortunately the ARM ARM permits.  I don't think we can go to the
> > extent of dealing with this in the generic code as it would unnecessarily
> > perturb those implementations which either the boot loader has already
> > sorted out that issue, or which don't have the issue at all.
> > 
> Yes, agreed.  It seems that Tegra and i.MX6Q are the only two CA9MP
> cases here.  But is it possible to maintain this v7_invalidate_l1()
> function in cache-v7.S, so that we do not need to duplicate it in
> platform codes?
> 
> > > Before applying this patch series, I have something like below actually
> > > working.
> > > 
> > > 
> > > 	outer_flush_all();
> > > 	outer_disable();
> > > 	imx_set_cpu_jump(0, imx6q_cpu_resume);
> > > 	/* Zzz ... */
> > > 	cpu_suspend(0, imx6q_suspend_finish);
> > > 
> > > I expect with you patches applied, I can still have it work with simply
> > > removing those two lines outer cache codes.
> > 
> > That should be the case.
> > 
> > > But unfortunately, I'm
> > > running into Oops when resuming back.  And I also have Oops with
> > > imx_set_cpu_jump(0, cpu_resume) which means skipping the
> > > v7_invalidate_l1() and calling generic cpu_resume() only.
> > 
> > Do you have a copy of the oops?
> > 
> 
Hi Russell,

After following your great debugging clue that we need to enable L2
before calling into generic cpu_resume(), now this patch series works
great for imx6q.  Thanks a lot, and here is my tag.

Tested-by: Shawn Guo <shawn.guo@linaro.org>

-- 
Regards,
Shawn


^ permalink raw reply	[flat|nested] 56+ messages in thread

* [PATCH 00/11] Add L2 cache cleaning to generic CPU suspend
@ 2011-09-10 16:10         ` Shawn Guo
  0 siblings, 0 replies; 56+ messages in thread
From: Shawn Guo @ 2011-09-10 16:10 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Sep 01, 2011 at 11:57:54PM +0800, Shawn Guo wrote:
> On Thu, Sep 01, 2011 at 04:34:51PM +0100, Russell King - ARM Linux wrote:
> > On Thu, Sep 01, 2011 at 11:33:43PM +0800, Shawn Guo wrote:
> > > This is also the case on i.MX6Q, which L2 cache is retained during a
> > > suspend/resume cycle.  Currently, I have to call into the following
> > > before calling generic cpu_suspend() to clean/invalidate the entire
> > > L2 cache.
> > > 
> > > 	outer_flush_all();
> > > 	outer_disable();
> > > 
> > > But there is a wired thing on using generic cpu_resume().  I have to
> > > invalidate L1 before calling into cpu_resume() like below.
> > > 
> > > ENTRY(imx6q_cpu_resume)
> > >         bl      v7_invalidate_l1
> > >         b       cpu_resume
> > > ENDPROC(imx6q_cpu_resume)
> > > 
> > > ENTRY(imx6q_secondary_startup)
> > >         bl      v7_invalidate_l1
> > >         b       secondary_startup
> > > ENDPROC(imx6q_secondary_startup)
> > > 
> > > The v7_invalidate_l1() is the function copied from mach-tegra/headsmp.S,
> > > which has to be called before calling secondary_startup to boot
> > > secondary cores (same situation between Tegra and i.MX6Q).
> > 
> > Presumably that's because your L1 cache contains randomized data with
> > random validity (and presumably random dirtyness) at boot time - something
> > which unfortunately the ARM ARM permits.  I don't think we can go to the
> > extent of dealing with this in the generic code as it would unnecessarily
> > perturb those implementations which either the boot loader has already
> > sorted out that issue, or which don't have the issue at all.
> > 
> Yes, agreed.  It seems that Tegra and i.MX6Q are the only two CA9MP
> cases here.  But is it possible to maintain this v7_invalidate_l1()
> function in cache-v7.S, so that we do not need to duplicate it in
> platform codes?
> 
> > > Before applying this patch series, I have something like below actually
> > > working.
> > > 
> > > 
> > > 	outer_flush_all();
> > > 	outer_disable();
> > > 	imx_set_cpu_jump(0, imx6q_cpu_resume);
> > > 	/* Zzz ... */
> > > 	cpu_suspend(0, imx6q_suspend_finish);
> > > 
> > > I expect with you patches applied, I can still have it work with simply
> > > removing those two lines outer cache codes.
> > 
> > That should be the case.
> > 
> > > But unfortunately, I'm
> > > running into Oops when resuming back.  And I also have Oops with
> > > imx_set_cpu_jump(0, cpu_resume) which means skipping the
> > > v7_invalidate_l1() and calling generic cpu_resume() only.
> > 
> > Do you have a copy of the oops?
> > 
> 
Hi Russell,

After following your great debugging clue that we need to enable L2
before calling into generic cpu_resume(), now this patch series works
great for imx6q.  Thanks a lot, and here is my tag.

Tested-by: Shawn Guo <shawn.guo@linaro.org>

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [PATCH 00/11] Add L2 cache cleaning to generic CPU suspend
  2011-09-10 16:10         ` Shawn Guo
@ 2011-09-19 16:22           ` Russell King - ARM Linux
  -1 siblings, 0 replies; 56+ messages in thread
From: Russell King - ARM Linux @ 2011-09-19 16:22 UTC (permalink / raw)
  To: Shawn Guo; +Cc: linux-omap, Santosh Shilimkar, linux-arm-kernel

On Sun, Sep 11, 2011 at 12:10:04AM +0800, Shawn Guo wrote:
> On Thu, Sep 01, 2011 at 11:57:54PM +0800, Shawn Guo wrote:
> > On Thu, Sep 01, 2011 at 04:34:51PM +0100, Russell King - ARM Linux wrote:
> > > On Thu, Sep 01, 2011 at 11:33:43PM +0800, Shawn Guo wrote:
> > > > This is also the case on i.MX6Q, which L2 cache is retained during a
> > > > suspend/resume cycle.  Currently, I have to call into the following
> > > > before calling generic cpu_suspend() to clean/invalidate the entire
> > > > L2 cache.
> > > > 
> > > > 	outer_flush_all();
> > > > 	outer_disable();
> > > > 
> > > > But there is a wired thing on using generic cpu_resume().  I have to
> > > > invalidate L1 before calling into cpu_resume() like below.
> > > > 
> > > > ENTRY(imx6q_cpu_resume)
> > > >         bl      v7_invalidate_l1
> > > >         b       cpu_resume
> > > > ENDPROC(imx6q_cpu_resume)
> > > > 
> > > > ENTRY(imx6q_secondary_startup)
> > > >         bl      v7_invalidate_l1
> > > >         b       secondary_startup
> > > > ENDPROC(imx6q_secondary_startup)
> > > > 
> > > > The v7_invalidate_l1() is the function copied from mach-tegra/headsmp.S,
> > > > which has to be called before calling secondary_startup to boot
> > > > secondary cores (same situation between Tegra and i.MX6Q).
> > > 
> > > Presumably that's because your L1 cache contains randomized data with
> > > random validity (and presumably random dirtyness) at boot time - something
> > > which unfortunately the ARM ARM permits.  I don't think we can go to the
> > > extent of dealing with this in the generic code as it would unnecessarily
> > > perturb those implementations which either the boot loader has already
> > > sorted out that issue, or which don't have the issue at all.
> > > 
> > Yes, agreed.  It seems that Tegra and i.MX6Q are the only two CA9MP
> > cases here.  But is it possible to maintain this v7_invalidate_l1()
> > function in cache-v7.S, so that we do not need to duplicate it in
> > platform codes?
> > 
> > > > Before applying this patch series, I have something like below actually
> > > > working.
> > > > 
> > > > 
> > > > 	outer_flush_all();
> > > > 	outer_disable();
> > > > 	imx_set_cpu_jump(0, imx6q_cpu_resume);
> > > > 	/* Zzz ... */
> > > > 	cpu_suspend(0, imx6q_suspend_finish);
> > > > 
> > > > I expect with you patches applied, I can still have it work with simply
> > > > removing those two lines outer cache codes.
> > > 
> > > That should be the case.
> > > 
> > > > But unfortunately, I'm
> > > > running into Oops when resuming back.  And I also have Oops with
> > > > imx_set_cpu_jump(0, cpu_resume) which means skipping the
> > > > v7_invalidate_l1() and calling generic cpu_resume() only.
> > > 
> > > Do you have a copy of the oops?
> > > 
> > 
> Hi Russell,
> 
> After following your great debugging clue that we need to enable L2
> before calling into generic cpu_resume(), now this patch series works
> great for imx6q.  Thanks a lot, and here is my tag.
> 
> Tested-by: Shawn Guo <shawn.guo@linaro.org>

Is that for all these patches?

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [PATCH 00/11] Add L2 cache cleaning to generic CPU suspend
@ 2011-09-19 16:22           ` Russell King - ARM Linux
  0 siblings, 0 replies; 56+ messages in thread
From: Russell King - ARM Linux @ 2011-09-19 16:22 UTC (permalink / raw)
  To: linux-arm-kernel

On Sun, Sep 11, 2011 at 12:10:04AM +0800, Shawn Guo wrote:
> On Thu, Sep 01, 2011 at 11:57:54PM +0800, Shawn Guo wrote:
> > On Thu, Sep 01, 2011 at 04:34:51PM +0100, Russell King - ARM Linux wrote:
> > > On Thu, Sep 01, 2011 at 11:33:43PM +0800, Shawn Guo wrote:
> > > > This is also the case on i.MX6Q, which L2 cache is retained during a
> > > > suspend/resume cycle.  Currently, I have to call into the following
> > > > before calling generic cpu_suspend() to clean/invalidate the entire
> > > > L2 cache.
> > > > 
> > > > 	outer_flush_all();
> > > > 	outer_disable();
> > > > 
> > > > But there is a wired thing on using generic cpu_resume().  I have to
> > > > invalidate L1 before calling into cpu_resume() like below.
> > > > 
> > > > ENTRY(imx6q_cpu_resume)
> > > >         bl      v7_invalidate_l1
> > > >         b       cpu_resume
> > > > ENDPROC(imx6q_cpu_resume)
> > > > 
> > > > ENTRY(imx6q_secondary_startup)
> > > >         bl      v7_invalidate_l1
> > > >         b       secondary_startup
> > > > ENDPROC(imx6q_secondary_startup)
> > > > 
> > > > The v7_invalidate_l1() is the function copied from mach-tegra/headsmp.S,
> > > > which has to be called before calling secondary_startup to boot
> > > > secondary cores (same situation between Tegra and i.MX6Q).
> > > 
> > > Presumably that's because your L1 cache contains randomized data with
> > > random validity (and presumably random dirtyness) at boot time - something
> > > which unfortunately the ARM ARM permits.  I don't think we can go to the
> > > extent of dealing with this in the generic code as it would unnecessarily
> > > perturb those implementations which either the boot loader has already
> > > sorted out that issue, or which don't have the issue at all.
> > > 
> > Yes, agreed.  It seems that Tegra and i.MX6Q are the only two CA9MP
> > cases here.  But is it possible to maintain this v7_invalidate_l1()
> > function in cache-v7.S, so that we do not need to duplicate it in
> > platform codes?
> > 
> > > > Before applying this patch series, I have something like below actually
> > > > working.
> > > > 
> > > > 
> > > > 	outer_flush_all();
> > > > 	outer_disable();
> > > > 	imx_set_cpu_jump(0, imx6q_cpu_resume);
> > > > 	/* Zzz ... */
> > > > 	cpu_suspend(0, imx6q_suspend_finish);
> > > > 
> > > > I expect with you patches applied, I can still have it work with simply
> > > > removing those two lines outer cache codes.
> > > 
> > > That should be the case.
> > > 
> > > > But unfortunately, I'm
> > > > running into Oops when resuming back.  And I also have Oops with
> > > > imx_set_cpu_jump(0, cpu_resume) which means skipping the
> > > > v7_invalidate_l1() and calling generic cpu_resume() only.
> > > 
> > > Do you have a copy of the oops?
> > > 
> > 
> Hi Russell,
> 
> After following your great debugging clue that we need to enable L2
> before calling into generic cpu_resume(), now this patch series works
> great for imx6q.  Thanks a lot, and here is my tag.
> 
> Tested-by: Shawn Guo <shawn.guo@linaro.org>

Is that for all these patches?

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [PATCH 10/11] ARM: pm: convert some assembly to C
  2011-09-07 15:48     ` Lorenzo Pieralisi
@ 2011-09-19 16:32       ` Russell King - ARM Linux
  -1 siblings, 0 replies; 56+ messages in thread
From: Russell King - ARM Linux @ 2011-09-19 16:32 UTC (permalink / raw)
  To: Lorenzo Pieralisi; +Cc: Santosh Shilimkar, linux-omap, linux-arm-kernel

On Wed, Sep 07, 2011 at 04:48:28PM +0100, Lorenzo Pieralisi wrote:
> > @@ -29,8 +48,7 @@ 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(virt_to_phys(suspend_pgd),
> > -			    PHYS_OFFSET - PAGE_OFFSET, arg, fn);
> > +	ret = __cpu_suspend(arg, fn);
> >  	if (ret == 0)
> >  		cpu_switch_mm(mm->pgd, mm);
> 
> It is still early testing, but without a local tlb flush here I am getting
> random segmentation faults in user space.
> My fear is that 1:1 global TLB entries cause issues if user space processes 
> happen to map those pages at addresses overlapping 1:1 mapping set-up for 
> resume and we do not flush the TLB.

Yes, having the global TLB entry potentially in userspace is a problem.
I don't think we can get around this any other way than by calling
local_flush_tlb_all() here.  I'll post an updated series shortly.

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [PATCH 10/11] ARM: pm: convert some assembly to C
@ 2011-09-19 16:32       ` Russell King - ARM Linux
  0 siblings, 0 replies; 56+ messages in thread
From: Russell King - ARM Linux @ 2011-09-19 16:32 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Sep 07, 2011 at 04:48:28PM +0100, Lorenzo Pieralisi wrote:
> > @@ -29,8 +48,7 @@ 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(virt_to_phys(suspend_pgd),
> > -			    PHYS_OFFSET - PAGE_OFFSET, arg, fn);
> > +	ret = __cpu_suspend(arg, fn);
> >  	if (ret == 0)
> >  		cpu_switch_mm(mm->pgd, mm);
> 
> It is still early testing, but without a local tlb flush here I am getting
> random segmentation faults in user space.
> My fear is that 1:1 global TLB entries cause issues if user space processes 
> happen to map those pages at addresses overlapping 1:1 mapping set-up for 
> resume and we do not flush the TLB.

Yes, having the global TLB entry potentially in userspace is a problem.
I don't think we can get around this any other way than by calling
local_flush_tlb_all() here.  I'll post an updated series shortly.

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [PATCH 00/11] Add L2 cache cleaning to generic CPU suspend
  2011-09-19 16:22           ` Russell King - ARM Linux
@ 2011-09-20  3:24             ` Shawn Guo
  -1 siblings, 0 replies; 56+ messages in thread
From: Shawn Guo @ 2011-09-20  3:24 UTC (permalink / raw)
  To: Russell King - ARM Linux; +Cc: linux-omap, Santosh Shilimkar, linux-arm-kernel

On Mon, Sep 19, 2011 at 05:22:22PM +0100, Russell King - ARM Linux wrote:
> On Sun, Sep 11, 2011 at 12:10:04AM +0800, Shawn Guo wrote:
> > On Thu, Sep 01, 2011 at 11:57:54PM +0800, Shawn Guo wrote:
> > > On Thu, Sep 01, 2011 at 04:34:51PM +0100, Russell King - ARM Linux wrote:
> > > > On Thu, Sep 01, 2011 at 11:33:43PM +0800, Shawn Guo wrote:
> > > > > This is also the case on i.MX6Q, which L2 cache is retained during a
> > > > > suspend/resume cycle.  Currently, I have to call into the following
> > > > > before calling generic cpu_suspend() to clean/invalidate the entire
> > > > > L2 cache.
> > > > > 
> > > > > 	outer_flush_all();
> > > > > 	outer_disable();
> > > > > 
> > > > > But there is a wired thing on using generic cpu_resume().  I have to
> > > > > invalidate L1 before calling into cpu_resume() like below.
> > > > > 
> > > > > ENTRY(imx6q_cpu_resume)
> > > > >         bl      v7_invalidate_l1
> > > > >         b       cpu_resume
> > > > > ENDPROC(imx6q_cpu_resume)
> > > > > 
> > > > > ENTRY(imx6q_secondary_startup)
> > > > >         bl      v7_invalidate_l1
> > > > >         b       secondary_startup
> > > > > ENDPROC(imx6q_secondary_startup)
> > > > > 
> > > > > The v7_invalidate_l1() is the function copied from mach-tegra/headsmp.S,
> > > > > which has to be called before calling secondary_startup to boot
> > > > > secondary cores (same situation between Tegra and i.MX6Q).
> > > > 
> > > > Presumably that's because your L1 cache contains randomized data with
> > > > random validity (and presumably random dirtyness) at boot time - something
> > > > which unfortunately the ARM ARM permits.  I don't think we can go to the
> > > > extent of dealing with this in the generic code as it would unnecessarily
> > > > perturb those implementations which either the boot loader has already
> > > > sorted out that issue, or which don't have the issue at all.
> > > > 
> > > Yes, agreed.  It seems that Tegra and i.MX6Q are the only two CA9MP
> > > cases here.  But is it possible to maintain this v7_invalidate_l1()
> > > function in cache-v7.S, so that we do not need to duplicate it in
> > > platform codes?
> > > 
> > > > > Before applying this patch series, I have something like below actually
> > > > > working.
> > > > > 
> > > > > 
> > > > > 	outer_flush_all();
> > > > > 	outer_disable();
> > > > > 	imx_set_cpu_jump(0, imx6q_cpu_resume);
> > > > > 	/* Zzz ... */
> > > > > 	cpu_suspend(0, imx6q_suspend_finish);
> > > > > 
> > > > > I expect with you patches applied, I can still have it work with simply
> > > > > removing those two lines outer cache codes.
> > > > 
> > > > That should be the case.
> > > > 
> > > > > But unfortunately, I'm
> > > > > running into Oops when resuming back.  And I also have Oops with
> > > > > imx_set_cpu_jump(0, cpu_resume) which means skipping the
> > > > > v7_invalidate_l1() and calling generic cpu_resume() only.
> > > > 
> > > > Do you have a copy of the oops?
> > > > 
> > > 
> > Hi Russell,
> > 
> > After following your great debugging clue that we need to enable L2
> > before calling into generic cpu_resume(), now this patch series works
> > great for imx6q.  Thanks a lot, and here is my tag.
> > 
> > Tested-by: Shawn Guo <shawn.guo@linaro.org>
> 
> Is that for all these patches?
> 
Yes, it is.

-- 
Regards,
Shawn


^ permalink raw reply	[flat|nested] 56+ messages in thread

* [PATCH 00/11] Add L2 cache cleaning to generic CPU suspend
@ 2011-09-20  3:24             ` Shawn Guo
  0 siblings, 0 replies; 56+ messages in thread
From: Shawn Guo @ 2011-09-20  3:24 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Sep 19, 2011 at 05:22:22PM +0100, Russell King - ARM Linux wrote:
> On Sun, Sep 11, 2011 at 12:10:04AM +0800, Shawn Guo wrote:
> > On Thu, Sep 01, 2011 at 11:57:54PM +0800, Shawn Guo wrote:
> > > On Thu, Sep 01, 2011 at 04:34:51PM +0100, Russell King - ARM Linux wrote:
> > > > On Thu, Sep 01, 2011 at 11:33:43PM +0800, Shawn Guo wrote:
> > > > > This is also the case on i.MX6Q, which L2 cache is retained during a
> > > > > suspend/resume cycle.  Currently, I have to call into the following
> > > > > before calling generic cpu_suspend() to clean/invalidate the entire
> > > > > L2 cache.
> > > > > 
> > > > > 	outer_flush_all();
> > > > > 	outer_disable();
> > > > > 
> > > > > But there is a wired thing on using generic cpu_resume().  I have to
> > > > > invalidate L1 before calling into cpu_resume() like below.
> > > > > 
> > > > > ENTRY(imx6q_cpu_resume)
> > > > >         bl      v7_invalidate_l1
> > > > >         b       cpu_resume
> > > > > ENDPROC(imx6q_cpu_resume)
> > > > > 
> > > > > ENTRY(imx6q_secondary_startup)
> > > > >         bl      v7_invalidate_l1
> > > > >         b       secondary_startup
> > > > > ENDPROC(imx6q_secondary_startup)
> > > > > 
> > > > > The v7_invalidate_l1() is the function copied from mach-tegra/headsmp.S,
> > > > > which has to be called before calling secondary_startup to boot
> > > > > secondary cores (same situation between Tegra and i.MX6Q).
> > > > 
> > > > Presumably that's because your L1 cache contains randomized data with
> > > > random validity (and presumably random dirtyness) at boot time - something
> > > > which unfortunately the ARM ARM permits.  I don't think we can go to the
> > > > extent of dealing with this in the generic code as it would unnecessarily
> > > > perturb those implementations which either the boot loader has already
> > > > sorted out that issue, or which don't have the issue at all.
> > > > 
> > > Yes, agreed.  It seems that Tegra and i.MX6Q are the only two CA9MP
> > > cases here.  But is it possible to maintain this v7_invalidate_l1()
> > > function in cache-v7.S, so that we do not need to duplicate it in
> > > platform codes?
> > > 
> > > > > Before applying this patch series, I have something like below actually
> > > > > working.
> > > > > 
> > > > > 
> > > > > 	outer_flush_all();
> > > > > 	outer_disable();
> > > > > 	imx_set_cpu_jump(0, imx6q_cpu_resume);
> > > > > 	/* Zzz ... */
> > > > > 	cpu_suspend(0, imx6q_suspend_finish);
> > > > > 
> > > > > I expect with you patches applied, I can still have it work with simply
> > > > > removing those two lines outer cache codes.
> > > > 
> > > > That should be the case.
> > > > 
> > > > > But unfortunately, I'm
> > > > > running into Oops when resuming back.  And I also have Oops with
> > > > > imx_set_cpu_jump(0, cpu_resume) which means skipping the
> > > > > v7_invalidate_l1() and calling generic cpu_resume() only.
> > > > 
> > > > Do you have a copy of the oops?
> > > > 
> > > 
> > Hi Russell,
> > 
> > After following your great debugging clue that we need to enable L2
> > before calling into generic cpu_resume(), now this patch series works
> > great for imx6q.  Thanks a lot, and here is my tag.
> > 
> > Tested-by: Shawn Guo <shawn.guo@linaro.org>
> 
> Is that for all these patches?
> 
Yes, it is.

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 56+ messages in thread

end of thread, other threads:[~2011-09-20  3:24 UTC | newest]

Thread overview: 56+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-09-01 12:47 [PATCH 00/11] Add L2 cache cleaning to generic CPU suspend Russell King - ARM Linux
2011-09-01 12:47 ` Russell King - ARM Linux
2011-09-01 12:48 ` [PATCH 01/11] ARM: pm: CPU specific code should not overwrite r1 (v:p offset) Russell King - ARM Linux
2011-09-01 12:48   ` Russell King - ARM Linux
2011-09-01 12:48 ` [PATCH 02/11] ARM: pm: arm920/926: fix number of registers saved Russell King - ARM Linux
2011-09-01 12:48   ` Russell King - ARM Linux
2011-09-01 12:49 ` [PATCH 03/11] ARM: pm: some ARMv7 requires a dsb in resume to ensure correctness Russell King - ARM Linux
2011-09-01 12:49   ` Russell King - ARM Linux
2011-09-07 15:41   ` Catalin Marinas
2011-09-07 15:41     ` Catalin Marinas
2011-09-07 16:19     ` Russell King - ARM Linux
2011-09-07 16:19       ` Russell King - ARM Linux
2011-09-07 16:26       ` Catalin Marinas
2011-09-07 16:26         ` Catalin Marinas
2011-09-07 16:54       ` Catalin Marinas
2011-09-07 16:54         ` Catalin Marinas
2011-09-01 12:49 ` [PATCH 04/11] ARM: pm: avoid writing the auxillary control register for ARMv7 Russell King - ARM Linux
2011-09-01 12:49   ` Russell King - ARM Linux
2011-09-01 12:49 ` [PATCH 05/11] ARM: pm: force non-zero return value from __cpu_suspend when aborting Russell King - ARM Linux
2011-09-01 12:49   ` Russell King - ARM Linux
2011-09-01 12:50 ` [PATCH 06/11] ARM: pm: preallocate a page table for suspend/resume Russell King - ARM Linux
2011-09-01 12:50   ` Russell King - ARM Linux
2011-09-01 12:50 ` [PATCH 07/11] ARM: pm: only use preallocated page table during resume Russell King - ARM Linux
2011-09-01 12:50   ` Russell King - ARM Linux
2011-09-01 12:50 ` [PATCH 08/11] ARM: pm: no need to save/restore context ID register Russell King - ARM Linux
2011-09-01 12:50   ` Russell King - ARM Linux
2011-09-03 16:33   ` Santosh
2011-09-03 16:33     ` Santosh
2011-09-04 10:08     ` Russell King - ARM Linux
2011-09-04 10:08       ` Russell King - ARM Linux
2011-09-01 12:51 ` [PATCH 09/11] ARM: pm: get rid of cpu_resume_turn_mmu_on Russell King - ARM Linux
2011-09-01 12:51   ` Russell King - ARM Linux
2011-09-01 12:51 ` [PATCH 10/11] ARM: pm: convert some assembly to C Russell King - ARM Linux
2011-09-01 12:51   ` Russell King - ARM Linux
2011-09-07 15:48   ` Lorenzo Pieralisi
2011-09-07 15:48     ` Lorenzo Pieralisi
2011-09-19 16:32     ` Russell King - ARM Linux
2011-09-19 16:32       ` Russell King - ARM Linux
2011-09-01 12:51 ` [PATCH 11/11] ARM: pm: add L2 cache cleaning for suspend Russell King - ARM Linux
2011-09-01 12:51   ` Russell King - ARM Linux
2011-09-01 15:33 ` [PATCH 00/11] Add L2 cache cleaning to generic CPU suspend Shawn Guo
2011-09-01 15:33   ` Shawn Guo
2011-09-01 15:34   ` Russell King - ARM Linux
2011-09-01 15:34     ` Russell King - ARM Linux
2011-09-01 15:57     ` Shawn Guo
2011-09-01 15:57       ` Shawn Guo
2011-09-10 16:10       ` Shawn Guo
2011-09-10 16:10         ` Shawn Guo
2011-09-19 16:22         ` Russell King - ARM Linux
2011-09-19 16:22           ` Russell King - ARM Linux
2011-09-20  3:24           ` Shawn Guo
2011-09-20  3:24             ` Shawn Guo
2011-09-03 16:36 ` Santosh
2011-09-03 16:36   ` Santosh
2011-09-04 10:12   ` Russell King - ARM Linux
2011-09-04 10:12     ` Russell King - ARM Linux

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.