diff options
author | Johan Hovold <johan@kernel.org> | 2015-05-04 11:23:25 -0400 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2015-05-12 04:56:28 -0400 |
commit | 6d86750ce62391f5a0a7985d5c050c2e3c823ab9 (patch) | |
tree | 9e5d2939be3b01a3ffdec34c37640905e5389ced /drivers/gpio | |
parent | 030bbdbf4c833bc69f502eae58498bc5572db736 (diff) |
gpio: fix gpio leak in gpiochip_add error path
Make sure to free any hogged gpios on errors in gpiochip_add.
Also move all forward declarations to the top of the file.
Fixes: f625d4601759 ("gpio: add GPIO hogging mechanism")
Signed-off-by: Johan Hovold <johan@kernel.org>
Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/gpio')
-rw-r--r-- | drivers/gpio/gpiolib.c | 10 |
1 files changed, 6 insertions, 4 deletions
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 59eaa23767d8..6bc612b8a49f 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c | |||
@@ -53,6 +53,11 @@ static DEFINE_MUTEX(gpio_lookup_lock); | |||
53 | static LIST_HEAD(gpio_lookup_list); | 53 | static LIST_HEAD(gpio_lookup_list); |
54 | LIST_HEAD(gpio_chips); | 54 | LIST_HEAD(gpio_chips); |
55 | 55 | ||
56 | |||
57 | static void gpiochip_free_hogs(struct gpio_chip *chip); | ||
58 | static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip); | ||
59 | |||
60 | |||
56 | static inline void desc_set_label(struct gpio_desc *d, const char *label) | 61 | static inline void desc_set_label(struct gpio_desc *d, const char *label) |
57 | { | 62 | { |
58 | d->label = label; | 63 | d->label = label; |
@@ -297,6 +302,7 @@ int gpiochip_add(struct gpio_chip *chip) | |||
297 | 302 | ||
298 | err_remove_chip: | 303 | err_remove_chip: |
299 | acpi_gpiochip_remove(chip); | 304 | acpi_gpiochip_remove(chip); |
305 | gpiochip_free_hogs(chip); | ||
300 | of_gpiochip_remove(chip); | 306 | of_gpiochip_remove(chip); |
301 | spin_lock_irqsave(&gpio_lock, flags); | 307 | spin_lock_irqsave(&gpio_lock, flags); |
302 | list_del(&chip->list); | 308 | list_del(&chip->list); |
@@ -313,10 +319,6 @@ err_free_descs: | |||
313 | } | 319 | } |
314 | EXPORT_SYMBOL_GPL(gpiochip_add); | 320 | EXPORT_SYMBOL_GPL(gpiochip_add); |
315 | 321 | ||
316 | /* Forward-declaration */ | ||
317 | static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip); | ||
318 | static void gpiochip_free_hogs(struct gpio_chip *chip); | ||
319 | |||
320 | /** | 322 | /** |
321 | * gpiochip_remove() - unregister a gpio_chip | 323 | * gpiochip_remove() - unregister a gpio_chip |
322 | * @chip: the chip to unregister | 324 | * @chip: the chip to unregister |