Commit 0d72ba93 authored by Olof Johansson's avatar Olof Johansson Committed by Paul Mackerras

[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: default avatarOlof Johansson <olof@lixom.net>
Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
parent 2099172d
...@@ -137,6 +137,16 @@ config MPIC_U3_HT_IRQS ...@@ -137,6 +137,16 @@ config MPIC_U3_HT_IRQS
depends on PPC_MAPLE depends on PPC_MAPLE
default y default y
config MPIC_BROKEN_REGREAD
bool
depends on MPIC
help
This option enables a MPIC driver workaround for some chips
that have a bug that causes some interrupt source information
to not read back properly. It is safe to use on other chips as
well, but enabling it uses about 8KB of memory to keep copies
of the register contents in software.
config IBMVIO config IBMVIO
depends on PPC_PSERIES || PPC_ISERIES depends on PPC_PSERIES || PPC_ISERIES
bool bool
......
...@@ -5,6 +5,7 @@ config PPC_PASEMI ...@@ -5,6 +5,7 @@ config PPC_PASEMI
select MPIC select MPIC
select PPC_UDBG_16550 select PPC_UDBG_16550
select PPC_NATIVE select PPC_NATIVE
select MPIC_BROKEN_REGREAD
help help
This option enables support for PA Semi's PWRficient line This option enables support for PA Semi's PWRficient line
of SoC processors, including PA6T-1682M of SoC processors, including PA6T-1682M
......
...@@ -228,8 +228,13 @@ static inline u32 _mpic_irq_read(struct mpic *mpic, unsigned int src_no, unsigne ...@@ -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 isu = src_no >> mpic->isu_shift;
unsigned int idx = src_no & mpic->isu_mask; unsigned int idx = src_no & mpic->isu_mask;
return _mpic_read(mpic->reg_type, &mpic->isus[isu], #ifdef CONFIG_MPIC_BROKEN_REGREAD
reg + (idx * MPIC_INFO(IRQ_STRIDE))); 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, 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, ...@@ -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], _mpic_write(mpic->reg_type, &mpic->isus[isu],
reg + (idx * MPIC_INFO(IRQ_STRIDE)), value); 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)) #define mpic_read(b,r) _mpic_read(mpic->reg_type,&(b),(r))
......
...@@ -306,6 +306,10 @@ struct mpic ...@@ -306,6 +306,10 @@ struct mpic
unsigned long *hwirq_bitmap; unsigned long *hwirq_bitmap;
#endif #endif
#ifdef CONFIG_MPIC_BROKEN_REGREAD
u32 isu_reg0_shadow[MPIC_MAX_IRQ_SOURCES];
#endif
/* link */ /* link */
struct mpic *next; struct mpic *next;
......
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