powerpc: Add workaround for MPICs with broken register reads
PATCH 1/1 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.
arch/powerpc/platforms/Kconfig +4 -0
@@ -137,6 +137,10 @@ config MPIC_U3_HT_IRQS depends on PPC_MAPLE default y +config MPIC_BROKEN_REGREAD + bool + depends on PPC_PASEMI + config IBMVIO depends on PPC_PSERIES || PPC_ISERIES bool
arch/powerpc/platforms/pasemi/Kconfig +1 -0
@@ -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
arch/powerpc/sysdev/mpic.c +12 -2
@@ -228,8 +228,13 @@ static inline u32 _mpic_irq_read(struct mpic *mpic, unsigned int src_no, unsigneunsigned 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))
include/asm-powerpc/mpic.h +4 -0
@@ -309,6 +309,10 @@ struct mpicunsigned long *hwirq_bitmap;#endif +#ifdef CONFIG_MPIC_BROKEN_REGREAD +u32 isu_reg0_shadow[MPIC_MAX_IRQ_SOURCES ]; +#endif +/* link */ struct mpic *next;
Quoted 20 lines · Olof Johansson
arch/powerpc/platforms/Kconfig +4
-0@@ -137,6 +137,10 @@ config MPIC_U3_HT_IRQS depends on PPC_MAPLE default y +config MPIC_BROKEN_REGREAD + bool + depends on PPC_PASEMI + config IBMVIO depends on PPC_PSERIES || PPC_ISERIES boolarch/powerpc/platforms/pasemi/Kconfig +0
-0
arch/powerpc/platforms/pasemi/Kconfig config PPC_PASEMI · line 11
Quoted 7 lines
arch/powerpc/platforms/pasemi/Kconfig +1
-0@@ -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
Since you are using select (and not default y), instead of the depends on PPC_PASEMI how about adding a short description of what the config does as help text, in case some future mpic has a similar bug?
milton
Quoted 27 lines · Milton Miller
Quoted 26 lines · Olof Johansson
arch/powerpc/platforms/Kconfig +4
-0@@ -137,6 +137,10 @@ config MPIC_U3_HT_IRQS depends on PPC_MAPLE default y +config MPIC_BROKEN_REGREAD + bool + depends on PPC_PASEMI + config IBMVIO depends on PPC_PSERIES || PPC_ISERIES boolarch/powerpc/platforms/pasemi/Kconfig +1
-0@@ -5,6 +5,7 @@ config PPC_PASEMI select MPIC select PPC_UDBG_16550 select PPC_NATIVE + select MPIC_BROKEN_REGREAD
Quoted 8 lines
arch/powerpc/platforms/pasemi/Kconfig config PPC_PASEMI · line 11
Quoted 3 lines
arch/powerpc/platforms/pasemi/Kconfig +0
-0help This option enables support for PA Semi's PWRficient line of SoC processors, including PA6T-1682MSince you are using select (and not default y), instead of the depends on
PPC_PASEMIhow about adding a short description of what the config does as help text, in case some future mpic has a similar bug?
Thanks Milton, that's a reasonable suggestion (not that any of the other options do it, including the very vague MPIC_WEIRD :-).
New patch posted shortly.
-Olof
PATCH v2 1/1 powerpc: Add workaround for MPICs with broken register reads
In reply to Olof JohanssonSome 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.
arch/powerpc/platforms/Kconfig +12 -0
@@ -137,6 +137,18 @@ config MPIC_U3_HT_IRQS depends on PPC_MAPLE default y +config MPIC_BROKEN_REGREAD + bool "MPIC workaround for broken register reads" + depends on MPIC + help + Say Y here to enable 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. + + Say N if you are unsure. + config IBMVIO depends on PPC_PSERIES || PPC_ISERIES bool
arch/powerpc/platforms/pasemi/Kconfig +1 -0
@@ -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
arch/powerpc/sysdev/mpic.c +12 -2
@@ -228,8 +228,13 @@ static inline u32 _mpic_irq_read(struct mpic *mpic, unsigned int src_no, unsigneunsigned 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))
include/asm-powerpc/mpic.h +4 -0
@@ -309,6 +309,10 @@ struct mpicunsigned long *hwirq_bitmap;#endif +#ifdef CONFIG_MPIC_BROKEN_REGREAD +u32 isu_reg0_shadow[MPIC_MAX_IRQ_SOURCES ]; +#endif +/* link */ struct mpic *next;
Quoted 22 lines · Olof Johansson
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 <[email protected]>arch/powerpc/platforms/Kconfig +3
-0@@ -137,6 +137,18 @@ config MPIC_U3_HT_IRQS depends on PPC_MAPLE default y +config MPIC_BROKEN_REGREAD + bool "MPIC workaround for broken register reads" + depends on MPIC
arch/powerpc/platforms/Kconfig config MPIC_U3_HT_IRQS · line 152
Quoted 10 lines
arch/powerpc/platforms/Kconfig +9
-0+ help + Say Y here to enable 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. + + Say N if you are unsure. +
I'm sorry, I didn't mean to imply it should be asked / selectable, just that the help should be provided. I won't object to leaving it except that it asks the average user unnecessary questions. In other words, drop the question after bool.
milton
Quoted 4 lines · Milton Miller
I'm sorry, I didn't mean to imply it should be asked / selectable, just
that the help should be provided. I won't object to leaving it except
that it asks the average user unnecessary questions. In other words, drop
the question after bool.
Sigh. Why is it always that the simple patches/changes require 3 respins? It's a valid point though, posting v3.
-Olof
PATCH v3 1/1 powerpc: Add workaround for MPICs with broken register reads
In reply to Olof JohanssonSome 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.
arch/powerpc/platforms/Kconfig +10 -0
@@ -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
arch/powerpc/platforms/pasemi/Kconfig +1 -0
@@ -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
arch/powerpc/sysdev/mpic.c +12 -2
@@ -228,8 +228,13 @@ static inline u32 _mpic_irq_read(struct mpic *mpic, unsigned int src_no, unsigneunsigned 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))
include/asm-powerpc/mpic.h +4 -0
@@ -309,6 +309,10 @@ struct mpicunsigned long *hwirq_bitmap;#endif +#ifdef CONFIG_MPIC_BROKEN_REGREAD +u32 isu_reg0_shadow[MPIC_MAX_IRQ_SOURCES ]; +#endif +/* link */ struct mpic *next;