pinctrl: mcp23s08: fix irq and irqchip setup order
authorMarco Felsch <m.felsch@pengutronix.de>
Tue, 2 Oct 2018 08:06:46 +0000 (10:06 +0200)
committerLinus Walleij <linus.walleij@linaro.org>
Wed, 10 Oct 2018 12:36:35 +0000 (14:36 +0200)
Since 'commit 02e389e63e35 ("pinctrl: mcp23s08: fix irq setup order")' the
irq request isn't the last devm_* allocation. Without a deeper look at
the irq and testing this isn't a good solution. Since this driver relies
on the devm mechanism, requesting a interrupt should be the last thing
to avoid memory corruptions during unbinding.

'Commit 02e389e63e35 ("pinctrl: mcp23s08: fix irq setup order")' fixed the
order for the interrupt-controller use case only. The
mcp23s08_irq_setup() must be split into two to fix it for the
interrupt-controller use case and to register the irq at last. So the
irq will be freed first during unbind.

Cc: stable@vger.kernel.org
Cc: Jan Kundrát <jan.kundrat@cesnet.cz>
Cc: Dmitry Mastykin <mastichi@gmail.com>
Cc: Sebastian Reichel <sebastian.reichel@collabora.co.uk>
Fixes: 82039d244f87 ("pinctrl: mcp23s08: add pinconf support")
Fixes: 02e389e63e35 ("pinctrl: mcp23s08: fix irq setup order")
Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
Tested-by: Phil Reid <preid@electromag.com.au>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
drivers/pinctrl/pinctrl-mcp23s08.c

index 4a8a8efadefab04b7add3ffe37a5c81fb322c093..cf73a403d22dfc1778d6a893bca04d5b706dce18 100644 (file)
@@ -636,6 +636,14 @@ static int mcp23s08_irq_setup(struct mcp23s08 *mcp)
                return err;
        }
 
+       return 0;
+}
+
+static int mcp23s08_irqchip_setup(struct mcp23s08 *mcp)
+{
+       struct gpio_chip *chip = &mcp->chip;
+       int err;
+
        err =  gpiochip_irqchip_add_nested(chip,
                                           &mcp23s08_irq_chip,
                                           0,
@@ -912,7 +920,7 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev,
        }
 
        if (mcp->irq && mcp->irq_controller) {
-               ret = mcp23s08_irq_setup(mcp);
+               ret = mcp23s08_irqchip_setup(mcp);
                if (ret)
                        goto fail;
        }
@@ -944,6 +952,9 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev,
                goto fail;
        }
 
+       if (mcp->irq)
+               ret = mcp23s08_irq_setup(mcp);
+
 fail:
        if (ret < 0)
                dev_dbg(dev, "can't setup chip %d, --> %d\n", addr, ret);