mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-30 14:19:16 +00:00
gpio: omap: ensure irq is enabled before wakeup
[ Upstream commit c859e0d479
]
Documentation states:
NOTE: There must be a correlation between the wake-up enable and
interrupt-enable registers. If a GPIO pin has a wake-up configured
on it, it must also have the corresponding interrupt enabled (on
one of the two interrupt lines).
Ensure that this condition is always satisfied by enabling the detection
events after enabling the interrupt, and disabling the detection before
disabling the interrupt. This ensures interrupt/wakeup events can not
happen until both the wakeup and interrupt enables correlate.
If we do any clearing, clear between the interrupt enable/disable and
trigger setting.
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
Tested-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
ddeef7a000
commit
544cd592ca
1 changed files with 8 additions and 7 deletions
|
@ -837,9 +837,9 @@ static void omap_gpio_irq_shutdown(struct irq_data *d)
|
|||
|
||||
raw_spin_lock_irqsave(&bank->lock, flags);
|
||||
bank->irq_usage &= ~(BIT(offset));
|
||||
omap_set_gpio_irqenable(bank, offset, 0);
|
||||
omap_clear_gpio_irqstatus(bank, offset);
|
||||
omap_set_gpio_triggering(bank, offset, IRQ_TYPE_NONE);
|
||||
omap_clear_gpio_irqstatus(bank, offset);
|
||||
omap_set_gpio_irqenable(bank, offset, 0);
|
||||
if (!LINE_USED(bank->mod_usage, offset))
|
||||
omap_clear_gpio_debounce(bank, offset);
|
||||
omap_disable_gpio_module(bank, offset);
|
||||
|
@ -881,8 +881,8 @@ static void omap_gpio_mask_irq(struct irq_data *d)
|
|||
unsigned long flags;
|
||||
|
||||
raw_spin_lock_irqsave(&bank->lock, flags);
|
||||
omap_set_gpio_irqenable(bank, offset, 0);
|
||||
omap_set_gpio_triggering(bank, offset, IRQ_TYPE_NONE);
|
||||
omap_set_gpio_irqenable(bank, offset, 0);
|
||||
raw_spin_unlock_irqrestore(&bank->lock, flags);
|
||||
}
|
||||
|
||||
|
@ -894,9 +894,6 @@ static void omap_gpio_unmask_irq(struct irq_data *d)
|
|||
unsigned long flags;
|
||||
|
||||
raw_spin_lock_irqsave(&bank->lock, flags);
|
||||
if (trigger)
|
||||
omap_set_gpio_triggering(bank, offset, trigger);
|
||||
|
||||
omap_set_gpio_irqenable(bank, offset, 1);
|
||||
|
||||
/*
|
||||
|
@ -904,9 +901,13 @@ static void omap_gpio_unmask_irq(struct irq_data *d)
|
|||
* is cleared, thus after the handler has run. OMAP4 needs this done
|
||||
* after enabing the interrupt to clear the wakeup status.
|
||||
*/
|
||||
if (bank->level_mask & BIT(offset))
|
||||
if (bank->regs->leveldetect0 && bank->regs->wkup_en &&
|
||||
trigger & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW))
|
||||
omap_clear_gpio_irqstatus(bank, offset);
|
||||
|
||||
if (trigger)
|
||||
omap_set_gpio_triggering(bank, offset, trigger);
|
||||
|
||||
raw_spin_unlock_irqrestore(&bank->lock, flags);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue