diff options
author | Olof Johansson <olof@lixom.net> | 2007-09-07 15:13:19 -0400 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2007-09-13 11:33:25 -0400 |
commit | 0d72ba930cbc9140a584af7e4e65041b6c7a7d18 (patch) | |
tree | 8dd36503702183fb15f5e783249433c9880e45ee /arch | |
parent | 2099172d61abda1b793b499bb8edcaac4de2cdae (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')
-rw-r--r-- | arch/powerpc/platforms/Kconfig | 10 | ||||
-rw-r--r-- | arch/powerpc/platforms/pasemi/Kconfig | 1 | ||||
-rw-r--r-- | arch/powerpc/sysdev/mpic.c | 14 |
3 files changed, 23 insertions, 2 deletions
diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig index 065f3b19d6c7..78a7edac577f 100644 --- a/arch/powerpc/platforms/Kconfig +++ b/arch/powerpc/platforms/Kconfig | |||
@@ -137,6 +137,16 @@ config MPIC_U3_HT_IRQS | |||
137 | depends on PPC_MAPLE | 137 | depends on PPC_MAPLE |
138 | default y | 138 | default y |
139 | 139 | ||
140 | config MPIC_BROKEN_REGREAD | ||
141 | bool | ||
142 | depends on MPIC | ||
143 | help | ||
144 | This option enables a MPIC driver workaround for some chips | ||
145 | that have a bug that causes some interrupt source information | ||
146 | to not read back properly. It is safe to use on other chips as | ||
147 | well, but enabling it uses about 8KB of memory to keep copies | ||
148 | of the register contents in software. | ||
149 | |||
140 | config IBMVIO | 150 | config IBMVIO |
141 | depends on PPC_PSERIES || PPC_ISERIES | 151 | depends on PPC_PSERIES || PPC_ISERIES |
142 | bool | 152 | bool |
diff --git a/arch/powerpc/platforms/pasemi/Kconfig b/arch/powerpc/platforms/pasemi/Kconfig index 95cd90fd81c7..117d90aa5008 100644 --- a/arch/powerpc/platforms/pasemi/Kconfig +++ b/arch/powerpc/platforms/pasemi/Kconfig | |||
@@ -5,6 +5,7 @@ config PPC_PASEMI | |||
5 | select MPIC | 5 | select MPIC |
6 | select PPC_UDBG_16550 | 6 | select PPC_UDBG_16550 |
7 | select PPC_NATIVE | 7 | select PPC_NATIVE |
8 | select MPIC_BROKEN_REGREAD | ||
8 | help | 9 | help |
9 | This option enables support for PA Semi's PWRficient line | 10 | This option enables support for PA Semi's PWRficient line |
10 | of SoC processors, including PA6T-1682M | 11 | of SoC processors, including PA6T-1682M |
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 | |||
228 | unsigned int isu = src_no >> mpic->isu_shift; | 228 | unsigned int isu = src_no >> mpic->isu_shift; |
229 | unsigned int idx = src_no & mpic->isu_mask; | 229 | unsigned int idx = src_no & mpic->isu_mask; |
230 | 230 | ||
231 | return _mpic_read(mpic->reg_type, &mpic->isus[isu], | 231 | #ifdef CONFIG_MPIC_BROKEN_REGREAD |
232 | reg + (idx * MPIC_INFO(IRQ_STRIDE))); | 232 | if (reg == 0) |
233 | return mpic->isu_reg0_shadow[idx]; | ||
234 | else | ||
235 | #endif | ||
236 | return _mpic_read(mpic->reg_type, &mpic->isus[isu], | ||
237 | reg + (idx * MPIC_INFO(IRQ_STRIDE))); | ||
233 | } | 238 | } |
234 | 239 | ||
235 | static inline void _mpic_irq_write(struct mpic *mpic, unsigned int src_no, | 240 | 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 | 245 | ||
241 | _mpic_write(mpic->reg_type, &mpic->isus[isu], | 246 | _mpic_write(mpic->reg_type, &mpic->isus[isu], |
242 | reg + (idx * MPIC_INFO(IRQ_STRIDE)), value); | 247 | reg + (idx * MPIC_INFO(IRQ_STRIDE)), value); |
248 | |||
249 | #ifdef CONFIG_MPIC_BROKEN_REGREAD | ||
250 | if (reg == 0) | ||
251 | mpic->isu_reg0_shadow[idx] = value; | ||
252 | #endif | ||
243 | } | 253 | } |
244 | 254 | ||
245 | #define mpic_read(b,r) _mpic_read(mpic->reg_type,&(b),(r)) | 255 | #define mpic_read(b,r) _mpic_read(mpic->reg_type,&(b),(r)) |