Commit a560643e authored by Paul Mackerras's avatar Paul Mackerras

[POWERPC] Defer processing of interrupts when the CPU wakes from sleep mode

This provides a way to defer processing of an interrupt that wakes the
processor out of sleep mode.  On 32-bit platforms that use an
interrupt to wake the processor, we have to have interrupts enabled in
hardware at the point where we go to sleep, otherwise the processor
will never wake up.  However, because interrupts are logically
disabled at this point, we don't want to process the interrupt
straight away.

This is handled by setting the _TLF_SLEEPING flag.  When we get an
interrupt and _TLF_SLEEPING is set, we firstly clear the MSR_EE
(external interrupt enable) bit in the saved MSR value, and secondly
we then return to the address in the link register, like we do for
_TLF_NAPPING, but without actually handling the interrupt.

Note that this is handled somewhat differently on powerbooks, so this
new code will only be used on non-Apple machines.
Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
parent fcff474e
...@@ -147,6 +147,7 @@ transfer_to_handler: ...@@ -147,6 +147,7 @@ transfer_to_handler:
lwz r12,TI_LOCAL_FLAGS(r9) lwz r12,TI_LOCAL_FLAGS(r9)
mtcrf 0x01,r12 mtcrf 0x01,r12
bt- 31-TLF_NAPPING,4f bt- 31-TLF_NAPPING,4f
bt- 31-TLF_SLEEPING,7f
#endif /* CONFIG_6xx */ #endif /* CONFIG_6xx */
.globl transfer_to_handler_cont .globl transfer_to_handler_cont
transfer_to_handler_cont: transfer_to_handler_cont:
...@@ -164,6 +165,13 @@ transfer_to_handler_cont: ...@@ -164,6 +165,13 @@ transfer_to_handler_cont:
4: rlwinm r12,r12,0,~_TLF_NAPPING 4: rlwinm r12,r12,0,~_TLF_NAPPING
stw r12,TI_LOCAL_FLAGS(r9) stw r12,TI_LOCAL_FLAGS(r9)
b power_save_6xx_restore b power_save_6xx_restore
7: rlwinm r12,r12,0,~_TLF_SLEEPING
stw r12,TI_LOCAL_FLAGS(r9)
lwz r9,_MSR(r11) /* if sleeping, clear MSR.EE */
rlwinm r9,r9,0,~MSR_EE
lwz r12,_LINK(r11) /* and return to address in LR */
b fast_exception_return
#endif #endif
/* /*
......
...@@ -144,9 +144,11 @@ static inline struct thread_info *current_thread_info(void) ...@@ -144,9 +144,11 @@ static inline struct thread_info *current_thread_info(void)
/* Bits in local_flags */ /* Bits in local_flags */
/* Don't move TLF_NAPPING without adjusting the code in entry_32.S */ /* Don't move TLF_NAPPING without adjusting the code in entry_32.S */
#define TLF_NAPPING 0 /* idle thread enabled NAP mode */ #define TLF_NAPPING 0 /* idle thread enabled NAP mode */
#define TLF_RESTORE_SIGMASK 1 /* Restore signal mask in do_signal */ #define TLF_SLEEPING 1 /* suspend code enabled SLEEP mode */
#define TLF_RESTORE_SIGMASK 2 /* Restore signal mask in do_signal */
#define _TLF_NAPPING (1 << TLF_NAPPING) #define _TLF_NAPPING (1 << TLF_NAPPING)
#define _TLF_SLEEPING (1 << TLF_SLEEPING)
#define _TLF_RESTORE_SIGMASK (1 << TLF_RESTORE_SIGMASK) #define _TLF_RESTORE_SIGMASK (1 << TLF_RESTORE_SIGMASK)
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment