Commit cd16d17d authored by Bjarki Arge Andreasen's avatar Bjarki Arge Andreasen Committed by Chris Friedt
Browse files

pm: device: introduce pm_device_driver_deinit()



Introduce pm_device_driver_deinit() which is required to fully
support device_deinit(). This function shall be called by drivers
when device_deinit() is called.

If PM_DEVICE is enabled, it will
simply check whether the device is either SUSPENDED or OFF, this
will prevent device_deinit() on a device which is currently in
use, and ensure the device is in the correct state if device_init()
is called later.

If PM_DEVICE is not enabled, it will invoke the SUSPEND action which
mirrors the pm_device_driver_init() behavior. Note that TURN_OFF
action is not called since the device is deinitialized after this
call.

Signed-off-by: default avatarBjarki Arge Andreasen <bjarki.andreasen@nordicsemi.no>
parent 6821b5b3
Loading
Loading
Loading
Loading
+24 −0
Original line number Diff line number Diff line
@@ -646,6 +646,25 @@ bool pm_device_is_powered(const struct device *dev);
 */
int pm_device_driver_init(const struct device *dev, pm_device_action_cb_t action_cb);

/**
 * @brief Prepare PM device for device driver deinit
 *
 * @details Ensures device is either SUSPENDED or OFF. If CONFIG_PM_DEVICE=y,
 * the function checks whether power management has moved the device to
 * either the SUSPENDED or OFF states. If CONFIG_PM_DEVICE=n, the function
 * uses the device driver's internal PM hook to move the device to the
 * SUSPENDED state.
 *
 * @note This function must be called at the beginning of a driver's deinit
 * function.
 *
 * @param dev Device instance.
 * @param action_cb Device PM control callback function.
 * @retval 0 if success.
 * @retval -EBUSY Device is not SUSPENDED nor OFF
 * @retval -errno code if failure.
 */
int pm_device_driver_deinit(const struct device *dev, pm_device_action_cb_t action_cb);
#else
static inline int pm_device_state_get(const struct device *dev,
				      enum pm_device_state *state)
@@ -742,6 +761,11 @@ static inline int pm_device_driver_init(const struct device *dev, pm_device_acti
	return 0;
}

static inline int pm_device_driver_deinit(const struct device *dev, pm_device_action_cb_t action_cb)
{
	return action_cb(dev, PM_DEVICE_ACTION_SUSPEND);
}

#endif /* CONFIG_PM_DEVICE */

/** @} */
+11 −0
Original line number Diff line number Diff line
@@ -401,3 +401,14 @@ int pm_device_driver_init(const struct device *dev,
	/* Return the PM_DEVICE_ACTION_RESUME result */
	return rc;
}

int pm_device_driver_deinit(const struct device *dev,
			    pm_device_action_cb_t action_cb)
{
	struct pm_device_base *pm = dev->pm_base;

	return pm->state == PM_DEVICE_STATE_SUSPENDED ||
	       pm->state == PM_DEVICE_STATE_OFF ?
	       0 :
	       -EBUSY;
}