@@ -31,19 +31,10 @@ static sys_slist_t pm_notifiers = SYS_SLIST_STATIC_INIT(&pm_notifiers);
31
31
IS_ENABLED(CONFIG_PM_PREWAKEUP_CONV_MODE_NEAR) ? k_us_to_ticks_near32(us) : \
32
32
IS_ENABLED(CONFIG_PM_PREWAKEUP_CONV_MODE_CEIL) ? k_us_to_ticks_ceil32(us) : \
33
33
k_us_to_ticks_floor32(us)
34
- /*
35
- * Properly initialize cpu power states. Do not make assumptions that
36
- * ACTIVE_STATE is 0
37
- */
38
- #define CPU_PM_STATE_INIT (_ , __ ) \
39
- { .state = PM_STATE_ACTIVE }
40
- static struct pm_state_info z_cpus_pm_state [] = {
41
- LISTIFY (CONFIG_MP_MAX_NUM_CPUS , CPU_PM_STATE_INIT , (,))
42
- };
43
34
44
- static struct pm_state_info z_cpus_pm_forced_state [] = {
45
- LISTIFY ( CONFIG_MP_MAX_NUM_CPUS , CPU_PM_STATE_INIT , (,))
46
- } ;
35
+ /* State pointers which are set to NULL indicate ACTIVE state. */
36
+ static const struct pm_state_info * z_cpus_pm_state [ CONFIG_MP_MAX_NUM_CPUS ];
37
+ static const struct pm_state_info * z_cpus_pm_forced_state [ CONFIG_MP_MAX_NUM_CPUS ] ;
47
38
48
39
static struct k_spinlock pm_forced_state_lock ;
49
40
static struct k_spinlock pm_notifier_lock ;
@@ -67,7 +58,7 @@ static inline void pm_state_notify(bool entering_state)
67
58
}
68
59
69
60
if (callback ) {
70
- callback (z_cpus_pm_state [CPU_ID ]. state );
61
+ callback (z_cpus_pm_state [CPU_ID ]-> state );
71
62
}
72
63
}
73
64
k_spin_unlock (& pm_notifier_lock , pm_notifier_key );
@@ -115,19 +106,19 @@ void pm_system_resume(void)
115
106
if (atomic_test_and_clear_bit (z_post_ops_required , id )) {
116
107
#ifdef CONFIG_PM_DEVICE_SYSTEM_MANAGED
117
108
if (atomic_add (& _cpus_active , 1 ) == 0 ) {
118
- if ((z_cpus_pm_state [id ]. state != PM_STATE_RUNTIME_IDLE ) &&
119
- !z_cpus_pm_state [id ]. pm_device_disabled ) {
109
+ if ((z_cpus_pm_state [id ]-> state != PM_STATE_RUNTIME_IDLE ) &&
110
+ !z_cpus_pm_state [id ]-> pm_device_disabled ) {
120
111
pm_resume_devices ();
121
112
}
122
113
}
123
114
#endif
124
- pm_state_exit_post_ops (z_cpus_pm_state [id ].state , z_cpus_pm_state [id ].substate_id );
115
+ pm_state_exit_post_ops (z_cpus_pm_state [id ]-> state ,
116
+ z_cpus_pm_state [id ]-> substate_id );
125
117
pm_state_notify (false);
126
118
#ifdef CONFIG_SYS_CLOCK_EXISTS
127
119
sys_clock_idle_exit ();
128
120
#endif /* CONFIG_SYS_CLOCK_EXISTS */
129
- z_cpus_pm_state [id ] = (struct pm_state_info ){PM_STATE_ACTIVE , 0 , false,
130
- 0 , 0 };
121
+ z_cpus_pm_state [id ] = NULL ;
131
122
}
132
123
}
133
124
@@ -138,8 +129,10 @@ bool pm_state_force(uint8_t cpu, const struct pm_state_info *info)
138
129
__ASSERT (info -> state < PM_STATE_COUNT ,
139
130
"Invalid power state %d!" , info -> state );
140
131
132
+ info = pm_state_get (cpu , info -> state , info -> substate_id );
133
+
141
134
key = k_spin_lock (& pm_forced_state_lock );
142
- z_cpus_pm_forced_state [cpu ] = * info ;
135
+ z_cpus_pm_forced_state [cpu ] = info ;
143
136
k_spin_unlock (& pm_forced_state_lock , key );
144
137
145
138
return true;
@@ -162,45 +155,37 @@ bool pm_system_suspend(int32_t kernel_ticks)
162
155
ticks = ticks_expiring_sooner (kernel_ticks , events_ticks );
163
156
164
157
key = k_spin_lock (& pm_forced_state_lock );
165
- if (z_cpus_pm_forced_state [id ]. state != PM_STATE_ACTIVE ) {
158
+ if (z_cpus_pm_forced_state [id ] != NULL ) {
166
159
z_cpus_pm_state [id ] = z_cpus_pm_forced_state [id ];
167
- z_cpus_pm_forced_state [id ]. state = PM_STATE_ACTIVE ;
160
+ z_cpus_pm_forced_state [id ] = NULL ;
168
161
} else {
169
- const struct pm_state_info * info ;
170
-
171
- info = pm_policy_next_state (id , ticks );
172
- if (info != NULL ) {
173
- z_cpus_pm_state [id ] = * info ;
174
- } else {
175
- z_cpus_pm_state [id ].state = PM_STATE_ACTIVE ;
176
- }
162
+ z_cpus_pm_state [id ] = pm_policy_next_state (id , ticks );
177
163
}
178
164
k_spin_unlock (& pm_forced_state_lock , key );
179
165
180
- if (z_cpus_pm_state [id ]. state == PM_STATE_ACTIVE ) {
166
+ if (z_cpus_pm_state [id ] == NULL ) {
181
167
LOG_DBG ("No PM operations done." );
182
- SYS_PORT_TRACING_FUNC_EXIT (pm , system_suspend , ticks ,
183
- z_cpus_pm_state [id ].state );
168
+ SYS_PORT_TRACING_FUNC_EXIT (pm , system_suspend , ticks , PM_STATE_ACTIVE );
184
169
return false;
185
170
}
186
171
187
172
#ifdef CONFIG_PM_DEVICE_SYSTEM_MANAGED
188
173
if (atomic_sub (& _cpus_active , 1 ) == 1 ) {
189
- if ((z_cpus_pm_state [id ]. state != PM_STATE_RUNTIME_IDLE ) &&
190
- !z_cpus_pm_state [id ]. pm_device_disabled ) {
174
+ if ((z_cpus_pm_state [id ]-> state != PM_STATE_RUNTIME_IDLE ) &&
175
+ !z_cpus_pm_state [id ]-> pm_device_disabled ) {
191
176
if (!pm_suspend_devices ()) {
192
177
pm_resume_devices ();
193
- z_cpus_pm_state [id ]. state = PM_STATE_ACTIVE ;
178
+ z_cpus_pm_state [id ] = NULL ;
194
179
(void )atomic_add (& _cpus_active , 1 );
195
180
SYS_PORT_TRACING_FUNC_EXIT (pm , system_suspend , ticks ,
196
- z_cpus_pm_state [ id ]. state );
181
+ PM_STATE_ACTIVE );
197
182
return false;
198
183
}
199
184
}
200
185
}
201
186
#endif
202
187
203
- exit_latency_ticks = EXIT_LATENCY_US_TO_TICKS (z_cpus_pm_state [id ]. exit_latency_us );
188
+ exit_latency_ticks = EXIT_LATENCY_US_TO_TICKS (z_cpus_pm_state [id ]-> exit_latency_us );
204
189
if ((exit_latency_ticks > 0 ) && (ticks != K_TICKS_FOREVER )) {
205
190
/*
206
191
* We need to set the timer to interrupt a little bit early to
@@ -223,15 +208,16 @@ bool pm_system_suspend(int32_t kernel_ticks)
223
208
/* Enter power state */
224
209
pm_state_notify (true);
225
210
atomic_set_bit (z_post_ops_required , id );
226
- pm_state_set (z_cpus_pm_state [id ]. state , z_cpus_pm_state [id ]. substate_id );
211
+ pm_state_set (z_cpus_pm_state [id ]-> state , z_cpus_pm_state [id ]-> substate_id );
227
212
pm_stats_stop ();
228
213
229
214
/* Wake up sequence starts here */
230
- pm_stats_update (z_cpus_pm_state [id ]. state );
215
+ pm_stats_update (z_cpus_pm_state [id ]-> state );
231
216
pm_system_resume ();
232
217
k_sched_unlock ();
233
218
SYS_PORT_TRACING_FUNC_EXIT (pm , system_suspend , ticks ,
234
- z_cpus_pm_state [id ].state );
219
+ z_cpus_pm_state [id ] ?
220
+ z_cpus_pm_state [id ]-> state : PM_STATE_ACTIVE );
235
221
236
222
return true;
237
223
}
@@ -260,5 +246,9 @@ int pm_notifier_unregister(struct pm_notifier *notifier)
260
246
261
247
const struct pm_state_info * pm_state_next_get (uint8_t cpu )
262
248
{
263
- return & z_cpus_pm_state [cpu ];
249
+ static const struct pm_state_info active = {
250
+ .state = PM_STATE_ACTIVE
251
+ };
252
+
253
+ return z_cpus_pm_state [cpu ] ? z_cpus_pm_state [cpu ] : & active ;
264
254
}
0 commit comments