forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-01-31 f9004dbfff8a3fbbd7e2a88c8a4327c7f2f8e5b2
kernel/arch/arm/mach-omap2/cpuidle44xx.c
....@@ -1,13 +1,10 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * OMAP4+ CPU idle Routines
34 *
45 * Copyright (C) 2011-2013 Texas Instruments, Inc.
56 * Santosh Shilimkar <santosh.shilimkar@ti.com>
67 * Rajendra Nayak <rnayak@ti.com>
7
- *
8
- * This program is free software; you can redistribute it and/or modify
9
- * it under the terms of the GNU General Public License version 2 as
10
- * published by the Free Software Foundation.
118 */
129
1310 #include <linux/sched.h>
....@@ -125,6 +122,7 @@
125122 {
126123 struct idle_statedata *cx = state_ptr + index;
127124 u32 mpuss_can_lose_context = 0;
125
+ int error;
128126
129127 /*
130128 * CPU0 has to wait and stay ON until CPU1 is OFF state.
....@@ -153,27 +151,37 @@
153151 (cx->mpu_logic_state == PWRDM_POWER_OFF);
154152
155153 /* Enter broadcast mode for periodic timers */
156
- tick_broadcast_enable();
154
+ RCU_NONIDLE(tick_broadcast_enable());
157155
158156 /* Enter broadcast mode for one-shot timers */
159
- tick_broadcast_enter();
157
+ RCU_NONIDLE(tick_broadcast_enter());
160158
161159 /*
162160 * Call idle CPU PM enter notifier chain so that
163161 * VFP and per CPU interrupt context is saved.
164162 */
165
- cpu_pm_enter();
163
+ error = cpu_pm_enter();
164
+ if (error)
165
+ goto cpu_pm_out;
166166
167167 if (dev->cpu == 0) {
168168 pwrdm_set_logic_retst(mpu_pd, cx->mpu_logic_state);
169
- omap_set_pwrdm_state(mpu_pd, cx->mpu_state);
169
+ RCU_NONIDLE(omap_set_pwrdm_state(mpu_pd, cx->mpu_state));
170170
171171 /*
172172 * Call idle CPU cluster PM enter notifier chain
173173 * to save GIC and wakeupgen context.
174174 */
175
- if (mpuss_can_lose_context)
176
- cpu_cluster_pm_enter();
175
+ if (mpuss_can_lose_context) {
176
+ error = cpu_cluster_pm_enter();
177
+ if (error) {
178
+ index = 0;
179
+ cx = state_ptr + index;
180
+ pwrdm_set_logic_retst(mpu_pd, cx->mpu_logic_state);
181
+ RCU_NONIDLE(omap_set_pwrdm_state(mpu_pd, cx->mpu_state));
182
+ mpuss_can_lose_context = 0;
183
+ }
184
+ }
177185 }
178186
179187 omap4_enter_lowpower(dev->cpu, cx->cpu_state);
....@@ -186,9 +194,9 @@
186194 mpuss_can_lose_context)
187195 gic_dist_disable();
188196
189
- clkdm_deny_idle(cpu_clkdm[1]);
190
- omap_set_pwrdm_state(cpu_pd[1], PWRDM_POWER_ON);
191
- clkdm_allow_idle(cpu_clkdm[1]);
197
+ RCU_NONIDLE(clkdm_deny_idle(cpu_clkdm[1]));
198
+ RCU_NONIDLE(omap_set_pwrdm_state(cpu_pd[1], PWRDM_POWER_ON));
199
+ RCU_NONIDLE(clkdm_allow_idle(cpu_clkdm[1]));
192200
193201 if (IS_PM44XX_ERRATUM(PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD) &&
194202 mpuss_can_lose_context) {
....@@ -201,19 +209,20 @@
201209 }
202210
203211 /*
204
- * Call idle CPU PM exit notifier chain to restore
205
- * VFP and per CPU IRQ context.
206
- */
207
- cpu_pm_exit();
208
-
209
- /*
210212 * Call idle CPU cluster PM exit notifier chain
211213 * to restore GIC and wakeupgen context.
212214 */
213215 if (dev->cpu == 0 && mpuss_can_lose_context)
214216 cpu_cluster_pm_exit();
215217
216
- tick_broadcast_exit();
218
+ /*
219
+ * Call idle CPU PM exit notifier chain to restore
220
+ * VFP and per CPU IRQ context.
221
+ */
222
+ cpu_pm_exit();
223
+
224
+cpu_pm_out:
225
+ RCU_NONIDLE(tick_broadcast_exit());
217226
218227 fail:
219228 cpuidle_coupled_parallel_barrier(dev, &abort_barrier);