Workaround for errata 4111: IPI registers of the OpenPIC don't read back
right.

Also, reading back regular irq setup registers is broken, so keep a
software copy.


Index: mainline/arch/powerpc/sysdev/mpic.c
===================================================================
--- mainline.orig/arch/powerpc/sysdev/mpic.c
+++ mainline/arch/powerpc/sysdev/mpic.c
@@ -187,6 +187,9 @@ static inline void _mpic_write(enum mpic
 
 static inline u32 _mpic_ipi_read(struct mpic *mpic, unsigned int ipi)
 {
+#ifdef CONFIG_MPIC_BROKEN_REGREAD
+       return mpic->ipi_reg_shadow[ipi];
+#else
        enum mpic_reg_type type = mpic->reg_type;
        unsigned int offset = MPIC_INFO(GREG_IPI_VECTOR_PRI_0) +
                              (ipi * MPIC_INFO(GREG_IPI_STRIDE));
@@ -194,6 +197,7 @@ static inline u32 _mpic_ipi_read(struct 
        if ((mpic->flags & MPIC_BROKEN_IPI) && type == mpic_access_mmio_le)
                type = mpic_access_mmio_be;
        return _mpic_read(type, &mpic->gregs, offset);
+#endif
 }
 
 static inline void _mpic_ipi_write(struct mpic *mpic, unsigned int ipi, u32 
value)
@@ -202,6 +206,9 @@ static inline void _mpic_ipi_write(struc
                              (ipi * MPIC_INFO(GREG_IPI_STRIDE));
 
        _mpic_write(mpic->reg_type, &mpic->gregs, offset, value);
+#ifdef CONFIG_MPIC_BROKEN_REGREAD
+       mpic->ipi_reg_shadow[ipi] = value;
+#endif
 }
 
 static inline u32 _mpic_cpu_read(struct mpic *mpic, unsigned int reg)
@@ -213,6 +220,13 @@ static inline u32 _mpic_cpu_read(struct 
        return _mpic_read(mpic->reg_type, &mpic->cpuregs[cpu], reg);
 }
 
+static inline void _mpic_cpu0_write(struct mpic *mpic, unsigned int reg, u32 
value)
+{
+       unsigned int cpu = 0;
+
+       _mpic_write(mpic->reg_type, &mpic->cpuregs[cpu], reg, value);
+}
+
 static inline void _mpic_cpu_write(struct mpic *mpic, unsigned int reg, u32 
value)
 {
        unsigned int cpu = 0;
@@ -228,8 +242,13 @@ static inline u32 _mpic_irq_read(struct 
        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 +259,11 @@ static inline void _mpic_irq_write(struc
 
        _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))
@@ -1157,6 +1181,8 @@ void __init mpic_assign_isu(struct mpic 
                 MPIC_INFO(IRQ_STRIDE) * mpic->isu_size);
        if ((isu_first + mpic->isu_size) > mpic->num_sources)
                mpic->num_sources = isu_first + mpic->isu_size;
+
+       printk("num_sources %d\n", mpic->num_sources);
 }
 
 void __init mpic_set_default_senses(struct mpic *mpic, u8 *senses, int count)
@@ -1394,7 +1420,7 @@ void mpic_send_ipi(unsigned int ipi_no, 
        DBG("%s: send_ipi(ipi_no: %d)\n", mpic->name, ipi_no);
 #endif
 
-       mpic_cpu_write(MPIC_INFO(CPU_IPI_DISPATCH_0) +
+       _mpic_cpu0_write(mpic, MPIC_INFO(CPU_IPI_DISPATCH_0) +
                       ipi_no * MPIC_INFO(CPU_IPI_DISPATCH_STRIDE),
                       mpic_physmask(cpu_mask & cpus_addr(cpu_online_map)[0]));
 }
Index: mainline/include/asm-powerpc/mpic.h
===================================================================
--- mainline.orig/include/asm-powerpc/mpic.h
+++ mainline/include/asm-powerpc/mpic.h
@@ -306,6 +306,11 @@ struct mpic
        unsigned long           *hwirq_bitmap;
 #endif
 
+#ifdef CONFIG_MPIC_BROKEN_REGREAD
+       u32                     ipi_reg_shadow[4];
+       u32                     isu_reg0_shadow[MPIC_MAX_IRQ_SOURCES];
+#endif
+
        /* link */
        struct mpic             *next;
 
Index: mainline/arch/powerpc/platforms/Kconfig
===================================================================
--- mainline.orig/arch/powerpc/platforms/Kconfig
+++ mainline/arch/powerpc/platforms/Kconfig
@@ -121,6 +121,11 @@ config MPIC_U3_HT_IRQS
        depends on PPC_MAPLE
        default y
 
+config MPIC_BROKEN_REGREAD
+       bool
+       depends on PPC_PASEMI
+       default y
+
 config IBMVIO
        depends on PPC_PSERIES || PPC_ISERIES
        bool
Index: mainline/arch/powerpc/platforms/pasemi/Kconfig
===================================================================
--- mainline.orig/arch/powerpc/platforms/pasemi/Kconfig
+++ mainline/arch/powerpc/platforms/pasemi/Kconfig
@@ -6,6 +6,7 @@ config PPC_PASEMI
        select PPC_UDBG_16550
        select PPC_NATIVE
        select EMBEDDED
+       select MPIC_BROKEN_REGREAD
        help
          This option enables support for PA Semi's PWRficient line
          of SoC processors, including PA6T-1682M

--

_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev

Reply via email to