diff options
author | Linus Walleij <linus.walleij@linaro.org> | 2022-09-11 21:07:51 +0200 |
---|---|---|
committer | Bartosz Golaszewski <brgl@bgdev.pl> | 2022-09-13 16:17:45 +0200 |
commit | 94e9bc73d85aa6ecfe249e985ff57abe0ab35f34 (patch) | |
tree | 8e9dfeb086b48e3d17fe8841be72d67bd23e1908 /drivers/gpio/gpio-ixp4xx.c | |
parent | MAINTAINERS: Update HiSilicon GPIO Driver maintainer (diff) | |
download | linux-94e9bc73d85aa6ecfe249e985ff57abe0ab35f34.tar.xz linux-94e9bc73d85aa6ecfe249e985ff57abe0ab35f34.zip |
gpio: ixp4xx: Make irqchip immutable
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>
Diffstat (limited to 'drivers/gpio/gpio-ixp4xx.c')
-rw-r--r-- | drivers/gpio/gpio-ixp4xx.c | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/drivers/gpio/gpio-ixp4xx.c b/drivers/gpio/gpio-ixp4xx.c index 312309be0287..56656fb519f8 100644 --- a/drivers/gpio/gpio-ixp4xx.c +++ b/drivers/gpio/gpio-ixp4xx.c @@ -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; |