diff options
-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 | ||||
-rw-r--r-- | include/asm-powerpc/mpic.h | 4 |
4 files changed, 27 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)) |
diff --git a/include/asm-powerpc/mpic.h b/include/asm-powerpc/mpic.h index 0eb3ab9ec2bb..edb4a7c84506 100644 --- a/include/asm-powerpc/mpic.h +++ b/include/asm-powerpc/mpic.h | |||
@@ -306,6 +306,10 @@ struct mpic | |||
306 | unsigned long *hwirq_bitmap; | 306 | unsigned long *hwirq_bitmap; |
307 | #endif | 307 | #endif |
308 | 308 | ||
309 | #ifdef CONFIG_MPIC_BROKEN_REGREAD | ||
310 | u32 isu_reg0_shadow[MPIC_MAX_IRQ_SOURCES]; | ||
311 | #endif | ||
312 | |||
309 | /* link */ | 313 | /* link */ |
310 | struct mpic *next; | 314 | struct mpic *next; |
311 | 315 | ||