diff options
author | Ian Munsie <imunsie@au1.ibm.com> | 2012-11-14 13:49:48 -0500 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2013-01-09 23:09:07 -0500 |
commit | fe9e1d54e3ea2e5134d7aaa233441f9229326ef6 (patch) | |
tree | b8347ea44bef6ad8c8a615a26a9a8124745f50f3 /arch/powerpc/kernel/irq.c | |
parent | 919ca8681f48ce81848c76f0ed66edb1bb99209b (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.c | 11 |
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 ! */ |