aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/sysdev/mpic.c
diff options
context:
space:
mode:
authorMichael Ellerman <michael@ellerman.id.au>2009-07-05 12:08:52 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2009-08-19 20:12:22 -0400
commit11a6b292c1bc9cb39970e44edd6958250f23d3a8 (patch)
treeac23c82f0739ad7521b531f570305d2a306c7651 /arch/powerpc/sysdev/mpic.c
parent66dc3304f3875ea85c630a57a88ecf79032890c4 (diff)
powerpc/mpic: Fix MPIC_BROKEN_REGREAD on non broken MPICs
The workaround enabled by CONFIG_MPIC_BROKEN_REGREAD does not work on non-broken MPICs. The symptom is no interrupts being received. The fix is twofold. Firstly the code was broken for multiple isus, we need to index into the shadow array with the src_no, not the idx. Secondly, we always do the read, but only use the VECPRI_MASK and VECPRI_ACTIVITY bits from the hardware, the rest of "val" comes from the shadow. Signed-off-by: Michael Ellerman <michael@ellerman.id.au> Signed-off-by: Olof Johansson <olof@lixom.net> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/sysdev/mpic.c')
-rw-r--r--arch/powerpc/sysdev/mpic.c13
1 files changed, 8 insertions, 5 deletions
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index 3981ae4cb58e..30c44e6b0413 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -230,14 +230,16 @@ static inline u32 _mpic_irq_read(struct mpic *mpic, unsigned int src_no, unsigne
230{ 230{
231 unsigned int isu = src_no >> mpic->isu_shift; 231 unsigned int isu = src_no >> mpic->isu_shift;
232 unsigned int idx = src_no & mpic->isu_mask; 232 unsigned int idx = src_no & mpic->isu_mask;
233 unsigned int val;
233 234
235 val = _mpic_read(mpic->reg_type, &mpic->isus[isu],
236 reg + (idx * MPIC_INFO(IRQ_STRIDE)));
234#ifdef CONFIG_MPIC_BROKEN_REGREAD 237#ifdef CONFIG_MPIC_BROKEN_REGREAD
235 if (reg == 0) 238 if (reg == 0)
236 return mpic->isu_reg0_shadow[idx]; 239 val = (val & (MPIC_VECPRI_MASK | MPIC_VECPRI_ACTIVITY)) |
237 else 240 mpic->isu_reg0_shadow[src_no];
238#endif 241#endif
239 return _mpic_read(mpic->reg_type, &mpic->isus[isu], 242 return val;
240 reg + (idx * MPIC_INFO(IRQ_STRIDE)));
241} 243}
242 244
243static inline void _mpic_irq_write(struct mpic *mpic, unsigned int src_no, 245static inline void _mpic_irq_write(struct mpic *mpic, unsigned int src_no,
@@ -251,7 +253,8 @@ static inline void _mpic_irq_write(struct mpic *mpic, unsigned int src_no,
251 253
252#ifdef CONFIG_MPIC_BROKEN_REGREAD 254#ifdef CONFIG_MPIC_BROKEN_REGREAD
253 if (reg == 0) 255 if (reg == 0)
254 mpic->isu_reg0_shadow[idx] = value; 256 mpic->isu_reg0_shadow[src_no] =
257 value & ~(MPIC_VECPRI_MASK | MPIC_VECPRI_ACTIVITY);
255#endif 258#endif
256} 259}
257 260