Skip to content

Commit e3e2b74

Browse files
committed
pm: policy: Add option to lock all power states
Add function for getting and putting a lock for all power states. It is much faster version of requesting 0 us latency with actual intention to disable all power states. Signed-off-by: Krzysztof Chruściński <[email protected]>
1 parent 0fb3e47 commit e3e2b74

File tree

2 files changed

+45
-3
lines changed

2 files changed

+45
-3
lines changed

include/zephyr/pm/policy.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ const struct pm_state_info *pm_policy_next_state(uint8_t cpu, int32_t ticks);
112112
*
113113
* @see pm_policy_state_lock_put()
114114
*/
115+
115116
void pm_policy_state_lock_get(enum pm_state state, uint8_t substate_id);
116117

117118
/**
@@ -125,6 +126,18 @@ void pm_policy_state_lock_get(enum pm_state state, uint8_t substate_id);
125126
*/
126127
void pm_policy_state_lock_put(enum pm_state state, uint8_t substate_id);
127128

129+
/**
130+
* @brief Request to lock all power states.
131+
*
132+
* Requests use a reference counter.
133+
*/
134+
void pm_policy_state_all_lock_get(void);
135+
136+
/**
137+
* @brief Release locking of all power states.
138+
*/
139+
void pm_policy_state_all_lock_put(void);
140+
128141
/**
129142
* @brief Apply power state constraints by locking the specified states.
130143
*
@@ -274,6 +287,14 @@ static inline void pm_policy_state_lock_put(enum pm_state state, uint8_t substat
274287
ARG_UNUSED(substate_id);
275288
}
276289

290+
static inline void pm_policy_state_all_lock_get(void)
291+
{
292+
}
293+
294+
static inline void pm_policy_state_all_lock_put(void)
295+
{
296+
}
297+
277298
static inline bool pm_policy_state_lock_is_active(enum pm_state state, uint8_t substate_id)
278299
{
279300
ARG_UNUSED(state);
@@ -344,6 +365,7 @@ static inline void pm_policy_device_power_lock_put(const struct device *dev)
344365
{
345366
ARG_UNUSED(dev);
346367
}
368+
347369
#endif /* CONFIG_PM_POLICY_DEVICE_CONSTRAINTS */
348370

349371
#if defined(CONFIG_PM) || defined(CONFIG_PM_POLICY_LATENCY_STANDALONE) || defined(__DOXYGEN__)

subsys/pm/policy/policy_state_lock.c

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,27 @@ static const struct {
4343
static atomic_t lock_cnt[ARRAY_SIZE(substates)];
4444
static atomic_t latency_mask = BIT_MASK(ARRAY_SIZE(substates));
4545
static atomic_t unlock_mask = BIT_MASK(ARRAY_SIZE(substates));
46+
static atomic_t global_lock_cnt;
4647
static struct k_spinlock lock;
4748

4849
#endif
4950

51+
void pm_policy_state_all_lock_get(void)
52+
{
53+
#if DT_HAS_COMPAT_STATUS_OKAY(zephyr_power_state)
54+
(void)atomic_inc(&global_lock_cnt);
55+
#endif
56+
}
57+
58+
void pm_policy_state_all_lock_put(void)
59+
{
60+
#if DT_HAS_COMPAT_STATUS_OKAY(zephyr_power_state)
61+
__ASSERT(global_lock_cnt > 0, "Unbalanced state lock get/put");
62+
(void)atomic_dec(&global_lock_cnt);
63+
#endif
64+
}
65+
66+
5067
void pm_policy_state_lock_get(enum pm_state state, uint8_t substate_id)
5168
{
5269
#if DT_HAS_COMPAT_STATUS_OKAY(zephyr_power_state)
@@ -106,7 +123,8 @@ bool pm_policy_state_lock_is_active(enum pm_state state, uint8_t substate_id)
106123
for (size_t i = 0; i < ARRAY_SIZE(substates); i++) {
107124
if (substates[i].state == state &&
108125
(substates[i].substate_id == substate_id || substate_id == PM_ALL_SUBSTATES)) {
109-
return atomic_get(&lock_cnt[i]) != 0;
126+
return (atomic_get(&lock_cnt[i]) != 0) ||
127+
(atomic_get(&global_lock_cnt) != 0);
110128
}
111129
}
112130
#endif
@@ -121,7 +139,8 @@ bool pm_policy_state_is_available(enum pm_state state, uint8_t substate_id)
121139
if (substates[i].state == state &&
122140
(substates[i].substate_id == substate_id || substate_id == PM_ALL_SUBSTATES)) {
123141
return (atomic_get(&lock_cnt[i]) == 0) &&
124-
(atomic_get(&latency_mask) & BIT(i));
142+
(atomic_get(&latency_mask) & BIT(i)) &&
143+
(atomic_get(&global_lock_cnt) == 0);
125144
}
126145
}
127146
#endif
@@ -135,7 +154,8 @@ bool pm_policy_state_any_active(void)
135154
/* Check if there is any power state that is not locked and not disabled due
136155
* to latency requirements.
137156
*/
138-
return atomic_get(&unlock_mask) & atomic_get(&latency_mask);
157+
return atomic_get(&unlock_mask) & atomic_get(&latency_mask) &&
158+
(atomic_get(&global_lock_cnt) == 0);
139159
#endif
140160
return true;
141161
}

0 commit comments

Comments
 (0)