Commit 347ae6e2 authored by Linus Walleij's avatar Linus Walleij

Merge branch 'ib-omap-block-idle' into devel

parents bc0ae0e7 579ced8f
...@@ -109,6 +109,7 @@ static int omap3_enter_idle(struct cpuidle_device *dev, ...@@ -109,6 +109,7 @@ static int omap3_enter_idle(struct cpuidle_device *dev,
int index) int index)
{ {
struct omap3_idle_statedata *cx = &omap3_idle_data[index]; struct omap3_idle_statedata *cx = &omap3_idle_data[index];
int error;
if (omap_irq_pending() || need_resched()) if (omap_irq_pending() || need_resched())
goto return_sleep_time; goto return_sleep_time;
...@@ -125,8 +126,11 @@ static int omap3_enter_idle(struct cpuidle_device *dev, ...@@ -125,8 +126,11 @@ static int omap3_enter_idle(struct cpuidle_device *dev,
* Call idle CPU PM enter notifier chain so that * Call idle CPU PM enter notifier chain so that
* VFP context is saved. * VFP context is saved.
*/ */
if (cx->mpu_state == PWRDM_POWER_OFF) if (cx->mpu_state == PWRDM_POWER_OFF) {
cpu_pm_enter(); error = cpu_pm_enter();
if (error)
goto out_clkdm_set;
}
/* Execute ARM wfi */ /* Execute ARM wfi */
omap_sram_idle(); omap_sram_idle();
...@@ -139,6 +143,7 @@ static int omap3_enter_idle(struct cpuidle_device *dev, ...@@ -139,6 +143,7 @@ static int omap3_enter_idle(struct cpuidle_device *dev,
pwrdm_read_prev_pwrst(mpu_pd) == PWRDM_POWER_OFF) pwrdm_read_prev_pwrst(mpu_pd) == PWRDM_POWER_OFF)
cpu_pm_exit(); cpu_pm_exit();
out_clkdm_set:
/* Re-allow idle for C1 */ /* Re-allow idle for C1 */
if (cx->flags & OMAP_CPUIDLE_CX_NO_CLKDM_IDLE) if (cx->flags & OMAP_CPUIDLE_CX_NO_CLKDM_IDLE)
clkdm_allow_idle(mpu_pd->pwrdm_clkdms[0]); clkdm_allow_idle(mpu_pd->pwrdm_clkdms[0]);
......
...@@ -122,6 +122,7 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev, ...@@ -122,6 +122,7 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev,
{ {
struct idle_statedata *cx = state_ptr + index; struct idle_statedata *cx = state_ptr + index;
u32 mpuss_can_lose_context = 0; u32 mpuss_can_lose_context = 0;
int error;
/* /*
* CPU0 has to wait and stay ON until CPU1 is OFF state. * CPU0 has to wait and stay ON until CPU1 is OFF state.
...@@ -159,7 +160,9 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev, ...@@ -159,7 +160,9 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev,
* Call idle CPU PM enter notifier chain so that * Call idle CPU PM enter notifier chain so that
* VFP and per CPU interrupt context is saved. * VFP and per CPU interrupt context is saved.
*/ */
cpu_pm_enter(); error = cpu_pm_enter();
if (error)
goto cpu_pm_out;
if (dev->cpu == 0) { if (dev->cpu == 0) {
pwrdm_set_logic_retst(mpu_pd, cx->mpu_logic_state); pwrdm_set_logic_retst(mpu_pd, cx->mpu_logic_state);
...@@ -169,13 +172,17 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev, ...@@ -169,13 +172,17 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev,
* Call idle CPU cluster PM enter notifier chain * Call idle CPU cluster PM enter notifier chain
* to save GIC and wakeupgen context. * to save GIC and wakeupgen context.
*/ */
if (mpuss_can_lose_context) if (mpuss_can_lose_context) {
cpu_cluster_pm_enter(); error = cpu_cluster_pm_enter();
if (error)
goto cpu_cluster_pm_out;
}
} }
omap4_enter_lowpower(dev->cpu, cx->cpu_state); omap4_enter_lowpower(dev->cpu, cx->cpu_state);
cpu_done[dev->cpu] = true; cpu_done[dev->cpu] = true;
cpu_cluster_pm_out:
/* Wakeup CPU1 only if it is not offlined */ /* Wakeup CPU1 only if it is not offlined */
if (dev->cpu == 0 && cpumask_test_cpu(1, cpu_online_mask)) { if (dev->cpu == 0 && cpumask_test_cpu(1, cpu_online_mask)) {
...@@ -197,12 +204,6 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev, ...@@ -197,12 +204,6 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev,
} }
} }
/*
* Call idle CPU PM exit notifier chain to restore
* VFP and per CPU IRQ context.
*/
cpu_pm_exit();
/* /*
* Call idle CPU cluster PM exit notifier chain * Call idle CPU cluster PM exit notifier chain
* to restore GIC and wakeupgen context. * to restore GIC and wakeupgen context.
...@@ -210,6 +211,13 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev, ...@@ -210,6 +211,13 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev,
if (dev->cpu == 0 && mpuss_can_lose_context) if (dev->cpu == 0 && mpuss_can_lose_context)
cpu_cluster_pm_exit(); cpu_cluster_pm_exit();
/*
* Call idle CPU PM exit notifier chain to restore
* VFP and per CPU IRQ context.
*/
cpu_pm_exit();
cpu_pm_out:
tick_broadcast_exit(); tick_broadcast_exit();
fail: fail:
......
...@@ -191,6 +191,7 @@ void omap_sram_idle(void) ...@@ -191,6 +191,7 @@ void omap_sram_idle(void)
int per_next_state = PWRDM_POWER_ON; int per_next_state = PWRDM_POWER_ON;
int core_next_state = PWRDM_POWER_ON; int core_next_state = PWRDM_POWER_ON;
u32 sdrc_pwr = 0; u32 sdrc_pwr = 0;
int error;
mpu_next_state = pwrdm_read_next_pwrst(mpu_pwrdm); mpu_next_state = pwrdm_read_next_pwrst(mpu_pwrdm);
switch (mpu_next_state) { switch (mpu_next_state) {
...@@ -219,8 +220,11 @@ void omap_sram_idle(void) ...@@ -219,8 +220,11 @@ void omap_sram_idle(void)
pwrdm_pre_transition(NULL); pwrdm_pre_transition(NULL);
/* PER */ /* PER */
if (per_next_state == PWRDM_POWER_OFF) if (per_next_state == PWRDM_POWER_OFF) {
cpu_cluster_pm_enter(); error = cpu_cluster_pm_enter();
if (error)
return;
}
/* CORE */ /* CORE */
if (core_next_state < PWRDM_POWER_ON) { if (core_next_state < PWRDM_POWER_ON) {
......
...@@ -1102,23 +1102,13 @@ static void omap_gpio_idle(struct gpio_bank *bank, bool may_lose_context) ...@@ -1102,23 +1102,13 @@ static void omap_gpio_idle(struct gpio_bank *bank, bool may_lose_context)
{ {
struct device *dev = bank->chip.parent; struct device *dev = bank->chip.parent;
void __iomem *base = bank->base; void __iomem *base = bank->base;
u32 mask, nowake; u32 nowake;
bank->saved_datain = readl_relaxed(base + bank->regs->datain); bank->saved_datain = readl_relaxed(base + bank->regs->datain);
if (!bank->enabled_non_wakeup_gpios) if (!bank->enabled_non_wakeup_gpios)
goto update_gpio_context_count; goto update_gpio_context_count;
/* Check for pending EDGE_FALLING, ignore EDGE_BOTH */
mask = bank->enabled_non_wakeup_gpios & bank->context.fallingdetect;
mask &= ~bank->context.risingdetect;
bank->saved_datain |= mask;
/* Check for pending EDGE_RISING, ignore EDGE_BOTH */
mask = bank->enabled_non_wakeup_gpios & bank->context.risingdetect;
mask &= ~bank->context.fallingdetect;
bank->saved_datain &= ~mask;
if (!may_lose_context) if (!may_lose_context)
goto update_gpio_context_count; goto update_gpio_context_count;
...@@ -1237,26 +1227,35 @@ static int gpio_omap_cpu_notifier(struct notifier_block *nb, ...@@ -1237,26 +1227,35 @@ static int gpio_omap_cpu_notifier(struct notifier_block *nb,
{ {
struct gpio_bank *bank; struct gpio_bank *bank;
unsigned long flags; unsigned long flags;
int ret = NOTIFY_OK;
u32 isr, mask;
bank = container_of(nb, struct gpio_bank, nb); bank = container_of(nb, struct gpio_bank, nb);
raw_spin_lock_irqsave(&bank->lock, flags); raw_spin_lock_irqsave(&bank->lock, flags);
if (bank->is_suspended)
goto out_unlock;
switch (cmd) { switch (cmd) {
case CPU_CLUSTER_PM_ENTER: case CPU_CLUSTER_PM_ENTER:
if (bank->is_suspended) mask = omap_get_gpio_irqbank_mask(bank);
isr = readl_relaxed(bank->base + bank->regs->irqstatus) & mask;
if (isr) {
ret = NOTIFY_BAD;
break; break;
}
omap_gpio_idle(bank, true); omap_gpio_idle(bank, true);
break; break;
case CPU_CLUSTER_PM_ENTER_FAILED: case CPU_CLUSTER_PM_ENTER_FAILED:
case CPU_CLUSTER_PM_EXIT: case CPU_CLUSTER_PM_EXIT:
if (bank->is_suspended)
break;
omap_gpio_unidle(bank); omap_gpio_unidle(bank);
break; break;
} }
out_unlock:
raw_spin_unlock_irqrestore(&bank->lock, flags); raw_spin_unlock_irqrestore(&bank->lock, flags);
return NOTIFY_OK; return ret;
} }
static const struct omap_gpio_reg_offs omap2_gpio_regs = { static const struct omap_gpio_reg_offs omap2_gpio_regs = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment