From: Gilles Chanteperdrix Date: Sun, 3 Dec 2017 16:17:19 +0000 (+0100) Subject: gpio: pl061: ipipe: enable pipelined interrupts X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ce8bc4c94d46d15cc18a3a8d1816d3f6ad7ee8a1;p=platform%2Fkernel%2Flinux-exynos.git gpio: pl061: ipipe: enable pipelined interrupts --- diff --git a/drivers/gpio/gpio-pl061.c b/drivers/gpio/gpio-pl061.c index 6aaaab79c205..bb8a14acf46e 100644 --- a/drivers/gpio/gpio-pl061.c +++ b/drivers/gpio/gpio-pl061.c @@ -26,6 +26,7 @@ #include #include #include +#include #define GPIODIR 0x400 #define GPIOIS 0x404 @@ -50,7 +51,11 @@ struct pl061_context_save_regs { #endif struct pl061 { +#ifdef CONFIG_IPIPE + ipipe_spinlock_t lock; +#else raw_spinlock_t lock; +#endif void __iomem *base; struct gpio_chip gc; @@ -221,14 +226,30 @@ static void pl061_irq_handler(struct irq_desc *desc) pending = readb(pl061->base + GPIOMIS); if (pending) { for_each_set_bit(offset, &pending, PL061_GPIO_NR) - generic_handle_irq(irq_find_mapping(gc->irqdomain, - offset)); + ipipe_handle_demuxed_irq(irq_find_mapping(gc->irqdomain, + offset)); } chained_irq_exit(irqchip, desc); } static void pl061_irq_mask(struct irq_data *d) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct pl061 *pl061 = gpiochip_get_data(gc); + u8 mask = BIT(irqd_to_hwirq(d) % PL061_GPIO_NR); + unsigned long flags; + u8 gpioie; + + raw_spin_lock_irqsave(&pl061->lock, flags); + gpioie = readb(pl061->base + GPIOIE) & ~mask; + writeb(gpioie, pl061->base + GPIOIE); + ipipe_lock_irq(d->irq); + raw_spin_unlock_irqrestore(&pl061->lock, flags); +} + +#ifdef CONFIG_IPIPE +static void pl061_irq_mask_ack(struct irq_data *d) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct pl061 *pl061 = gpiochip_get_data(gc); @@ -240,7 +261,7 @@ static void pl061_irq_mask(struct irq_data *d) writeb(gpioie, pl061->base + GPIOIE); raw_spin_unlock(&pl061->lock); } - +#endif static void pl061_irq_unmask(struct irq_data *d) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); @@ -288,6 +309,10 @@ static struct irq_chip pl061_irqchip = { .irq_unmask = pl061_irq_unmask, .irq_set_type = pl061_irq_type, .irq_set_wake = pl061_irq_set_wake, +#ifdef CONFIG_IPIPE + .irq_mask_ack = pl061_irq_mask_ack, + .flags = IRQCHIP_PIPELINE_SAFE, +#endif }; static int pl061_probe(struct amba_device *adev, const struct amba_id *id)