]> git.itanic.dy.fi Git - linux-stable/commitdiff
gpio: ixp4xx: Make irqchip immutable
authorLinus Walleij <linus.walleij@linaro.org>
Sun, 11 Sep 2022 19:07:51 +0000 (21:07 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 28 Sep 2022 09:32:24 +0000 (11:32 +0200)
[ Upstream commit 94e9bc73d85aa6ecfe249e985ff57abe0ab35f34 ]

This turns the IXP4xx GPIO irqchip into an immutable
irqchip, a bit different from the standard template due
to being hierarchical.

Tested on the IXP4xx which uses drivers/ata/pata_ixp4xx_cf.c
for a rootfs on compact flash with IRQs from this GPIO
block to the CF ATA controller.

Cc: Marc Zyngier <maz@kernel.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Acked-by: Marc Zyngier <maz@kernel.org>
Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/gpio/gpio-ixp4xx.c

index 312309be0287db567c0a5c838078969fd4b19b1a..56656fb519f8553e783998188473c88db9a6e1b1 100644 (file)
@@ -63,6 +63,14 @@ static void ixp4xx_gpio_irq_ack(struct irq_data *d)
        __raw_writel(BIT(d->hwirq), g->base + IXP4XX_REG_GPIS);
 }
 
+static void ixp4xx_gpio_mask_irq(struct irq_data *d)
+{
+       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+
+       irq_chip_mask_parent(d);
+       gpiochip_disable_irq(gc, d->hwirq);
+}
+
 static void ixp4xx_gpio_irq_unmask(struct irq_data *d)
 {
        struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
@@ -72,6 +80,7 @@ static void ixp4xx_gpio_irq_unmask(struct irq_data *d)
        if (!(g->irq_edge & BIT(d->hwirq)))
                ixp4xx_gpio_irq_ack(d);
 
+       gpiochip_enable_irq(gc, d->hwirq);
        irq_chip_unmask_parent(d);
 }
 
@@ -149,12 +158,14 @@ static int ixp4xx_gpio_irq_set_type(struct irq_data *d, unsigned int type)
        return irq_chip_set_type_parent(d, IRQ_TYPE_LEVEL_HIGH);
 }
 
-static struct irq_chip ixp4xx_gpio_irqchip = {
+static const struct irq_chip ixp4xx_gpio_irqchip = {
        .name = "IXP4GPIO",
        .irq_ack = ixp4xx_gpio_irq_ack,
-       .irq_mask = irq_chip_mask_parent,
+       .irq_mask = ixp4xx_gpio_mask_irq,
        .irq_unmask = ixp4xx_gpio_irq_unmask,
        .irq_set_type = ixp4xx_gpio_irq_set_type,
+       .flags = IRQCHIP_IMMUTABLE,
+       GPIOCHIP_IRQ_RESOURCE_HELPERS,
 };
 
 static int ixp4xx_gpio_child_to_parent_hwirq(struct gpio_chip *gc,
@@ -263,7 +274,7 @@ static int ixp4xx_gpio_probe(struct platform_device *pdev)
        g->gc.owner = THIS_MODULE;
 
        girq = &g->gc.irq;
-       girq->chip = &ixp4xx_gpio_irqchip;
+       gpio_irq_chip_set_chip(girq, &ixp4xx_gpio_irqchip);
        girq->fwnode = g->fwnode;
        girq->parent_domain = parent;
        girq->child_to_parent_hwirq = ixp4xx_gpio_child_to_parent_hwirq;