On 09/08/2019 10:31, Lubomir Rintel wrote: > The lack of chained_irq_exit() leaves the muxed interrupt masked on MMP3. > For reasons unknown this is not a problem on MMP2. > > Signed-off-by: Lubomir Rintel <lkundrak@xxxxx> > --- > drivers/irqchip/irq-mmp.c | 9 ++++++++- > 1 file changed, 8 insertions(+), 1 deletion(-) > > diff --git a/drivers/irqchip/irq-mmp.c b/drivers/irqchip/irq-mmp.c > index af9cba4a51c2e..cd8d2253f56d1 100644 > --- a/drivers/irqchip/irq-mmp.c > +++ b/drivers/irqchip/irq-mmp.c > @@ -13,6 +13,7 @@ > #include <linux/init.h> > #include <linux/irq.h> > #include <linux/irqchip.h> > +#include <linux/irqchip/chained_irq.h> > #include <linux/irqdomain.h> > #include <linux/io.h> > #include <linux/ioport.h> > @@ -132,11 +133,14 @@ struct irq_chip icu_irq_chip = { > static void icu_mux_irq_demux(struct irq_desc *desc) > { > unsigned int irq = irq_desc_get_irq(desc); > + struct irq_chip *chip = irq_get_chip(irq); Consider using irq_desc_get_chip() instead, which avoids going through the irq->desc again. > struct irq_domain *domain; > struct icu_chip_data *data; > int i; > unsigned long mask, status, n; > > + chained_irq_enter(chip, desc); > + > for (i = 1; i < max_icu_nr; i++) { > if (irq == icu_data[i].cascade_irq) { > domain = icu_data[i].domain; > @@ -146,7 +150,7 @@ static void icu_mux_irq_demux(struct irq_desc *desc) > } > if (i >= max_icu_nr) { > pr_err("Spurious irq %d in MMP INTC\n", irq); > - return; > + goto out; > } > > mask = readl_relaxed(data->reg_mask); > @@ -158,6 +162,9 @@ static void icu_mux_irq_demux(struct irq_desc *desc) > generic_handle_irq(icu_data[i].virq_base + n); > } > } > + > +out: > + chained_irq_exit(chip, desc); > } > > static int mmp_irq_domain_map(struct irq_domain *d, unsigned int irq, > Otherwise looks OK. M. -- Jazz is not dead, it just smells funny...