diff options
-rw-r--r-- | arch/arm/mach-omap2/pm24xx.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-omap2/pm34xx.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-omap2/pm44xx.c | 15 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/plat/gpio.h | 4 | ||||
-rw-r--r-- | drivers/gpio/gpio-omap.c | 114 |
5 files changed, 60 insertions, 77 deletions
diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c index fb999bc..faa8463 100644 --- a/arch/arm/mach-omap2/pm24xx.c +++ b/arch/arm/mach-omap2/pm24xx.c @@ -148,7 +148,7 @@ no_sleep: tmp = timespec_to_ns(&ts_idle) * NSEC_PER_USEC; omap2_pm_dump(0, 1, tmp); } - omap2_gpio_resume_after_idle(); + omap2_gpio_resume_after_idle(0); clk_enable(osc_ck); diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 321a7e6..535480f 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -449,7 +449,7 @@ void omap_sram_idle(void) /* PER */ if (per_next_state < PWRDM_POWER_ON) { per_prev_state = pwrdm_read_prev_pwrst(per_pwrdm); - omap2_gpio_resume_after_idle(); + omap2_gpio_resume_after_idle(per_going_off); } /* Disable IO-PAD and IO-CHAIN wakeup */ diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c index 6c0bd35..cb40890 100644 --- a/arch/arm/mach-omap2/pm44xx.c +++ b/arch/arm/mach-omap2/pm44xx.c @@ -129,6 +129,8 @@ void omap4_enter_sleep(unsigned int cpu, unsigned int power_state, bool suspend) core_next_state = pwrdm_read_next_pwrst(core_pwrdm); mpu_next_state = pwrdm_read_next_pwrst(mpu_pwrdm); + omap2_gpio_prepare_for_idle(omap4_device_next_state_off()); + if (mpu_next_state < PWRDM_POWER_INACTIVE) { if (omap_dvfs_is_scaling(mpu_voltdm)) { mpu_next_state = PWRDM_POWER_INACTIVE; @@ -165,10 +167,7 @@ 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(); omap_dma_global_context_save(); } @@ -223,26 +222,20 @@ abort_device_off: } if (omap4_device_next_state_off()) { - /* - * GPIO: since we have put_synced clks, we need to resume - * even if OFF was not really achieved - */ - omap2_gpio_resume_after_idle(); - /* Disable the extension of Non-EMIF I/O isolation */ omap4_prminst_rmw_inst_reg_bits(OMAP4430_ISOOVR_EXTEND_MASK, 0, OMAP4430_PRM_PARTITION, 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); omap_sr_enable(mpu_voltdm); } + omap2_gpio_resume_after_idle(omap4_device_next_state_off()); + return; } diff --git a/arch/arm/plat-omap/include/plat/gpio.h b/arch/arm/plat-omap/include/plat/gpio.h index 89af4ad..b374a9e 100644 --- a/arch/arm/plat-omap/include/plat/gpio.h +++ b/arch/arm/plat-omap/include/plat/gpio.h @@ -214,11 +214,9 @@ struct omap_gpio_platform_data { }; extern void omap2_gpio_prepare_for_idle(int off_mode); -extern void omap2_gpio_resume_after_idle(void); +extern void omap2_gpio_resume_after_idle(int off_mode); 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 d91a5aa..26a5a7e 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -1385,72 +1385,63 @@ static int omap_gpio_pm_runtime_resume(struct device *dev) } #ifdef CONFIG_ARCH_OMAP2PLUS -void omap2_gpio_set_edge_wakeup(void) +static void omap2_gpio_set_edge_wakeup(struct gpio_bank *bank) { - struct gpio_bank *bank; + u32 level_low = 0; + u32 level_high = 0; + u32 wkup_status = 0; - list_for_each_entry(bank, &omap_gpio_list, node) { - u32 level_low = 0; - u32 level_high = 0; - u32 wkup_status = 0; + if (pm_runtime_get_sync(bank->dev) < 0) { + dev_err(bank->dev, "%s: GPIO bank %d pm_runtime_get_sync " + "failed\n", __func__, bank->id); + return; + } - if (pm_runtime_get_sync(bank->dev) < 0) { - dev_err(bank->dev, "%s: GPIO bank %d pm_runtime_get_sync " - "failed\n", __func__, bank->id); - return; - } + 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); - 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)); - /* - * 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)); - - if (pm_runtime_put_sync_suspend(bank->dev) < 0) { - dev_err(bank->dev, "%s: GPIO bank %d pm_runtime_put_sync " - "failed\n", __func__, bank->id); - return; - } + if (pm_runtime_put_sync_suspend(bank->dev) < 0) { + dev_err(bank->dev, "%s: GPIO bank %d pm_runtime_put_sync " + "failed\n", __func__, bank->id); + return; } } -void omap2_gpio_restore_edge_wakeup(void) +static void omap2_gpio_restore_edge_wakeup(struct gpio_bank *bank) { - struct gpio_bank *bank; - - list_for_each_entry(bank, &omap_gpio_list, node) { - /* restore edge setting */ - if (pm_runtime_get_sync(bank->dev) < 0) { - dev_err(bank->dev, "%s: GPIO bank %d pm_runtime_get_sync " - "failed\n", __func__, bank->id); - return; - } + if (pm_runtime_get_sync(bank->dev) < 0) { + dev_err(bank->dev, "%s: GPIO bank %d pm_runtime_get_sync " + "failed\n", __func__, bank->id); + return; + } - __raw_writel(bank->context.edge_falling, - (bank->base + bank->regs->fallingdetect)); - __raw_writel(bank->context.edge_rising, - (bank->base + bank->regs->risingdetect)); + __raw_writel(bank->context.edge_falling, + (bank->base + bank->regs->fallingdetect)); + __raw_writel(bank->context.edge_rising, + (bank->base + bank->regs->risingdetect)); - if (pm_runtime_put_sync_suspend(bank->dev) < 0) { - dev_err(bank->dev, "%s: GPIO bank %d pm_runtime_put_sync " - "failed\n", __func__, bank->id); - return; - } + if (pm_runtime_put_sync_suspend(bank->dev) < 0) { + dev_err(bank->dev, "%s: GPIO bank %d pm_runtime_put_sync " + "failed\n", __func__, bank->id); + return; } } @@ -1458,12 +1449,11 @@ void omap2_gpio_prepare_for_idle(int off_mode) { struct gpio_bank *bank; - if (!off_mode) - return; - list_for_each_entry(bank, &omap_gpio_list, node) { - if (!bank->mod_usage || !bank->loses_context) + if (!bank->mod_usage || !bank->loses_context || !off_mode) { + omap2_gpio_set_edge_wakeup(bank); continue; + } if (pm_runtime_put_sync_suspend(bank->dev) < 0) dev_err(bank->dev, "%s: GPIO bank %d " @@ -1472,13 +1462,15 @@ void omap2_gpio_prepare_for_idle(int off_mode) } } -void omap2_gpio_resume_after_idle(void) +void omap2_gpio_resume_after_idle(int off_mode) { struct gpio_bank *bank; list_for_each_entry(bank, &omap_gpio_list, node) { - if (!bank->mod_usage || !bank->loses_context) + if (!bank->mod_usage || !bank->loses_context || !off_mode) { + omap2_gpio_restore_edge_wakeup(bank); continue; + } if (pm_runtime_get_sync(bank->dev) < 0) dev_err(bank->dev, "%s: GPIO bank %d " |