aboutsummaryrefslogtreecommitdiff
path: root/arch/powerpc/kernel/idle_e500.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel/idle_e500.S')
-rw-r--r--arch/powerpc/kernel/idle_e500.S17
1 files changed, 15 insertions, 2 deletions
diff --git a/arch/powerpc/kernel/idle_e500.S b/arch/powerpc/kernel/idle_e500.S
index 06304034b39..15448668988 100644
--- a/arch/powerpc/kernel/idle_e500.S
+++ b/arch/powerpc/kernel/idle_e500.S
@@ -21,11 +21,22 @@
.text
_GLOBAL(e500_idle)
- rlwinm r3,r1,0,0,31-THREAD_SHIFT /* current thread_info */
+ CURRENT_THREAD_INFO(r3, r1)
lwz r4,TI_LOCAL_FLAGS(r3) /* set napping bit */
ori r4,r4,_TLF_NAPPING /* so when we take an exception */
stw r4,TI_LOCAL_FLAGS(r3) /* it will return to our caller */
+#ifdef CONFIG_PPC_E500MC
+ wrteei 1
+1: wait
+
+ /*
+ * Guard against spurious wakeups (e.g. from a hypervisor) --
+ * any real interrupt will cause us to return to LR due to
+ * _TLF_NAPPING.
+ */
+ b 1b
+#else
/* Check if we can nap or doze, put HID0 mask in r3 */
lis r3,0
BEGIN_FTR_SECTION
@@ -72,6 +83,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_L2CSR|CPU_FTR_CAN_NAP)
mtmsr r7
isync
2: b 2b
+#endif /* !E500MC */
/*
* Return from NAP/DOZE mode, restore some CPU specific registers,
@@ -84,10 +96,11 @@ _GLOBAL(power_save_ppc32_restore)
stw r9,_NIP(r11) /* make it do a blr */
#ifdef CONFIG_SMP
- mfspr r12,SPRN_SPRG3
+ CURRENT_THREAD_INFO(r12, r1)
lwz r11,TI_CPU(r12) /* get cpu number * 4 */
slwi r11,r11,2
#else
li r11,0
#endif
+
b transfer_to_handler_cont