aecf8e3c12ca4ede60cde3c3d1d0d5990ee57290
[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 = {