pm: device: Remove transitional states

PM_DEVICE_STATE_RESUMING and PM_DEVICE_STATE_SUSPENDING
are transitional states and are only used in device runtime. Remove it
and use device flag to keep track of a transition.

Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
This commit is contained in:
Flavio Ceolin 2021-08-26 22:44:58 -07:00 committed by Anas Nashif
commit d9d5c41294
4 changed files with 18 additions and 30 deletions

View file

@ -253,16 +253,6 @@ The four device power states:
Most device context is lost by the hardware. Device drivers must save and
restore or reinitialize any context lost by the hardware.
:code:`PM_DEVICE_STATE_SUSPENDING`
Device is currently transitioning from :c:macro:`PM_DEVICE_STATE_ACTIVE` to
:c:macro:`PM_DEVICE_STATE_SUSPENDED`.
:code:`PM_DEVICE_STATE_RESUMING`
Device is currently transitioning from :c:macro:`PM_DEVICE_STATE_SUSPENDED`
to :c:macro:`PM_DEVICE_STATE_ACTIVE`.
:code:`PM_DEVICE_STATE_OFF`
Power has been fully removed from the device. The device context is lost

View file

@ -48,11 +48,7 @@ enum pm_device_state {
* @note
* Device context is lost.
*/
PM_DEVICE_STATE_OFF,
/** Device is being resumed. */
PM_DEVICE_STATE_RESUMING,
/** Device is being suspended. */
PM_DEVICE_STATE_SUSPENDING,
PM_DEVICE_STATE_OFF
};
/** @brief Device PM flags. */
@ -66,6 +62,8 @@ enum pm_device_flag {
PM_DEVICE_FLAGS_WS_CAPABLE,
/** Indicates if the device is being used as wakeup source. */
PM_DEVICE_FLAGS_WS_ENABLED,
/** Indicates that the device is changing its state */
PM_DEVICE_FLAG_TRANSITIONING,
/** Number of flags (internal use only). */
PM_DEVICE_FLAG_COUNT
};
@ -161,8 +159,9 @@ const char *pm_device_state_str(enum pm_device_state state);
*
* @retval 0 If successful.
* @retval -ENOTSUP If requested state is not supported.
* @retval -EALREADY If device is already at (or transitioning to) the requested
* state.
* @retval -EALREADY If device is already at the requested state.
* @retval -EBUSY If device is changing its state.
* @retval Errno Other negative errno on failure.
*/
int pm_device_state_set(const struct device *dev,

View file

@ -103,10 +103,13 @@ int pm_device_state_set(const struct device *dev,
return -ENOSYS;
}
if (atomic_test_bit(&dev->pm->flags, PM_DEVICE_FLAG_TRANSITIONING)) {
return -EBUSY;
}
switch (state) {
case PM_DEVICE_STATE_SUSPENDED:
if ((dev->pm->state == PM_DEVICE_STATE_SUSPENDED) ||
(dev->pm->state == PM_DEVICE_STATE_SUSPENDING)) {
if (dev->pm->state == PM_DEVICE_STATE_SUSPENDED) {
return -EALREADY;
} else if (dev->pm->state == PM_DEVICE_STATE_OFF) {
return -ENOTSUP;
@ -115,8 +118,7 @@ int pm_device_state_set(const struct device *dev,
action = PM_DEVICE_ACTION_SUSPEND;
break;
case PM_DEVICE_STATE_ACTIVE:
if ((dev->pm->state == PM_DEVICE_STATE_ACTIVE) ||
(dev->pm->state == PM_DEVICE_STATE_RESUMING)) {
if (dev->pm->state == PM_DEVICE_STATE_ACTIVE) {
return -EALREADY;
}

View file

@ -24,6 +24,9 @@ static void pm_device_runtime_state_set(struct pm_device *pm)
const struct device *dev = pm->dev;
int ret = 0;
/* Clear transitioning flags */
atomic_clear_bit(&dev->pm->flags, PM_DEVICE_FLAG_TRANSITIONING);
switch (dev->pm->state) {
case PM_DEVICE_STATE_ACTIVE:
if ((dev->pm->usage == 0) && dev->pm->enable) {
@ -35,11 +38,6 @@ static void pm_device_runtime_state_set(struct pm_device *pm)
ret = pm_device_state_set(dev, PM_DEVICE_STATE_ACTIVE);
}
break;
case PM_DEVICE_STATE_SUSPENDING:
__fallthrough;
case PM_DEVICE_STATE_RESUMING:
/* Do nothing: We are waiting for resume/suspend to finish */
break;
default:
LOG_ERR("Invalid state!!\n");
}
@ -127,13 +125,13 @@ static int pm_device_request(const struct device *dev,
/* Return in case of Async request */
if (pm_flags & PM_DEVICE_ASYNC) {
atomic_set_bit(&dev->pm->flags, PM_DEVICE_FLAG_TRANSITIONING);
(void)k_work_schedule(&dev->pm->work, K_NO_WAIT);
goto out_unlock;
}
while ((k_work_delayable_is_pending(&dev->pm->work)) ||
(dev->pm->state == PM_DEVICE_STATE_SUSPENDING) ||
(dev->pm->state == PM_DEVICE_STATE_RESUMING)) {
atomic_test_bit(&dev->pm->flags, PM_DEVICE_FLAG_TRANSITIONING)) {
ret = k_condvar_wait(&dev->pm->condvar, &dev->pm->lock,
K_FOREVER);
if (ret != 0) {
@ -238,8 +236,7 @@ int pm_device_wait(const struct device *dev, k_timeout_t timeout)
k_mutex_lock(&dev->pm->lock, K_FOREVER);
while ((k_work_delayable_is_pending(&dev->pm->work)) ||
(dev->pm->state == PM_DEVICE_STATE_SUSPENDING) ||
(dev->pm->state == PM_DEVICE_STATE_RESUMING)) {
atomic_test_bit(&dev->pm->flags, PM_DEVICE_FLAG_TRANSITIONING)) {
ret = k_condvar_wait(&dev->pm->condvar, &dev->pm->lock,
timeout);
if (ret != 0) {