Skip to content

Commit 10b4677

Browse files
committed
[nrf fromtree] 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]> (cherry picked from commit 336e89e)
1 parent 34106e6 commit 10b4677

File tree

2 files changed

+43
-2
lines changed

2 files changed

+43
-2
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: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,23 @@ 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+
(void)atomic_inc(&global_lock_cnt);
54+
}
55+
56+
void pm_policy_state_all_lock_put(void)
57+
{
58+
__ASSERT(global_lock_cnt > 0, "Unbalanced state lock get/put");
59+
(void)atomic_dec(&global_lock_cnt);
60+
}
61+
62+
5063
void pm_policy_state_lock_get(enum pm_state state, uint8_t substate_id)
5164
{
5265
#if DT_HAS_COMPAT_STATUS_OKAY(zephyr_power_state)
@@ -106,7 +119,8 @@ bool pm_policy_state_lock_is_active(enum pm_state state, uint8_t substate_id)
106119
for (size_t i = 0; i < ARRAY_SIZE(substates); i++) {
107120
if (substates[i].state == state &&
108121
(substates[i].substate_id == substate_id || substate_id == PM_ALL_SUBSTATES)) {
109-
return atomic_get(&lock_cnt[i]) != 0;
122+
return (atomic_get(&global_lock_cnt) != 0) ||
123+
(atomic_get(&lock_cnt[i]) != 0);
110124
}
111125
}
112126
#endif
@@ -117,6 +131,10 @@ bool pm_policy_state_lock_is_active(enum pm_state state, uint8_t substate_id)
117131
bool pm_policy_state_is_available(enum pm_state state, uint8_t substate_id)
118132
{
119133
#if DT_HAS_COMPAT_STATUS_OKAY(zephyr_power_state)
134+
if (atomic_get(&global_lock_cnt) != 0) {
135+
return false;
136+
}
137+
120138
for (size_t i = 0; i < ARRAY_SIZE(substates); i++) {
121139
if (substates[i].state == state &&
122140
(substates[i].substate_id == substate_id || substate_id == PM_ALL_SUBSTATES)) {
@@ -135,7 +153,8 @@ bool pm_policy_state_any_active(void)
135153
/* Check if there is any power state that is not locked and not disabled due
136154
* to latency requirements.
137155
*/
138-
return atomic_get(&unlock_mask) & atomic_get(&latency_mask);
156+
return (atomic_get(&global_lock_cnt) == 0) &&
157+
(atomic_get(&unlock_mask) & atomic_get(&latency_mask));
139158
#endif
140159
return true;
141160
}

0 commit comments

Comments
 (0)