Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0d72ba93 authored by Olof Johansson's avatar Olof Johansson Committed by Paul Mackerras
Browse files

[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
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -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
+1 −0
Original line number Diff line number Diff line
@@ -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
+12 −2
Original line number Diff line number Diff line
@@ -228,6 +228,11 @@ 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;

#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)));
}
@@ -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))
+4 −0
Original line number Diff line number Diff line
@@ -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;