gpio: tegra: fix unbalanced chained_irq_enter/exit
authorMichał Mirosław <mirq-linux@rere.qmqm.pl>
Tue, 18 Jul 2017 12:35:45 +0000 (14:35 +0200)
committerBen Hutchings <ben@decadent.org.uk>
Sat, 11 Nov 2017 13:34:28 +0000 (13:34 +0000)
commit 9e9509e38fbe034782339eb09c915f0b5765ff69 upstream.

When more than one GPIO IRQs are triggered simultaneously,
tegra_gpio_irq_handler() called chained_irq_exit() multiple
times for one chained_irq_enter().

Fixes: 3c92db9ac0ca3eee8e46e2424b6c074e2e394ad9
Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
[Also changed the variable to a bool]
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
drivers/gpio/gpio-tegra.c

index 61044c8..9c84ad5 100644 (file)
@@ -230,7 +230,7 @@ static void tegra_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
        struct tegra_gpio_bank *bank;
        int port;
        int pin;
-       int unmasked = 0;
+       bool unmasked = false;
        struct irq_chip *chip = irq_desc_get_chip(desc);
 
        chained_irq_enter(chip, desc);
@@ -250,8 +250,8 @@ static void tegra_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
                         * before executing the hander so that we don't
                         * miss edges
                         */
-                       if (lvl & (0x100 << pin)) {
-                               unmasked = 1;
+                       if (!unmasked && lvl & (0x100 << pin)) {
+                               unmasked = true;
                                chained_irq_exit(chip, desc);
                        }