diff options
Diffstat (limited to 'drivers/gpio')
-rw-r--r-- | drivers/gpio/gpio-omap.c | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index a06a054..312d45d 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -44,6 +44,8 @@ struct gpio_regs { u32 dataout; u32 debounce; u32 debounce_en; + u32 edge_falling; + u32 edge_rising; }; struct gpio_bank { @@ -1383,6 +1385,51 @@ static int omap_gpio_pm_runtime_resume(struct device *dev) } #ifdef CONFIG_ARCH_OMAP2PLUS +void omap2_gpio_set_edge_wakeup(void) +{ + struct gpio_bank *bank; + + list_for_each_entry(bank, &omap_gpio_list, node) { + u32 level_low = 0; + u32 level_high = 0; + u32 wkup_status = 0; + + level_low = __raw_readl(bank->base + + bank->regs->leveldetect0); + level_high = __raw_readl(bank->base + + bank->regs->leveldetect1); + wkup_status = __raw_readl(bank->base + + bank->regs->wkup_status); + bank->context.edge_falling = __raw_readl(bank->base + + bank->regs->fallingdetect); + bank->context.edge_rising = __raw_readl(bank->base + + bank->regs->risingdetect); + + /* + * Set edge trigger for all gpio's that are + * expected to produce wakeup from low power. + * even if they are set for level detection only. + */ + __raw_writel((bank->context.edge_falling | level_low) & wkup_status, + (bank->base + bank->regs->fallingdetect)); + __raw_writel((bank->context.edge_rising | level_high) & wkup_status, + (bank->base + bank->regs->risingdetect)); + + } +} + +void omap2_gpio_restore_edge_wakeup(void) +{ + struct gpio_bank *bank; + + list_for_each_entry(bank, &omap_gpio_list, node) { + /* restore edge setting */ + __raw_writel(bank->context.edge_falling, + (bank->base + bank->regs->fallingdetect)); + __raw_writel(bank->context.edge_rising, + (bank->base + bank->regs->risingdetect)); + } +} void omap2_gpio_prepare_for_idle(int off_mode) { |