diff options
author | Axel Haslam <axelhaslam@ti.com> | 2011-09-13 15:55:19 -0700 |
---|---|---|
committer | Todd Poynor <toddpoynor@google.com> | 2011-10-06 18:47:25 -0700 |
commit | 4b660d8efa30f1a8911114fa5007fcc602f8960f (patch) | |
tree | 4152287f6ad2d1410a4dfeb7e9d4be8e0102adb7 | |
parent | f42515c120a57bb9087e6efba1b447387870878c (diff) | |
download | kernel_samsung_tuna-4b660d8efa30f1a8911114fa5007fcc602f8960f.zip kernel_samsung_tuna-4b660d8efa30f1a8911114fa5007fcc602f8960f.tar.gz kernel_samsung_tuna-4b660d8efa30f1a8911114fa5007fcc602f8960f.tar.bz2 |
GPIO: OMAP: set edge trigger for wakeup gpio
Only edge trigger is supported for wakeup.
if a gpio is set as wakeup, and level trigger,
make sure we set the edge trigger so that we
can wake up.
Change-Id: Ibb61042be6ce053729ff20f3cb8d53899afe42b1
Signed-off-by: Axel Haslam <axelhaslam@ti.com>
-rw-r--r-- | arch/arm/mach-omap2/pm44xx.c | 4 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/plat/gpio.h | 2 | ||||
-rw-r--r-- | drivers/gpio/gpio-omap.c | 47 |
3 files changed, 53 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c index 7e2b3c8..8ffc139 100644 --- a/arch/arm/mach-omap2/pm44xx.c +++ b/arch/arm/mach-omap2/pm44xx.c @@ -165,6 +165,8 @@ void omap4_enter_sleep(unsigned int cpu, unsigned int power_state, bool suspend) } } + omap2_gpio_set_edge_wakeup(); + if (omap4_device_next_state_off()) { omap2_gpio_prepare_for_idle(true); omap_gpmc_save_context(); @@ -233,6 +235,8 @@ abort_device_off: OMAP4430_PRM_DEVICE_INST, OMAP4_PRM_IO_PMCTRL_OFFSET); } + omap2_gpio_restore_edge_wakeup(); + if (mpu_next_state < PWRDM_POWER_INACTIVE) { omap_vc_set_auto_trans(mpu_voltdm, OMAP_VC_CHANNEL_AUTO_TRANSITION_DISABLE); diff --git a/arch/arm/plat-omap/include/plat/gpio.h b/arch/arm/plat-omap/include/plat/gpio.h index 24b61af..89af4ad 100644 --- a/arch/arm/plat-omap/include/plat/gpio.h +++ b/arch/arm/plat-omap/include/plat/gpio.h @@ -217,6 +217,8 @@ extern void omap2_gpio_prepare_for_idle(int off_mode); extern void omap2_gpio_resume_after_idle(void); extern void omap_set_gpio_debounce(int gpio, int enable); extern void omap_set_gpio_debounce_time(int gpio, int enable); +extern void omap2_gpio_set_edge_wakeup(void); +extern void omap2_gpio_restore_edge_wakeup(void); /*-------------------------------------------------------------------------*/ /* Wrappers for "new style" GPIO calls, using the new infrastructure 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) { |