gpio: omap: fix error handling in omap_gpio_irq_type
authorGrygorii Strashko <grygorii.strashko@linaro.org>
Fri, 22 May 2015 14:35:49 +0000 (17:35 +0300)
committerLinus Walleij <linus.walleij@linaro.org>
Mon, 1 Jun 2015 14:51:16 +0000 (16:51 +0200)
The GPIO bank will be kept powered in case if input parameters
are invalid or error occurred in omap_gpio_irq_type.

Hence, fix it by ensuring that GPIO bank will be unpowered
in case of errors and add additional check of value returned
from omap_set_gpio_triggering().

Signed-off-by: Grygorii Strashko <grygorii.strashko@linaro.org>
Tested-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
drivers/gpio/gpio-omap.c

index 505266153b4c7036445517118acae3d02ffd36f4..81e229f5ade33d854cdffe65f3e52cc08654d3ac 100644 (file)
@@ -488,9 +488,6 @@ static int omap_gpio_irq_type(struct irq_data *d, unsigned type)
        unsigned long flags;
        unsigned offset = d->hwirq;
 
-       if (!BANK_USED(bank))
-               pm_runtime_get_sync(bank->dev);
-
        if (type & ~IRQ_TYPE_SENSE_MASK)
                return -EINVAL;
 
@@ -498,12 +495,18 @@ static int omap_gpio_irq_type(struct irq_data *d, unsigned type)
                (type & (IRQ_TYPE_LEVEL_LOW|IRQ_TYPE_LEVEL_HIGH)))
                return -EINVAL;
 
+       if (!BANK_USED(bank))
+               pm_runtime_get_sync(bank->dev);
+
        spin_lock_irqsave(&bank->lock, flags);
        retval = omap_set_gpio_triggering(bank, offset, type);
+       if (retval)
+               goto error;
        omap_gpio_init_irq(bank, offset);
        if (!omap_gpio_is_input(bank, offset)) {
                spin_unlock_irqrestore(&bank->lock, flags);
-               return -EINVAL;
+               retval = -EINVAL;
+               goto error;
        }
        spin_unlock_irqrestore(&bank->lock, flags);
 
@@ -512,6 +515,11 @@ static int omap_gpio_irq_type(struct irq_data *d, unsigned type)
        else if (type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
                __irq_set_handler_locked(d->irq, handle_edge_irq);
 
+       return 0;
+
+error:
+       if (!BANK_USED(bank))
+               pm_runtime_put(bank->dev);
        return retval;
 }