Re: [PATCH v5] gpio/mpc8xxx: change irq handler from chained to normal
From: Bartosz Golaszewski <hidden>
Date: 2019-09-18 07:36:45
Also in:
linux-devicetree, linux-gpio, lkml
pon., 16 wrz 2019 o 08:08 Hui Song [off-list ref] napisał(a):
quoted hunk ↗ jump to hunk
From: Song Hui <redacted> More than one gpio controllers can share one interrupt, change the driver to request shared irq. Signed-off-by: Laurentiu Tudor <Laurentiu.Tudor@nxp.com> Signed-off-by: Alex Marginean <redacted> Signed-off-by: Song Hui <redacted> --- Changes in v5: - add traverse every bit function. Changes in v4: - convert 'pr_err' to 'dev_err'. Changes in v3: - update the patch description. Changes in v2: - delete the compatible of ls1088a. drivers/gpio/gpio-mpc8xxx.c | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-)diff --git a/drivers/gpio/gpio-mpc8xxx.c b/drivers/gpio/gpio-mpc8xxx.c index 16a47de..3a06ca9 100644 --- a/drivers/gpio/gpio-mpc8xxx.c +++ b/drivers/gpio/gpio-mpc8xxx.c@@ -22,6 +22,7 @@ #include <linux/irq.h> #include <linux/gpio/driver.h> #include <linux/bitops.h> +#include <linux/interrupt.h> #define MPC8XXX_GPIO_PINS 32@@ -127,20 +128,20 @@ static int mpc8xxx_gpio_to_irq(struct gpio_chip *gc, unsigned offset) return -ENXIO; } -static void mpc8xxx_gpio_irq_cascade(struct irq_desc *desc) +static irqreturn_t mpc8xxx_gpio_irq_cascade(int irq, void *data) { - struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_desc_get_handler_data(desc); - struct irq_chip *chip = irq_desc_get_chip(desc); + struct mpc8xxx_gpio_chip *mpc8xxx_gc = (struct mpc8xxx_gpio_chip *)data;
There's no need to cast void pointers.
quoted hunk ↗ jump to hunk
struct gpio_chip *gc = &mpc8xxx_gc->gc; unsigned int mask; + int i; mask = gc->read_reg(mpc8xxx_gc->regs + GPIO_IER) & gc->read_reg(mpc8xxx_gc->regs + GPIO_IMR); - if (mask) + for_each_set_bit(i, &mask, 32) generic_handle_irq(irq_linear_revmap(mpc8xxx_gc->irq, - 32 - ffs(mask))); - if (chip->irq_eoi) - chip->irq_eoi(&desc->irq_data); + 31 - i)); + + return IRQ_HANDLED; } static void mpc8xxx_irq_unmask(struct irq_data *d)@@ -388,8 +389,8 @@ static int mpc8xxx_probe(struct platform_device *pdev) ret = gpiochip_add_data(gc, mpc8xxx_gc); if (ret) { - pr_err("%pOF: GPIO chip registration failed with status %d\n", - np, ret); + dev_err(&pdev->dev, "%pOF: GPIO chip registration failed with status %d\n", + np, ret); goto err; }@@ -409,8 +410,15 @@ static int mpc8xxx_probe(struct platform_device *pdev) if (devtype->gpio_dir_in_init) devtype->gpio_dir_in_init(gc); - irq_set_chained_handler_and_data(mpc8xxx_gc->irqn, - mpc8xxx_gpio_irq_cascade, mpc8xxx_gc); + ret = request_irq(mpc8xxx_gc->irqn, mpc8xxx_gpio_irq_cascade, + IRQF_NO_THREAD | IRQF_SHARED, "gpio-cascade", + mpc8xxx_gc);
You never free this irq. Maybe use devm_request_irq()? Bart
+ if (ret) {
+ dev_err(&pdev->dev, "%s: failed to request_irq(%d), ret = %d\n",
+ np->full_name, mpc8xxx_gc->irqn, ret);
+ goto err;
+ }
+
return 0;
err:
iounmap(mpc8xxx_gc->regs);
--
2.9.5_______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel