diff options
author | Lubomir Rintel <lkundrak@v3.sk> | 2019-08-22 11:26:30 +0200 |
---|---|---|
committer | Marc Zyngier <maz@kernel.org> | 2019-08-30 16:23:30 +0200 |
commit | a46bc5fd8b205050ebbdccc6d5ca4124edb8dc6c (patch) | |
tree | 1eed4492cacce8dc9102024a2fd98c312d56cf70 /drivers/irqchip/irq-mmp.c | |
parent | irqchip/mmp: Do not use of_address_to_resource() to get mux regs (diff) | |
download | linux-a46bc5fd8b205050ebbdccc6d5ca4124edb8dc6c.tar.xz linux-a46bc5fd8b205050ebbdccc6d5ca4124edb8dc6c.zip |
irqchip/mmp: Add missing chained_irq_{enter,exit}()
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@v3.sk>
Signed-off-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20190822092643.593488-8-lkundrak@v3.sk
Diffstat (limited to 'drivers/irqchip/irq-mmp.c')
-rw-r--r-- | drivers/irqchip/irq-mmp.c | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/drivers/irqchip/irq-mmp.c b/drivers/irqchip/irq-mmp.c index f60e52bd14c6..fa23947241e8 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_desc_get_chip(desc); 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, |