Skip to content

Commit 10a144b

Browse files
tmlindgregkh
authored andcommitted
ARM: OMAP2+: Handle errors for cpu_pm
[ Upstream commit 55be2f5 ] We need to check for errors when calling cpu_pm_enter() and cpu_cluster_pm_enter(). And we need to bail out on errors as otherwise we can enter a deeper idle state when not desired. I'm not aware of the lack of error handling causing issues yet, but we need this at least for blocking deeper idle states when a GPIO instance has pending interrupts. Cc: Dave Gerlach <d-gerlach@ti.com> Cc: Grygorii Strashko <grygorii.strashko@ti.com> Cc: Keerthy <j-keerthy@ti.com> Cc: Ladislav Michl <ladis@linux-mips.org> Cc: Russell King <rmk+kernel@armlinux.org.uk> Cc: Tero Kristo <t-kristo@ti.com> Signed-off-by: Tony Lindgren <tony@atomide.com> Link: https://lore.kernel.org/r/20200304225433.37336-2-tony@atomide.com Signed-off-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent d1a749c commit 10a144b

3 files changed

Lines changed: 30 additions & 13 deletions

File tree

arch/arm/mach-omap2/cpuidle34xx.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ static int omap3_enter_idle(struct cpuidle_device *dev,
109109
int index)
110110
{
111111
struct omap3_idle_statedata *cx = &omap3_idle_data[index];
112+
int error;
112113

113114
if (omap_irq_pending() || need_resched())
114115
goto return_sleep_time;
@@ -125,8 +126,11 @@ static int omap3_enter_idle(struct cpuidle_device *dev,
125126
* Call idle CPU PM enter notifier chain so that
126127
* VFP context is saved.
127128
*/
128-
if (cx->mpu_state == PWRDM_POWER_OFF)
129-
cpu_pm_enter();
129+
if (cx->mpu_state == PWRDM_POWER_OFF) {
130+
error = cpu_pm_enter();
131+
if (error)
132+
goto out_clkdm_set;
133+
}
130134

131135
/* Execute ARM wfi */
132136
omap_sram_idle();
@@ -139,6 +143,7 @@ static int omap3_enter_idle(struct cpuidle_device *dev,
139143
pwrdm_read_prev_pwrst(mpu_pd) == PWRDM_POWER_OFF)
140144
cpu_pm_exit();
141145

146+
out_clkdm_set:
142147
/* Re-allow idle for C1 */
143148
if (cx->flags & OMAP_CPUIDLE_CX_NO_CLKDM_IDLE)
144149
clkdm_allow_idle(mpu_pd->pwrdm_clkdms[0]);

arch/arm/mach-omap2/cpuidle44xx.c

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev,
122122
{
123123
struct idle_statedata *cx = state_ptr + index;
124124
u32 mpuss_can_lose_context = 0;
125+
int error;
125126

126127
/*
127128
* 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,
159160
* Call idle CPU PM enter notifier chain so that
160161
* VFP and per CPU interrupt context is saved.
161162
*/
162-
cpu_pm_enter();
163+
error = cpu_pm_enter();
164+
if (error)
165+
goto cpu_pm_out;
163166

164167
if (dev->cpu == 0) {
165168
pwrdm_set_logic_retst(mpu_pd, cx->mpu_logic_state);
@@ -169,13 +172,17 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev,
169172
* Call idle CPU cluster PM enter notifier chain
170173
* to save GIC and wakeupgen context.
171174
*/
172-
if (mpuss_can_lose_context)
173-
cpu_cluster_pm_enter();
175+
if (mpuss_can_lose_context) {
176+
error = cpu_cluster_pm_enter();
177+
if (error)
178+
goto cpu_cluster_pm_out;
179+
}
174180
}
175181

176182
omap4_enter_lowpower(dev->cpu, cx->cpu_state);
177183
cpu_done[dev->cpu] = true;
178184

185+
cpu_cluster_pm_out:
179186
/* Wakeup CPU1 only if it is not offlined */
180187
if (dev->cpu == 0 && cpumask_test_cpu(1, cpu_online_mask)) {
181188

@@ -197,19 +204,20 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev,
197204
}
198205
}
199206

200-
/*
201-
* Call idle CPU PM exit notifier chain to restore
202-
* VFP and per CPU IRQ context.
203-
*/
204-
cpu_pm_exit();
205-
206207
/*
207208
* Call idle CPU cluster PM exit notifier chain
208209
* to restore GIC and wakeupgen context.
209210
*/
210211
if (dev->cpu == 0 && mpuss_can_lose_context)
211212
cpu_cluster_pm_exit();
212213

214+
/*
215+
* Call idle CPU PM exit notifier chain to restore
216+
* VFP and per CPU IRQ context.
217+
*/
218+
cpu_pm_exit();
219+
220+
cpu_pm_out:
213221
tick_broadcast_exit();
214222

215223
fail:

arch/arm/mach-omap2/pm34xx.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ void omap_sram_idle(void)
194194
int per_next_state = PWRDM_POWER_ON;
195195
int core_next_state = PWRDM_POWER_ON;
196196
u32 sdrc_pwr = 0;
197+
int error;
197198

198199
mpu_next_state = pwrdm_read_next_pwrst(mpu_pwrdm);
199200
switch (mpu_next_state) {
@@ -222,8 +223,11 @@ void omap_sram_idle(void)
222223
pwrdm_pre_transition(NULL);
223224

224225
/* PER */
225-
if (per_next_state == PWRDM_POWER_OFF)
226-
cpu_cluster_pm_enter();
226+
if (per_next_state == PWRDM_POWER_OFF) {
227+
error = cpu_cluster_pm_enter();
228+
if (error)
229+
return;
230+
}
227231

228232
/* CORE */
229233
if (core_next_state < PWRDM_POWER_ON) {

0 commit comments

Comments
 (0)