pm: runtime: Migrate from condition variables to events

For the async operation move from condition variables to events to
reduce the dependency on the mutexes that cannot be used in IRQ
context.

Signed-off-by: Carlo Caione <ccaione@baylibre.com>
This commit is contained in:
Carlo Caione 2022-12-06 17:44:24 +01:00 committed by Carles Cufí
commit d38a6b4bcd
3 changed files with 20 additions and 7 deletions

View file

@ -104,6 +104,7 @@ config PM_DEVICE_POWER_DOMAIN_DYNAMIC_NUM
config PM_DEVICE_RUNTIME
bool "Runtime Device Power Management"
select EVENTS
help
Enable Runtime Power Management to save power. With device runtime PM
enabled, devices can be suspended or resumed based on the device

View file

@ -19,6 +19,11 @@ LOG_MODULE_DECLARE(pm_device, CONFIG_PM_DEVICE_LOG_LEVEL);
#define PM_DOMAIN(_pm) NULL
#endif
#define EVENT_STATE_ACTIVE BIT(PM_DEVICE_STATE_ACTIVE)
#define EVENT_STATE_SUSPENDED BIT(PM_DEVICE_STATE_SUSPENDED)
#define EVENT_MASK (EVENT_STATE_ACTIVE | EVENT_STATE_SUSPENDED)
/**
* @brief Suspend a device
*
@ -100,7 +105,7 @@ static void runtime_suspend_work(struct k_work *work)
} else {
pm->state = PM_DEVICE_STATE_SUSPENDED;
}
k_condvar_broadcast(&pm->condvar);
k_event_set(&pm->event, BIT(pm->state));
k_mutex_unlock(&pm->lock);
/*
@ -155,7 +160,11 @@ int pm_device_runtime_get(const struct device *dev)
if (!k_is_pre_kernel()) {
/* wait until possible async suspend is completed */
while (pm->state == PM_DEVICE_STATE_SUSPENDING) {
(void)k_condvar_wait(&pm->condvar, &pm->lock, K_FOREVER);
k_mutex_unlock(&pm->lock);
k_event_wait(&pm->event, EVENT_MASK, true, K_FOREVER);
(void)k_mutex_lock(&pm->lock, K_FOREVER);
}
}
@ -292,8 +301,11 @@ int pm_device_runtime_disable(const struct device *dev)
/* wait until possible async suspend is completed */
if (!k_is_pre_kernel()) {
while (pm->state == PM_DEVICE_STATE_SUSPENDING) {
(void)k_condvar_wait(&pm->condvar, &pm->lock,
K_FOREVER);
k_mutex_unlock(&pm->lock);
k_event_wait(&pm->event, EVENT_MASK, true, K_FOREVER);
(void)k_mutex_lock(&pm->lock, K_FOREVER);
}
}