From mboxrd@z Thu Jan 1 00:00:00 1970 From: Grygorii Strashko Subject: [PATCH-next 01/20] gpio: gpio-omap: ensure irq is enabled before wakeup Date: Mon, 10 Jun 2019 20:10:44 +0300 Message-ID: <20190610171103.30903-2-grygorii.strashko@ti.com> References: <20190610171103.30903-1-grygorii.strashko@ti.com> Mime-Version: 1.0 Content-Type: text/plain Return-path: In-Reply-To: <20190610171103.30903-1-grygorii.strashko@ti.com> Sender: linux-kernel-owner@vger.kernel.org To: Russell King , Linus Walleij , Tony Lindgren Cc: Bartosz Golaszewski , linux-omap@vger.kernel.org, linux-gpio@vger.kernel.org, linux-kernel@vger.kernel.org, Santosh Shilimkar , Russell King , Grygorii Strashko List-Id: linux-omap@vger.kernel.org From: Russell King 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 Signed-off-by: Grygorii Strashko --- 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 16289bafa001..2c6d46396834 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -832,9 +832,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); @@ -870,8 +870,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); } @@ -883,9 +883,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); /* @@ -893,9 +890,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.17.1