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 Most device context is lost by the hardware. Device drivers must save and
restore or reinitialize any context lost by the hardware. 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` :code:`PM_DEVICE_STATE_OFF`
Power has been fully removed from the device. The device context is lost Power has been fully removed from the device. The device context is lost

View file

@ -48,11 +48,7 @@ enum pm_device_state {
* @note * @note
* Device context is lost. * Device context is lost.
*/ */
PM_DEVICE_STATE_OFF, PM_DEVICE_STATE_OFF
/** Device is being resumed. */
PM_DEVICE_STATE_RESUMING,
/** Device is being suspended. */
PM_DEVICE_STATE_SUSPENDING,
}; };
/** @brief Device PM flags. */ /** @brief Device PM flags. */
@ -66,6 +62,8 @@ enum pm_device_flag {
PM_DEVICE_FLAGS_WS_CAPABLE, PM_DEVICE_FLAGS_WS_CAPABLE,
/** Indicates if the device is being used as wakeup source. */ /** Indicates if the device is being used as wakeup source. */
PM_DEVICE_FLAGS_WS_ENABLED, PM_DEVICE_FLAGS_WS_ENABLED,
/** Indicates that the device is changing its state */
PM_DEVICE_FLAG_TRANSITIONING,
/** Number of flags (internal use only). */ /** Number of flags (internal use only). */
PM_DEVICE_FLAG_COUNT PM_DEVICE_FLAG_COUNT
}; };
@ -161,8 +159,9 @@ const char *pm_device_state_str(enum pm_device_state state);
* *
* @retval 0 If successful. * @retval 0 If successful.
* @retval -ENOTSUP If requested state is not supported. * @retval -ENOTSUP If requested state is not supported.
* @retval -EALREADY If device is already at (or transitioning to) the requested * @retval -EALREADY If device is already at the requested state.
* state. * @retval -EBUSY If device is changing its state.
* @retval Errno Other negative errno on failure. * @retval Errno Other negative errno on failure.
*/ */
int pm_device_state_set(const struct device *dev, 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; return -ENOSYS;
} }
if (atomic_test_bit(&dev->pm->flags, PM_DEVICE_FLAG_TRANSITIONING)) {
return -EBUSY;
}
switch (state) { switch (state) {
case PM_DEVICE_STATE_SUSPENDED: case PM_DEVICE_STATE_SUSPENDED:
if ((dev->pm->state == PM_DEVICE_STATE_SUSPENDED) || if (dev->pm->state == PM_DEVICE_STATE_SUSPENDED) {
(dev->pm->state == PM_DEVICE_STATE_SUSPENDING)) {
return -EALREADY; return -EALREADY;
} else if (dev->pm->state == PM_DEVICE_STATE_OFF) { } else if (dev->pm->state == PM_DEVICE_STATE_OFF) {
return -ENOTSUP; return -ENOTSUP;
@ -115,8 +118,7 @@ int pm_device_state_set(const struct device *dev,
action = PM_DEVICE_ACTION_SUSPEND; action = PM_DEVICE_ACTION_SUSPEND;
break; break;
case PM_DEVICE_STATE_ACTIVE: case PM_DEVICE_STATE_ACTIVE:
if ((dev->pm->state == PM_DEVICE_STATE_ACTIVE) || if (dev->pm->state == PM_DEVICE_STATE_ACTIVE) {
(dev->pm->state == PM_DEVICE_STATE_RESUMING)) {
return -EALREADY; 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; const struct device *dev = pm->dev;
int ret = 0; int ret = 0;
/* Clear transitioning flags */
atomic_clear_bit(&dev->pm->flags, PM_DEVICE_FLAG_TRANSITIONING);
switch (dev->pm->state) { switch (dev->pm->state) {
case PM_DEVICE_STATE_ACTIVE: case PM_DEVICE_STATE_ACTIVE:
if ((dev->pm->usage == 0) && dev->pm->enable) { 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); ret = pm_device_state_set(dev, PM_DEVICE_STATE_ACTIVE);
} }
break; break;
case PM_DEVICE_STATE_SUSPENDING:
__fallthrough;
case PM_DEVICE_STATE_RESUMING:
/* Do nothing: We are waiting for resume/suspend to finish */
break;
default: default:
LOG_ERR("Invalid state!!\n"); LOG_ERR("Invalid state!!\n");
} }
@ -127,13 +125,13 @@ static int pm_device_request(const struct device *dev,
/* Return in case of Async request */ /* Return in case of Async request */
if (pm_flags & PM_DEVICE_ASYNC) { 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); (void)k_work_schedule(&dev->pm->work, K_NO_WAIT);
goto out_unlock; goto out_unlock;
} }
while ((k_work_delayable_is_pending(&dev->pm->work)) || while ((k_work_delayable_is_pending(&dev->pm->work)) ||
(dev->pm->state == PM_DEVICE_STATE_SUSPENDING) || atomic_test_bit(&dev->pm->flags, PM_DEVICE_FLAG_TRANSITIONING)) {
(dev->pm->state == PM_DEVICE_STATE_RESUMING)) {
ret = k_condvar_wait(&dev->pm->condvar, &dev->pm->lock, ret = k_condvar_wait(&dev->pm->condvar, &dev->pm->lock,
K_FOREVER); K_FOREVER);
if (ret != 0) { 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); k_mutex_lock(&dev->pm->lock, K_FOREVER);
while ((k_work_delayable_is_pending(&dev->pm->work)) || while ((k_work_delayable_is_pending(&dev->pm->work)) ||
(dev->pm->state == PM_DEVICE_STATE_SUSPENDING) || atomic_test_bit(&dev->pm->flags, PM_DEVICE_FLAG_TRANSITIONING)) {
(dev->pm->state == PM_DEVICE_STATE_RESUMING)) {
ret = k_condvar_wait(&dev->pm->condvar, &dev->pm->lock, ret = k_condvar_wait(&dev->pm->condvar, &dev->pm->lock,
timeout); timeout);
if (ret != 0) { if (ret != 0) {