summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGrygorii Strashko <grygorii.strashko@linaro.org>2015-05-22 17:35:49 +0300
committerLinus Walleij <linus.walleij@linaro.org>2015-06-01 16:51:16 +0200
commit1562e4618ded89b07d145d6985f469fe8be04830 (patch)
tree24d0116df779b7d32efd61d23697111674e369df
parent5f982c70a7c3382d3532ac6d13fdea48ab38b934 (diff)
downloadlinux-1562e4618ded89b07d145d6985f469fe8be04830.tar.bz2
gpio: omap: fix error handling in omap_gpio_irq_type
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>
-rw-r--r--drivers/gpio/gpio-omap.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index 505266153b4c..81e229f5ade3 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -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;
}