pm: Account device pm state lock

Do not execute pm operations on devices that the device pm state is
locked.

Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
This commit is contained in:
Flavio Ceolin 2021-11-17 21:50:08 -08:00 committed by Anas Nashif
commit 0a32eadd13
4 changed files with 16 additions and 3 deletions

View file

@ -298,6 +298,7 @@ const char *pm_device_state_str(enum pm_device_state state);
* @retval -EALREADY If device is already at the requested state.
* @retval -EBUSY If device is changing its state.
* @retval -ENOSYS If device does not support PM.
* @retval -EPERM If device has power state locked.
* @retval Errno Other negative errno on failure.
*/
__deprecated int pm_device_state_set(const struct device *dev,
@ -418,6 +419,8 @@ bool pm_device_wakeup_is_capable(const struct device *dev);
* system power management or device runtime power
* management until unlocked.
*
* @note The given device should not have device runtime enabled.
*
* @see pm_device_state_unlock
*
* @param dev Device instance.

View file

@ -6,6 +6,7 @@
#include <device.h>
#include <pm/device.h>
#include <pm/device_runtime.h>
#include <logging/log.h>
LOG_MODULE_REGISTER(pm_device, CONFIG_PM_DEVICE_LOG_LEVEL);
@ -35,6 +36,10 @@ int pm_device_state_set(const struct device *dev,
return -ENOSYS;
}
if (pm_device_state_is_locked(dev)) {
return -EPERM;
}
switch (state) {
case PM_DEVICE_STATE_SUSPENDED:
if (pm->state == PM_DEVICE_STATE_SUSPENDED) {
@ -246,7 +251,7 @@ void pm_device_state_lock(const struct device *dev)
{
struct pm_device *pm = dev->pm;
if (pm != NULL) {
if ((pm != NULL) && !pm_device_runtime_is_enabled(dev)) {
atomic_set_bit(&pm->flags, PM_DEVICE_FLAG_STATE_LOCKED);
}
}

View file

@ -172,6 +172,10 @@ void pm_device_runtime_enable(const struct device *dev)
SYS_PORT_TRACING_FUNC_ENTER(pm, device_runtime_enable, dev);
if (pm_device_state_is_locked(dev)) {
goto end;
}
if (!k_is_pre_kernel()) {
(void)k_mutex_lock(&pm->lock, K_FOREVER);
}
@ -195,6 +199,7 @@ unlock:
k_mutex_unlock(&pm->lock);
}
end:
SYS_PORT_TRACING_FUNC_EXIT(pm, device_runtime_enable, dev);
}

View file

@ -56,8 +56,8 @@ static int pm_suspend_devices(void)
* ignore busy devices, wake up source and devices with
* runtime PM enabled.
*/
if (pm_device_is_busy(dev) ||
pm_device_wakeup_is_enabled(dev) ||
if (pm_device_is_busy(dev) || pm_device_state_is_locked(dev)
|| pm_device_wakeup_is_enabled(dev) ||
((dev->pm != NULL) && pm_device_runtime_is_enabled(dev))) {
continue;
}