irqchip: brcmstb-l2: enable pipelined interrupts
authorDmitriy Cherkasov <dmitriy@oss-tech.org>
Fri, 29 Dec 2017 04:20:26 +0000 (20:20 -0800)
committerMarek Szyprowski <m.szyprowski@samsung.com>
Fri, 27 Apr 2018 09:21:34 +0000 (11:21 +0200)
drivers/irqchip/irq-brcmstb-l2.c

index b009b916a2923504414aafe6961b404614770da5..11db3f05743c21fb265e8248a5e0205710b790ef 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/irqdomain.h>
 #include <linux/irqchip.h>
 #include <linux/irqchip/chained_irq.h>
+#include <linux/ipipe.h>
 
 /* Register offsets in the L2 interrupt controller */
 #define CPU_STATUS     0x00
@@ -73,7 +74,7 @@ static void brcmstb_l2_intc_irq_handle(struct irq_desc *desc)
                /* ack at our level */
                irq_reg_writel(gc, 1 << irq, CPU_CLEAR);
                status &= ~(1 << irq);
-               generic_handle_irq(irq_find_mapping(b->domain, irq));
+               ipipe_handle_demuxed_irq(irq_find_mapping(b->domain, irq));
        } while (status);
 out:
        chained_irq_exit(chip, desc);
@@ -83,8 +84,9 @@ static void brcmstb_l2_intc_suspend(struct irq_data *d)
 {
        struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
        struct brcmstb_l2_intc_data *b = gc->private;
+       unsigned long flags;
 
-       irq_gc_lock(gc);
+       flags = irq_gc_lock(gc);
        /* Save the current mask */
        b->saved_mask = irq_reg_readl(gc, CPU_MASK_STATUS);
 
@@ -93,22 +95,23 @@ static void brcmstb_l2_intc_suspend(struct irq_data *d)
                irq_reg_writel(gc, ~gc->wake_active, CPU_MASK_SET);
                irq_reg_writel(gc, gc->wake_active, CPU_MASK_CLEAR);
        }
-       irq_gc_unlock(gc);
+       irq_gc_unlock(gc, flags);
 }
 
 static void brcmstb_l2_intc_resume(struct irq_data *d)
 {
        struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
        struct brcmstb_l2_intc_data *b = gc->private;
+       unsigned long flags;
 
-       irq_gc_lock(gc);
+       flags = irq_gc_lock(gc);
        /* Clear unmasked non-wakeup interrupts */
        irq_reg_writel(gc, ~b->saved_mask & ~gc->wake_active, CPU_CLEAR);
 
        /* Restore the saved mask */
        irq_reg_writel(gc, b->saved_mask, CPU_MASK_SET);
        irq_reg_writel(gc, ~b->saved_mask, CPU_MASK_CLEAR);
-       irq_gc_unlock(gc);
+       irq_gc_unlock(gc, flags);
 }
 
 static int __init brcmstb_l2_intc_of_init(struct device_node *np,
@@ -191,6 +194,8 @@ static int __init brcmstb_l2_intc_of_init(struct device_node *np,
        ct->chip.irq_resume = brcmstb_l2_intc_resume;
        ct->chip.irq_pm_shutdown = brcmstb_l2_intc_suspend;
 
+       ct->chip.flags = IRQCHIP_PIPELINE_SAFE;
+
        if (data->can_wake) {
                /* This IRQ chip can wake the system, set all child interrupts
                 * in wake_enabled mask