pm: device_runtime: Add delay to async put
Add a delay parameter to asynchronous device runtim put. This allows to delay the put operation what is useful to avoid multiple states transitions. Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
This commit is contained in:
parent
0ea173b774
commit
b5ca7a06b4
|
@ -224,5 +224,5 @@ asynchronous API:
|
|||
...
|
||||
|
||||
/* "put" device (decreases usage count, schedule suspend if no more users) */
|
||||
return pm_device_runtime_put_async(dev);
|
||||
return pm_device_runtime_put_async(dev, K_NO_WAIT);
|
||||
}
|
||||
|
|
|
@ -131,6 +131,7 @@ int pm_device_runtime_put(const struct device *dev);
|
|||
* @funcprops \pre_kernel_ok, \async, \isr_ok
|
||||
*
|
||||
* @param dev Device instance.
|
||||
* @param delay Minimum amount of time before triggering the action.
|
||||
*
|
||||
* @retval 0 If it succeeds. In case device runtime PM is not enabled or not
|
||||
* available this function will be a no-op and will also return 0.
|
||||
|
@ -140,7 +141,7 @@ int pm_device_runtime_put(const struct device *dev);
|
|||
*
|
||||
* @see pm_device_runtime_put()
|
||||
*/
|
||||
int pm_device_runtime_put_async(const struct device *dev);
|
||||
int pm_device_runtime_put_async(const struct device *dev, k_timeout_t delay);
|
||||
|
||||
/**
|
||||
* @brief Check if device runtime is enabled for a given device.
|
||||
|
@ -188,9 +189,11 @@ static inline int pm_device_runtime_put(const struct device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static inline int pm_device_runtime_put_async(const struct device *dev)
|
||||
static inline int pm_device_runtime_put_async(const struct device *dev,
|
||||
k_timeout_t delay)
|
||||
{
|
||||
ARG_UNUSED(dev);
|
||||
ARG_UNUSED(delay);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1954,15 +1954,17 @@
|
|||
/**
|
||||
* @brief Trace putting a device (asynchronously) call entry.
|
||||
* @param dev Device instance.
|
||||
* @param delay Time to delay the operation
|
||||
*/
|
||||
#define sys_port_trace_pm_device_runtime_put_async_enter(dev)
|
||||
#define sys_port_trace_pm_device_runtime_put_async_enter(dev, delay)
|
||||
|
||||
/**
|
||||
* @brief Trace putting a device (asynchronously) call exit.
|
||||
* @param dev Device instance.
|
||||
* @param delay Time to delay the operation.
|
||||
* @param ret Return value.
|
||||
*/
|
||||
#define sys_port_trace_pm_device_runtime_put_async_exit(dev, ret)
|
||||
#define sys_port_trace_pm_device_runtime_put_async_exit(dev, delay, ret)
|
||||
|
||||
/**
|
||||
* @brief Trace enabling device runtime PM call entry.
|
||||
|
|
|
@ -35,6 +35,7 @@ LOG_MODULE_DECLARE(pm_device, CONFIG_PM_DEVICE_LOG_LEVEL);
|
|||
*
|
||||
* @param dev Device instance.
|
||||
* @param async Perform operation asynchronously.
|
||||
* @param delay Period to delay the asynchronous operation.
|
||||
*
|
||||
* @retval 0 If device has been suspended or queued for suspend.
|
||||
* @retval -EALREADY If device is already suspended (can only happen if get/put
|
||||
|
@ -42,7 +43,8 @@ LOG_MODULE_DECLARE(pm_device, CONFIG_PM_DEVICE_LOG_LEVEL);
|
|||
* @retval -EBUSY If the device is busy.
|
||||
* @retval -errno Other negative errno, result of the action callback.
|
||||
*/
|
||||
static int runtime_suspend(const struct device *dev, bool async)
|
||||
static int runtime_suspend(const struct device *dev, bool async,
|
||||
k_timeout_t delay)
|
||||
{
|
||||
int ret = 0;
|
||||
struct pm_device *pm = dev->pm;
|
||||
|
@ -77,7 +79,7 @@ static int runtime_suspend(const struct device *dev, bool async)
|
|||
if (async && !k_is_pre_kernel()) {
|
||||
/* queue suspend */
|
||||
pm->state = PM_DEVICE_STATE_SUSPENDING;
|
||||
(void)k_work_schedule(&pm->work, K_NO_WAIT);
|
||||
(void)k_work_schedule(&pm->work, delay);
|
||||
} else {
|
||||
/* suspend now */
|
||||
ret = pm->action_cb(pm->dev, PM_DEVICE_ACTION_SUSPEND);
|
||||
|
@ -233,7 +235,7 @@ int pm_device_runtime_put(const struct device *dev)
|
|||
}
|
||||
|
||||
SYS_PORT_TRACING_FUNC_ENTER(pm, device_runtime_put, dev);
|
||||
ret = runtime_suspend(dev, false);
|
||||
ret = runtime_suspend(dev, false, K_NO_WAIT);
|
||||
|
||||
/*
|
||||
* Now put the domain
|
||||
|
@ -247,7 +249,7 @@ int pm_device_runtime_put(const struct device *dev)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int pm_device_runtime_put_async(const struct device *dev)
|
||||
int pm_device_runtime_put_async(const struct device *dev, k_timeout_t delay)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
@ -255,9 +257,9 @@ int pm_device_runtime_put_async(const struct device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
SYS_PORT_TRACING_FUNC_ENTER(pm, device_runtime_put_async, dev);
|
||||
ret = runtime_suspend(dev, true);
|
||||
SYS_PORT_TRACING_FUNC_EXIT(pm, device_runtime_put_async, dev, ret);
|
||||
SYS_PORT_TRACING_FUNC_ENTER(pm, device_runtime_put_async, dev, delay);
|
||||
ret = runtime_suspend(dev, true, delay);
|
||||
SYS_PORT_TRACING_FUNC_EXIT(pm, device_runtime_put_async, dev, delay, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -338,8 +338,8 @@ extern "C" {
|
|||
#define sys_port_trace_pm_device_runtime_get_exit(dev, ret)
|
||||
#define sys_port_trace_pm_device_runtime_put_enter(dev)
|
||||
#define sys_port_trace_pm_device_runtime_put_exit(dev, ret)
|
||||
#define sys_port_trace_pm_device_runtime_put_async_enter(dev)
|
||||
#define sys_port_trace_pm_device_runtime_put_async_exit(dev, ret)
|
||||
#define sys_port_trace_pm_device_runtime_put_async_enter(dev, delay)
|
||||
#define sys_port_trace_pm_device_runtime_put_async_exit(dev, delay, ret)
|
||||
#define sys_port_trace_pm_device_runtime_enable_enter(dev)
|
||||
#define sys_port_trace_pm_device_runtime_enable_exit(dev, ret)
|
||||
#define sys_port_trace_pm_device_runtime_disable_enter(dev)
|
||||
|
|
|
@ -164,7 +164,7 @@ TaskState 0xBF 1=dummy, 2=Waiting, 4=New, 8=Terminated, 16=Suspended, 32=Termina
|
|||
156 pm_system_suspend ticks=%u | Returns %Bool
|
||||
157 pm_device_runtime_get dev=%I | Returns %u
|
||||
158 pm_device_runtime_put dev=%I | Returns %u
|
||||
159 pm_device_runtime_put_async dev=%I | Returns %u
|
||||
159 pm_device_runtime_put_async dev=%I, Delay=%TimeOut | Returns %u
|
||||
160 pm_device_runtime_enable dev=%I | Returns %u
|
||||
161 pm_device_runtime_disable dev=%I | Returns %u
|
||||
|
||||
|
|
|
@ -640,10 +640,10 @@ void sys_trace_k_thread_info(struct k_thread *thread);
|
|||
#define sys_port_trace_pm_device_runtime_put_exit(dev, ret) \
|
||||
SEGGER_SYSVIEW_RecordEndCallU32(TID_PM_DEVICE_RUNTIME_PUT, \
|
||||
(uint32_t)ret)
|
||||
#define sys_port_trace_pm_device_runtime_put_async_enter(dev) \
|
||||
#define sys_port_trace_pm_device_runtime_put_async_enter(dev, delay) \
|
||||
SEGGER_SYSVIEW_RecordU32(TID_PM_DEVICE_RUNTIME_PUT_ASYNC, \
|
||||
(uint32_t)(uintptr_t)dev)
|
||||
#define sys_port_trace_pm_device_runtime_put_async_exit(dev, ret) \
|
||||
(uint32_t)(uintptr_t)dev, (uint32_t)delay.ticks)
|
||||
#define sys_port_trace_pm_device_runtime_put_async_exit(dev, delay, ret) \
|
||||
SEGGER_SYSVIEW_RecordEndCallU32(TID_PM_DEVICE_RUNTIME_PUT_ASYNC, \
|
||||
(uint32_t)ret)
|
||||
#define sys_port_trace_pm_device_runtime_enable_enter(dev) \
|
||||
|
|
|
@ -442,8 +442,8 @@
|
|||
#define sys_port_trace_pm_device_runtime_get_exit(dev, ret)
|
||||
#define sys_port_trace_pm_device_runtime_put_enter(dev)
|
||||
#define sys_port_trace_pm_device_runtime_put_exit(dev, ret)
|
||||
#define sys_port_trace_pm_device_runtime_put_async_enter(dev)
|
||||
#define sys_port_trace_pm_device_runtime_put_async_exit(dev, ret)
|
||||
#define sys_port_trace_pm_device_runtime_put_async_enter(dev, delay)
|
||||
#define sys_port_trace_pm_device_runtime_put_async_exit(dev, delay, ret)
|
||||
#define sys_port_trace_pm_device_runtime_enable_enter(dev)
|
||||
#define sys_port_trace_pm_device_runtime_enable_exit(dev, ret)
|
||||
#define sys_port_trace_pm_device_runtime_disable_enter(dev)
|
||||
|
|
|
@ -329,8 +329,8 @@ void sys_trace_idle(void);
|
|||
#define sys_port_trace_pm_device_runtime_get_exit(dev, ret)
|
||||
#define sys_port_trace_pm_device_runtime_put_enter(dev)
|
||||
#define sys_port_trace_pm_device_runtime_put_exit(dev, ret)
|
||||
#define sys_port_trace_pm_device_runtime_put_async_enter(dev)
|
||||
#define sys_port_trace_pm_device_runtime_put_async_exit(dev, ret)
|
||||
#define sys_port_trace_pm_device_runtime_put_async_enter(dev, delay)
|
||||
#define sys_port_trace_pm_device_runtime_put_async_exit(dev, delay, ret)
|
||||
#define sys_port_trace_pm_device_runtime_enable_enter(dev)
|
||||
#define sys_port_trace_pm_device_runtime_enable_exit(dev, ret)
|
||||
#define sys_port_trace_pm_device_runtime_disable_enter(dev)
|
||||
|
|
|
@ -42,7 +42,7 @@ void test_api_setup(void *data)
|
|||
zassert_equal(ret, 0);
|
||||
ret = pm_device_runtime_put(test_dev);
|
||||
zassert_equal(ret, 0);
|
||||
ret = pm_device_runtime_put_async(test_dev);
|
||||
ret = pm_device_runtime_put_async(test_dev, K_NO_WAIT);
|
||||
zassert_equal(ret, 0);
|
||||
|
||||
/* enable runtime PM */
|
||||
|
@ -138,7 +138,7 @@ ZTEST(device_runtime_api, test_api)
|
|||
test_driver_pm_async(test_dev);
|
||||
|
||||
/* usage: 1, -1, suspend: yes (queued) */
|
||||
ret = pm_device_runtime_put_async(test_dev);
|
||||
ret = pm_device_runtime_put_async(test_dev, K_NO_WAIT);
|
||||
zassert_equal(ret, 0);
|
||||
|
||||
(void)pm_device_state_get(test_dev, &state);
|
||||
|
@ -149,7 +149,7 @@ ZTEST(device_runtime_api, test_api)
|
|||
zassert_equal(ret, -EALREADY);
|
||||
|
||||
/* usage: 0, -1, suspend: no (unbalanced call) */
|
||||
ret = pm_device_runtime_put_async(test_dev);
|
||||
ret = pm_device_runtime_put_async(test_dev, K_NO_WAIT);
|
||||
zassert_equal(ret, -EALREADY);
|
||||
|
||||
/* unblock test driver and let it finish */
|
||||
|
@ -171,7 +171,7 @@ ZTEST(device_runtime_api, test_api)
|
|||
test_driver_pm_async(test_dev);
|
||||
|
||||
/* usage: 1, -1, suspend: yes (queued) */
|
||||
ret = pm_device_runtime_put_async(test_dev);
|
||||
ret = pm_device_runtime_put_async(test_dev, K_NO_WAIT);
|
||||
zassert_equal(ret, 0);
|
||||
|
||||
(void)pm_device_state_get(test_dev, &state);
|
||||
|
|
Loading…
Reference in a new issue