lkml.org 
[lkml]   [2019]   [Jul]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL 4.19 060/158] gpio: omap: ensure irq is enabled before wakeup
    Date
    From: Russell King <rmk+kernel@armlinux.org.uk>

    [ Upstream commit c859e0d479b3b4f6132fc12637c51e01492f31f6 ]

    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>
    ---
    drivers/gpio/gpio-omap.c | 15 ++++++++-------
    1 file changed, 8 insertions(+), 7 deletions(-)

    diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
    index 9254bcf7f647..feabac40743e 100644
    --- a/drivers/gpio/gpio-omap.c
    +++ b/drivers/gpio/gpio-omap.c
    @@ -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);
    }

    --
    2.20.1
    \
     
     \ /
      Last update: 2019-07-15 17:45    [W:2.640 / U:0.100 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site