Commit 55b6019a authored by Kevin Hilman's avatar Kevin Hilman

OMAP: GPIO: clear/restore level/edge detect settings on mask/unmask

If IRQ triggering is enabled, it can trigger a pending interrupt
even for masked interrupts.  Any pending GPIO interrupts can
prevent the powerdomain from hitting retention.

Problem found, reported and additional review and testing by Chunquiu
Wang.
Tested-by: default avatarChunquiu Wang <cqwang@motorola.com>
Signed-off-by: default avatarKevin Hilman <khilman@deeprootsystems.com>
parent 6c5f8039
...@@ -1189,6 +1189,7 @@ static void gpio_mask_irq(unsigned int irq) ...@@ -1189,6 +1189,7 @@ static void gpio_mask_irq(unsigned int irq)
struct gpio_bank *bank = get_irq_chip_data(irq); struct gpio_bank *bank = get_irq_chip_data(irq);
_set_gpio_irqenable(bank, gpio, 0); _set_gpio_irqenable(bank, gpio, 0);
_set_gpio_triggering(bank, get_gpio_index(gpio), IRQ_TYPE_NONE);
} }
static void gpio_unmask_irq(unsigned int irq) static void gpio_unmask_irq(unsigned int irq)
...@@ -1196,6 +1197,11 @@ static void gpio_unmask_irq(unsigned int irq) ...@@ -1196,6 +1197,11 @@ static void gpio_unmask_irq(unsigned int irq)
unsigned int gpio = irq - IH_GPIO_BASE; unsigned int gpio = irq - IH_GPIO_BASE;
struct gpio_bank *bank = get_irq_chip_data(irq); struct gpio_bank *bank = get_irq_chip_data(irq);
unsigned int irq_mask = 1 << get_gpio_index(gpio); unsigned int irq_mask = 1 << get_gpio_index(gpio);
struct irq_desc *desc = irq_to_desc(irq);
u32 trigger = desc->status & IRQ_TYPE_SENSE_MASK;
if (trigger)
_set_gpio_triggering(bank, get_gpio_index(gpio), trigger);
/* For level-triggered GPIOs, the clearing must be done after /* For level-triggered GPIOs, the clearing must be done after
* the HW source is cleared, thus after the handler has run */ * the HW source is cleared, thus after the handler has run */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment