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
depends on PPC_MAPLE
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
depends on PPC_PSERIES || PPC_ISERIES
bool
......
......@@ -5,6 +5,7 @@ config PPC_PASEMI
select MPIC
select PPC_UDBG_16550
select PPC_NATIVE
select MPIC_BROKEN_REGREAD
help
This option enables support for PA Semi's PWRficient line
of SoC processors, including PA6T-1682M
......
......@@ -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))
......
......@@ -306,6 +306,10 @@ struct mpic
unsigned long *hwirq_bitmap;
#endif
#ifdef CONFIG_MPIC_BROKEN_REGREAD
u32 isu_reg0_shadow[MPIC_MAX_IRQ_SOURCES];
#endif
/* link */
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