pm: device: Add pm_device_action_run

Devices PM callback receive an action and not a state. Add a new API
that receives an action instead of a state.

Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
This commit is contained in:
Flavio Ceolin 2021-11-22 15:32:17 -08:00 committed by Christopher Friedt
commit 9adffd620a
2 changed files with 70 additions and 0 deletions

View file

@ -293,6 +293,25 @@ int pm_device_state_set(const struct device *dev,
int pm_device_state_get(const struct device *dev, int pm_device_state_get(const struct device *dev,
enum pm_device_state *state); enum pm_device_state *state);
/**
* @brief Run a pm action on a device.
*
* This function calls the device PM control callback so that the device does
* the necessary operations to execute the given action.
*
* @param dev Device instance.
* @param action Device pm action.
*
* @retval 0 If successful.
* @retval -ENOTSUP If requested state is not supported.
* @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 Errno Other negative errno on failure.
*/
int pm_device_action_run(const struct device *dev,
enum pm_device_action action);
#if defined(CONFIG_PM_DEVICE) || defined(__DOXYGEN__) #if defined(CONFIG_PM_DEVICE) || defined(__DOXYGEN__)
/** /**
* @brief Mark a device as busy. * @brief Mark a device as busy.

View file

@ -73,6 +73,57 @@ int pm_device_state_set(const struct device *dev,
return 0; return 0;
} }
int pm_device_action_run(const struct device *dev,
enum pm_device_action action)
{
int ret;
enum pm_device_state state;
struct pm_device *pm = dev->pm;
if (pm == NULL) {
return -ENOSYS;
}
switch (action) {
case PM_DEVICE_ACTION_FORCE_SUSPEND:
__fallthrough;
case PM_DEVICE_ACTION_SUSPEND:
if (pm->state == PM_DEVICE_STATE_SUSPENDED) {
return -EALREADY;
} else if (pm->state == PM_DEVICE_STATE_OFF) {
return -ENOTSUP;
}
state = PM_DEVICE_STATE_SUSPENDED;
break;
case PM_DEVICE_ACTION_RESUME:
if (pm->state == PM_DEVICE_STATE_ACTIVE) {
return -EALREADY;
}
state = PM_DEVICE_STATE_ACTIVE;
break;
case PM_DEVICE_ACTION_TURN_OFF:
if (pm->state == PM_DEVICE_STATE_OFF) {
return -EALREADY;
}
state = PM_DEVICE_STATE_OFF;
break;
default:
return -ENOTSUP;
}
ret = pm->action_cb(dev, action);
if (ret < 0) {
return ret;
}
pm->state = state;
return 0;
}
int pm_device_state_get(const struct device *dev, int pm_device_state_get(const struct device *dev,
enum pm_device_state *state) enum pm_device_state *state)
{ {