[PATCH 2/3] pm: Handle HID0_SLEEP in the TLF_NAPPING hack.
Scott Wood
scottwood at freescale.com
Thu Sep 6 08:06:38 EST 2007
The e300 core (and probably most other 6xx chips) can only come out of
sleep mode with an interrupt. However, interrupts are logically disabled
by the power management layer.
This hack extends the existing doze/nap hack to also suppress the running
of the interrupt handler when in sleep mode.
Signed-off-by: Scott Wood <scottwood at freescale.com>
---
arch/powerpc/kernel/idle_6xx.S | 40 +++++++++++++++++++++++++++++++++++++---
1 files changed, 37 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/kernel/idle_6xx.S b/arch/powerpc/kernel/idle_6xx.S
index 01bcd52..d176042 100644
--- a/arch/powerpc/kernel/idle_6xx.S
+++ b/arch/powerpc/kernel/idle_6xx.S
@@ -147,6 +147,12 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
isync
b 1b
+#ifdef CONFIG_SUSPEND
+ret_from_sleep:
+ .long ret_from_except
+ .long ret_from_except
+#endif
+
/*
* Return from NAP/DOZE mode, restore some CPU specific registers,
* we are called with DR/IR still off and r2 containing physical
@@ -154,7 +160,33 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
* address). We have to preserve r10.
*/
_GLOBAL(power_save_6xx_restore)
- lwz r9,_LINK(r11) /* interrupted in ppc6xx_idle: */
+#ifdef CONFIG_SUSPEND
+ mfspr r8, SPRN_HID0
+ andis. r9, r8, HID0_SLEEP at h
+ beq+ 1f
+
+ /*
+ * SLEEP mode is invoked through the PM subsystem, which means
+ * that interrupts should be disabled. However, the hardware
+ * requires them to be enabled to wake up. To prevent the
+ * interrupt from being visible to Linux, return immediately
+ * rather than run the interrupt handler.
+ */
+ lis r9, ret_from_sleep at h
+ ori r9, r9, ret_from_sleep at l
+ tophys(r9, r9)
+ mtlr r9
+
+ /*
+ * Disable interrupts, so that the interrupt doesn't happen
+ * again until the PM code sets MSR[EE].
+ */
+ lwz r9, _MSR(r11)
+ rlwinm r9, r9, 0, ~MSR_EE
+ stw r9, _MSR(r11)
+#endif
+
+1: lwz r9,_LINK(r11) /* interrupted in ppc6xx_idle: */
stw r9,_NIP(r11) /* make it do a blr */
#ifdef CONFIG_SMP
@@ -168,8 +200,10 @@ _GLOBAL(power_save_6xx_restore)
* and load r11 (@ha part + CPU offset) only once
*/
BEGIN_FTR_SECTION
- mfspr r9,SPRN_HID0
- andis. r9,r9,HID0_NAP at h
+#ifndef CONFIG_SUSPEND
+ mfspr r8,SPRN_HID0
+#endif
+ andis. r9,r8,HID0_NAP at h
beq 1f
addis r9,r11,(nap_save_msscr0-KERNELBASE)@ha
lwz r9,nap_save_msscr0 at l(r9)
--
1.5.3
More information about the Linuxppc-dev
mailing list