diff options
author | Andrew Lunn <andrew@lunn.ch> | 2015-01-10 00:34:48 +0100 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2015-01-15 17:23:24 +0100 |
commit | f1d2d081e8d13b23ea53f32932ae03af76934b9a (patch) | |
tree | 67b668d1e46c6e589cbc9765027710f85bb093f1 | |
parent | a4319a611bcdc32f042578c9c9b75bbdc23149e3 (diff) |
gpio: mvebu: Fix probe cleanup on error
Ensure that when there is an error during probe that the gpiochip is
removed and the generic irq chip is removed.
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-rw-r--r-- | drivers/gpio/gpio-mvebu.c | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c index 7533d446b820..d0bc123c7975 100644 --- a/drivers/gpio/gpio-mvebu.c +++ b/drivers/gpio/gpio-mvebu.c @@ -667,6 +667,7 @@ static int mvebu_gpio_probe(struct platform_device *pdev) unsigned int ngpios; int soc_variant; int i, cpu, id; + int err; match = of_match_device(mvebu_gpio_of_match, &pdev->dev); if (match) @@ -785,14 +786,16 @@ static int mvebu_gpio_probe(struct platform_device *pdev) mvchip->irqbase = irq_alloc_descs(-1, 0, ngpios, -1); if (mvchip->irqbase < 0) { dev_err(&pdev->dev, "no irqs\n"); - return mvchip->irqbase; + err = mvchip->irqbase; + goto err_gpiochip_add; } gc = irq_alloc_generic_chip("mvebu_gpio_irq", 2, mvchip->irqbase, mvchip->membase, handle_level_irq); if (!gc) { dev_err(&pdev->dev, "Cannot allocate generic irq_chip\n"); - return -ENOMEM; + err = -ENOMEM; + goto err_gpiochip_add; } gc->private = mvchip; @@ -823,13 +826,21 @@ static int mvebu_gpio_probe(struct platform_device *pdev) if (!mvchip->domain) { dev_err(&pdev->dev, "couldn't allocate irq domain %s (DT).\n", mvchip->chip.label); - irq_remove_generic_chip(gc, IRQ_MSK(ngpios), IRQ_NOREQUEST, - IRQ_LEVEL | IRQ_NOPROBE); - kfree(gc); - return -ENODEV; + err = -ENODEV; + goto err_generic_chip; } return 0; + +err_generic_chip: + irq_remove_generic_chip(gc, IRQ_MSK(ngpios), IRQ_NOREQUEST, + IRQ_LEVEL | IRQ_NOPROBE); + kfree(gc); + +err_gpiochip_add: + gpiochip_remove(&mvchip->chip); + + return err; } static struct platform_driver mvebu_gpio_driver = { |