aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/irq.c
diff options
context:
space:
mode:
authorIan Munsie <imunsie@au1.ibm.com>2012-11-14 13:49:48 -0500
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2013-01-09 23:09:07 -0500
commitfe9e1d54e3ea2e5134d7aaa233441f9229326ef6 (patch)
treeb8347ea44bef6ad8c8a615a26a9a8124745f50f3 /arch/powerpc/kernel/irq.c
parent919ca8681f48ce81848c76f0ed66edb1bb99209b (diff)
powerpc: Add code to handle soft-disabled doorbells on server
This patch adds the logic to properly handle doorbells that come in when interrupts have been soft disabled and to replay them when interrupts are re-enabled: - masked_##_H##interrupt is modified to leave interrupts enabled when a doorbell has come in since doorbells are edge sensitive and as such won't be automatically re-raised. - __check_irq_replay now tests if a doorbell happened on book3s, and returns either 0xe80 or 0xa00 depending on whether we are the hypervisor or not. - restore_check_irq_replay now tests for the two possible server doorbell vector numbers to replay. - __replay_interrupt also adds tests for the two server doorbell vector numbers, and is modified to use a compare instruction rather than an andi. on the single bit difference between 0x500 and 0x900. The last two use a CPU feature section to avoid needlessly testing against the hypervisor vector if it is not the hypervisor, and vice versa. Signed-off-by: Ian Munsie <imunsie@au1.ibm.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/kernel/irq.c')
-rw-r--r--arch/powerpc/kernel/irq.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 71413f41278f..4f97fe345526 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -122,8 +122,8 @@ static inline notrace int decrementer_check_overflow(void)
122} 122}
123 123
124/* This is called whenever we are re-enabling interrupts 124/* This is called whenever we are re-enabling interrupts
125 * and returns either 0 (nothing to do) or 500/900 if there's 125 * and returns either 0 (nothing to do) or 500/900/280/a00/e80 if
126 * either an EE or a DEC to generate. 126 * there's an EE, DEC or DBELL to generate.
127 * 127 *
128 * This is called in two contexts: From arch_local_irq_restore() 128 * This is called in two contexts: From arch_local_irq_restore()
129 * before soft-enabling interrupts, and from the exception exit 129 * before soft-enabling interrupts, and from the exception exit
@@ -182,6 +182,13 @@ notrace unsigned int __check_irq_replay(void)
182 local_paca->irq_happened &= ~PACA_IRQ_DBELL; 182 local_paca->irq_happened &= ~PACA_IRQ_DBELL;
183 if (happened & PACA_IRQ_DBELL) 183 if (happened & PACA_IRQ_DBELL)
184 return 0x280; 184 return 0x280;
185#else
186 local_paca->irq_happened &= ~PACA_IRQ_DBELL;
187 if (happened & PACA_IRQ_DBELL) {
188 if (cpu_has_feature(CPU_FTR_HVMODE))
189 return 0xe80;
190 return 0xa00;
191 }
185#endif /* CONFIG_PPC_BOOK3E */ 192#endif /* CONFIG_PPC_BOOK3E */
186 193
187 /* There should be nothing left ! */ 194 /* There should be nothing left ! */