diff --git a/include/zephyr/pm/device.h b/include/zephyr/pm/device.h index 1161d6aabae..023d35b3d37 100644 --- a/include/zephyr/pm/device.h +++ b/include/zephyr/pm/device.h @@ -124,12 +124,12 @@ struct pm_device { const struct device *dev; /** Lock to synchronize the get/put operations */ struct k_mutex lock; + /** Event var to listen to the sync request events */ + struct k_event event; /** Device usage count */ uint32_t usage; /** Work object for asynchronous calls */ struct k_work_delayable work; - /** Event conditional var to listen to the sync request events */ - struct k_condvar condvar; #endif /* CONFIG_PM_DEVICE_RUNTIME */ #ifdef CONFIG_PM_DEVICE_POWER_DOMAIN /** Power Domain it belongs */ @@ -148,7 +148,7 @@ struct pm_device { #ifdef CONFIG_PM_DEVICE_RUNTIME #define Z_PM_DEVICE_RUNTIME_INIT(obj) \ .lock = Z_MUTEX_INITIALIZER(obj.lock), \ - .condvar = Z_CONDVAR_INITIALIZER(obj.condvar), + .event = Z_EVENT_INITIALIZER(obj.event), #else #define Z_PM_DEVICE_RUNTIME_INIT(obj) #endif /* CONFIG_PM_DEVICE_RUNTIME */ diff --git a/subsys/pm/Kconfig b/subsys/pm/Kconfig index a1f02a1279a..4395e771859 100644 --- a/subsys/pm/Kconfig +++ b/subsys/pm/Kconfig @@ -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 diff --git a/subsys/pm/device_runtime.c b/subsys/pm/device_runtime.c index bc105193d12..55cc645faee 100644 --- a/subsys/pm/device_runtime.c +++ b/subsys/pm/device_runtime.c @@ -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); } }