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:
parent
097e08c71a
commit
0a32eadd13
4 changed files with 16 additions and 3 deletions
|
@ -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 -EALREADY If device is already at the requested state.
|
||||||
* @retval -EBUSY If device is changing its state.
|
* @retval -EBUSY If device is changing its state.
|
||||||
* @retval -ENOSYS If device does not support PM.
|
* @retval -ENOSYS If device does not support PM.
|
||||||
|
* @retval -EPERM If device has power state locked.
|
||||||
* @retval Errno Other negative errno on failure.
|
* @retval Errno Other negative errno on failure.
|
||||||
*/
|
*/
|
||||||
__deprecated int pm_device_state_set(const struct device *dev,
|
__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
|
* system power management or device runtime power
|
||||||
* management until unlocked.
|
* management until unlocked.
|
||||||
*
|
*
|
||||||
|
* @note The given device should not have device runtime enabled.
|
||||||
|
*
|
||||||
* @see pm_device_state_unlock
|
* @see pm_device_state_unlock
|
||||||
*
|
*
|
||||||
* @param dev Device instance.
|
* @param dev Device instance.
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#include <device.h>
|
#include <device.h>
|
||||||
#include <pm/device.h>
|
#include <pm/device.h>
|
||||||
|
#include <pm/device_runtime.h>
|
||||||
|
|
||||||
#include <logging/log.h>
|
#include <logging/log.h>
|
||||||
LOG_MODULE_REGISTER(pm_device, CONFIG_PM_DEVICE_LOG_LEVEL);
|
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;
|
return -ENOSYS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pm_device_state_is_locked(dev)) {
|
||||||
|
return -EPERM;
|
||||||
|
}
|
||||||
|
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case PM_DEVICE_STATE_SUSPENDED:
|
case PM_DEVICE_STATE_SUSPENDED:
|
||||||
if (pm->state == 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;
|
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);
|
atomic_set_bit(&pm->flags, PM_DEVICE_FLAG_STATE_LOCKED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -172,6 +172,10 @@ void pm_device_runtime_enable(const struct device *dev)
|
||||||
|
|
||||||
SYS_PORT_TRACING_FUNC_ENTER(pm, device_runtime_enable, 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()) {
|
if (!k_is_pre_kernel()) {
|
||||||
(void)k_mutex_lock(&pm->lock, K_FOREVER);
|
(void)k_mutex_lock(&pm->lock, K_FOREVER);
|
||||||
}
|
}
|
||||||
|
@ -195,6 +199,7 @@ unlock:
|
||||||
k_mutex_unlock(&pm->lock);
|
k_mutex_unlock(&pm->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
end:
|
||||||
SYS_PORT_TRACING_FUNC_EXIT(pm, device_runtime_enable, dev);
|
SYS_PORT_TRACING_FUNC_EXIT(pm, device_runtime_enable, dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,8 +56,8 @@ static int pm_suspend_devices(void)
|
||||||
* ignore busy devices, wake up source and devices with
|
* ignore busy devices, wake up source and devices with
|
||||||
* runtime PM enabled.
|
* runtime PM enabled.
|
||||||
*/
|
*/
|
||||||
if (pm_device_is_busy(dev) ||
|
if (pm_device_is_busy(dev) || pm_device_state_is_locked(dev)
|
||||||
pm_device_wakeup_is_enabled(dev) ||
|
|| pm_device_wakeup_is_enabled(dev) ||
|
||||||
((dev->pm != NULL) && pm_device_runtime_is_enabled(dev))) {
|
((dev->pm != NULL) && pm_device_runtime_is_enabled(dev))) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue