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 <[EMAIL PROTECTED]>
---
 arch/powerpc/kernel/idle_6xx.S |   34 +++++++++++++++++++++++++++++++++-
 1 files changed, 33 insertions(+), 1 deletions(-)

diff --git a/arch/powerpc/kernel/idle_6xx.S b/arch/powerpc/kernel/idle_6xx.S
index 01bcd52..f45d634 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_PM
+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_PM
+       mfspr   r9, SPRN_HID0
+       andis.  r9, r9, [EMAIL PROTECTED]
+       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, [EMAIL PROTECTED]
+       ori     r9, r9, [EMAIL PROTECTED]
+       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
-- 
1.5.0.3

_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev

Reply via email to