summaryrefslogtreecommitdiff
path: root/arch/powerpc/sysdev/mpic.c
diff options
context:
space:
mode:
authorOlof Johansson <olof@lixom.net>2007-09-08 05:13:19 +1000
committerPaul Mackerras <paulus@samba.org>2007-09-14 01:33:25 +1000
commit0d72ba930cbc9140a584af7e4e65041b6c7a7d18 (patch)
tree8dd36503702183fb15f5e783249433c9880e45ee /arch/powerpc/sysdev/mpic.c
parent2099172d61abda1b793b499bb8edcaac4de2cdae (diff)
[POWERPC] Add workaround for MPICs with broken register reads
Some versions of PWRficient 1682M have an interrupt controller in which the first register in each pair for interrupt sources doesn't always read with the right polarity/sense values. To work around this, keep a software copy of the register instead. Since it's not modified from the mpic itself, it's a feasible solution. Still, keep it under a config option to avoid wasting memory on other platforms. Signed-off-by: Olof Johansson <olof@lixom.net> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/sysdev/mpic.c')
-rw-r--r--arch/powerpc/sysdev/mpic.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index 25a81f73cecf..8de29f28b4c7 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -228,8 +228,13 @@ static inline u32 _mpic_irq_read(struct mpic *mpic, unsigned int src_no, unsigne
unsigned int isu = src_no >> mpic->isu_shift;
unsigned int idx = src_no & mpic->isu_mask;
- return _mpic_read(mpic->reg_type, &mpic->isus[isu],
- reg + (idx * MPIC_INFO(IRQ_STRIDE)));
+#ifdef CONFIG_MPIC_BROKEN_REGREAD
+ if (reg == 0)
+ return mpic->isu_reg0_shadow[idx];
+ else
+#endif
+ return _mpic_read(mpic->reg_type, &mpic->isus[isu],
+ reg + (idx * MPIC_INFO(IRQ_STRIDE)));
}
static inline void _mpic_irq_write(struct mpic *mpic, unsigned int src_no,
@@ -240,6 +245,11 @@ static inline void _mpic_irq_write(struct mpic *mpic, unsigned int src_no,
_mpic_write(mpic->reg_type, &mpic->isus[isu],
reg + (idx * MPIC_INFO(IRQ_STRIDE)), value);
+
+#ifdef CONFIG_MPIC_BROKEN_REGREAD
+ if (reg == 0)
+ mpic->isu_reg0_shadow[idx] = value;
+#endif
}
#define mpic_read(b,r) _mpic_read(mpic->reg_type,&(b),(r))