gpio: mvebu: ipipe: enable pipelined interrupts
authorGilles Chanteperdrix <gilles.chanteperdrix@xenomai.org>
Sun, 3 Dec 2017 16:10:26 +0000 (17:10 +0100)
committerMarek Szyprowski <m.szyprowski@samsung.com>
Fri, 27 Apr 2018 09:21:34 +0000 (11:21 +0200)
drivers/gpio/gpio-mvebu.c

index 45c65f805fd6ba5a3899b5c29a9651fa2d6dcc43..058362c5adf0f24623edc08bb3b3cd968e09383b 100644 (file)
@@ -50,6 +50,7 @@
 #include <linux/pwm.h>
 #include <linux/regmap.h>
 #include <linux/slab.h>
+#include <linux/ipipe.h>
 
 #include "gpiolib.h"
 
@@ -392,10 +393,11 @@ static void mvebu_gpio_irq_ack(struct irq_data *d)
        struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
        struct mvebu_gpio_chip *mvchip = gc->private;
        u32 mask = d->mask;
+       unsigned long flags;
 
-       irq_gc_lock(gc);
+       flags = irq_gc_lock(gc);
        mvebu_gpio_write_edge_cause(mvchip, ~mask);
-       irq_gc_unlock(gc);
+       irq_gc_unlock(gc, flags);
 }
 
 static void mvebu_gpio_edge_irq_mask(struct irq_data *d)
@@ -404,11 +406,12 @@ static void mvebu_gpio_edge_irq_mask(struct irq_data *d)
        struct mvebu_gpio_chip *mvchip = gc->private;
        struct irq_chip_type *ct = irq_data_get_chip_type(d);
        u32 mask = d->mask;
+       unsigned long flags;
 
-       irq_gc_lock(gc);
+       flags = irq_gc_lock(gc);
        ct->mask_cache_priv &= ~mask;
        mvebu_gpio_write_edge_mask(mvchip, ct->mask_cache_priv);
-       irq_gc_unlock(gc);
+       irq_gc_unlock(gc, flags);
 }
 
 static void mvebu_gpio_edge_irq_unmask(struct irq_data *d)
@@ -417,11 +420,12 @@ static void mvebu_gpio_edge_irq_unmask(struct irq_data *d)
        struct mvebu_gpio_chip *mvchip = gc->private;
        struct irq_chip_type *ct = irq_data_get_chip_type(d);
        u32 mask = d->mask;
+       unsigned long flags;
 
-       irq_gc_lock(gc);
+       flags = irq_gc_lock(gc);
        ct->mask_cache_priv |= mask;
        mvebu_gpio_write_edge_mask(mvchip, ct->mask_cache_priv);
-       irq_gc_unlock(gc);
+       irq_gc_unlock(gc, flags);
 }
 
 static void mvebu_gpio_level_irq_mask(struct irq_data *d)
@@ -430,11 +434,12 @@ static void mvebu_gpio_level_irq_mask(struct irq_data *d)
        struct mvebu_gpio_chip *mvchip = gc->private;
        struct irq_chip_type *ct = irq_data_get_chip_type(d);
        u32 mask = d->mask;
+       unsigned long flags;
 
-       irq_gc_lock(gc);
+       flags = irq_gc_lock(gc);
        ct->mask_cache_priv &= ~mask;
        mvebu_gpio_write_level_mask(mvchip, ct->mask_cache_priv);
-       irq_gc_unlock(gc);
+       irq_gc_unlock(gc, flags);
 }
 
 static void mvebu_gpio_level_irq_unmask(struct irq_data *d)
@@ -443,11 +448,12 @@ static void mvebu_gpio_level_irq_unmask(struct irq_data *d)
        struct mvebu_gpio_chip *mvchip = gc->private;
        struct irq_chip_type *ct = irq_data_get_chip_type(d);
        u32 mask = d->mask;
+       unsigned long flags;
 
-       irq_gc_lock(gc);
+       flags = irq_gc_lock(gc);
        ct->mask_cache_priv |= mask;
        mvebu_gpio_write_level_mask(mvchip, ct->mask_cache_priv);
-       irq_gc_unlock(gc);
+       irq_gc_unlock(gc, flags);
 }
 
 /*****************************************************************************
@@ -581,7 +587,7 @@ static void mvebu_gpio_irq_handler(struct irq_desc *desc)
                                     polarity);
                }
 
-               generic_handle_irq(irq);
+               ipipe_handle_demuxed_irq(irq);
        }
 
        chained_irq_exit(chip, desc);
@@ -1228,6 +1234,7 @@ static int mvebu_gpio_probe(struct platform_device *pdev)
        ct->chip.irq_unmask = mvebu_gpio_level_irq_unmask;
        ct->chip.irq_set_type = mvebu_gpio_irq_set_type;
        ct->chip.name = mvchip->chip.label;
+       ct->chip.flags = IRQCHIP_PIPELINE_SAFE;
 
        ct = &gc->chip_types[1];
        ct->type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
@@ -1237,6 +1244,7 @@ static int mvebu_gpio_probe(struct platform_device *pdev)
        ct->chip.irq_set_type = mvebu_gpio_irq_set_type;
        ct->handler = handle_edge_irq;
        ct->chip.name = mvchip->chip.label;
+       ct->chip.flags = IRQCHIP_PIPELINE_SAFE;
 
        /*
         * Setup the interrupt handlers. Each chip can have up to 4