diff options
Diffstat (limited to 'drivers/gpio')
-rw-r--r-- | drivers/gpio/gpio-omap.c | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index afef0f7c..c48de8f 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -1206,8 +1206,30 @@ static int omap_gpio_runtime_suspend(struct device *dev) struct gpio_bank *bank = platform_get_drvdata(pdev); u32 l1 = 0, l2 = 0; unsigned long flags; + u32 wake_low, wake_hi; spin_lock_irqsave(&bank->lock, flags); + + /* + * Only edges can generate a wakeup event to the PRCM. + * + * Therefore, ensure any wake-up capable GPIOs have + * edge-detection enabled before going idle to ensure a wakeup + * to the PRCM is generated on a GPIO transition. (c.f. 34xx + * NDA TRM 25.5.3.1) + * + * The normal values will be restored upon ->runtime_resume() + * by writing back the values saved in bank->context. + */ + wake_low = bank->context.leveldetect0 & bank->context.wake_en; + if (wake_low) + __raw_writel(wake_low | bank->context.fallingdetect, + bank->base + bank->regs->fallingdetect); + wake_hi = bank->context.leveldetect1 & bank->context.wake_en; + if (wake_hi) + __raw_writel(wake_hi | bank->context.risingdetect, + bank->base + bank->regs->risingdetect); + if (bank->power_mode != OFF_MODE) { bank->power_mode = 0; goto update_gpio_context_count; @@ -1256,6 +1278,18 @@ static int omap_gpio_runtime_resume(struct device *dev) spin_lock_irqsave(&bank->lock, flags); _gpio_dbck_enable(bank); + + /* + * In ->runtime_suspend(), level-triggered, wakeup-enabled + * GPIOs were set to edge trigger also in order to be able to + * generate a PRCM wakeup. Here we restore the + * pre-runtime_suspend() values for edge triggering. + */ + __raw_writel(bank->context.fallingdetect, + bank->base + bank->regs->fallingdetect); + __raw_writel(bank->context.risingdetect, + bank->base + bank->regs->risingdetect); + if (!bank->enabled_non_wakeup_gpios || !bank->workaround_enabled) { spin_unlock_irqrestore(&bank->lock, flags); return 0; |