aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-omap2/pm24xx.c2
-rw-r--r--arch/arm/mach-omap2/pm34xx.c2
-rw-r--r--arch/arm/mach-omap2/pm44xx.c15
-rw-r--r--arch/arm/plat-omap/include/plat/gpio.h4
-rw-r--r--drivers/gpio/gpio-omap.c114
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 "