aecf8e3c12ca4ede60cde3c3d1d0d5990ee57290
[openwrt/openwrt.git] / target / linux / mvebu / patches-3.18 / 201-gpio_mvebu_fix_probe_cleanup_on_error.patch
1 Ensure that when there is an error during probe that the gpiochip is
2 removed and the generic irq chip is removed.
3
4 Signed-off-by: Andrew Lunn <andrew@lunn.ch>
5 ---
6 drivers/gpio/gpio-mvebu.c | 23 +++++++++++++++++------
7 1 file changed, 17 insertions(+), 6 deletions(-)
8
9 --- a/drivers/gpio/gpio-mvebu.c
10 +++ b/drivers/gpio/gpio-mvebu.c
11 @@ -667,6 +667,7 @@ static int mvebu_gpio_probe(struct platf
12 unsigned int ngpios;
13 int soc_variant;
14 int i, cpu, id;
15 + int err;
16
17 match = of_match_device(mvebu_gpio_of_match, &pdev->dev);
18 if (match)
19 @@ -785,14 +786,16 @@ static int mvebu_gpio_probe(struct platf
20 mvchip->irqbase = irq_alloc_descs(-1, 0, ngpios, -1);
21 if (mvchip->irqbase < 0) {
22 dev_err(&pdev->dev, "no irqs\n");
23 - return mvchip->irqbase;
24 + err = mvchip->irqbase;
25 + goto err_gpiochip_add;
26 }
27
28 gc = irq_alloc_generic_chip("mvebu_gpio_irq", 2, mvchip->irqbase,
29 mvchip->membase, handle_level_irq);
30 if (!gc) {
31 dev_err(&pdev->dev, "Cannot allocate generic irq_chip\n");
32 - return -ENOMEM;
33 + err = -ENOMEM;
34 + goto err_gpiochip_add;
35 }
36
37 gc->private = mvchip;
38 @@ -823,13 +826,21 @@ static int mvebu_gpio_probe(struct platf
39 if (!mvchip->domain) {
40 dev_err(&pdev->dev, "couldn't allocate irq domain %s (DT).\n",
41 mvchip->chip.label);
42 - irq_remove_generic_chip(gc, IRQ_MSK(ngpios), IRQ_NOREQUEST,
43 - IRQ_LEVEL | IRQ_NOPROBE);
44 - kfree(gc);
45 - return -ENODEV;
46 + err = -ENODEV;
47 + goto err_generic_chip;
48 }
49
50 return 0;
51 +
52 +err_generic_chip:
53 + irq_remove_generic_chip(gc, IRQ_MSK(ngpios), IRQ_NOREQUEST,
54 + IRQ_LEVEL | IRQ_NOPROBE);
55 + kfree(gc);
56 +
57 +err_gpiochip_add:
58 + gpiochip_remove(&mvchip->chip);
59 +
60 + return err;
61 }
62
63 static struct platform_driver mvebu_gpio_driver = {