diff --git a/doc/services/pm/device_runtime.rst b/doc/services/pm/device_runtime.rst index 5d9df2d8706..b0dd57db02e 100644 --- a/doc/services/pm/device_runtime.rst +++ b/doc/services/pm/device_runtime.rst @@ -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); } diff --git a/include/zephyr/pm/device_runtime.h b/include/zephyr/pm/device_runtime.h index 09bf0c04278..3a320b9ccbc 100644 --- a/include/zephyr/pm/device_runtime.h +++ b/include/zephyr/pm/device_runtime.h @@ -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; } diff --git a/include/zephyr/tracing/tracing.h b/include/zephyr/tracing/tracing.h index baf9632a30d..f1bbddeec51 100644 --- a/include/zephyr/tracing/tracing.h +++ b/include/zephyr/tracing/tracing.h @@ -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. diff --git a/subsys/pm/device_runtime.c b/subsys/pm/device_runtime.c index a4b64fbe994..fb1d3286c54 100644 --- a/subsys/pm/device_runtime.c +++ b/subsys/pm/device_runtime.c @@ -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; } diff --git a/subsys/tracing/ctf/tracing_ctf.h b/subsys/tracing/ctf/tracing_ctf.h index 6b1b03e97d0..986a314f915 100644 --- a/subsys/tracing/ctf/tracing_ctf.h +++ b/subsys/tracing/ctf/tracing_ctf.h @@ -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) diff --git a/subsys/tracing/sysview/SYSVIEW_Zephyr.txt b/subsys/tracing/sysview/SYSVIEW_Zephyr.txt index dfad10e404a..758023d19f7 100644 --- a/subsys/tracing/sysview/SYSVIEW_Zephyr.txt +++ b/subsys/tracing/sysview/SYSVIEW_Zephyr.txt @@ -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 diff --git a/subsys/tracing/sysview/tracing_sysview.h b/subsys/tracing/sysview/tracing_sysview.h index 105cfb1a3ee..8d6e90666f5 100644 --- a/subsys/tracing/sysview/tracing_sysview.h +++ b/subsys/tracing/sysview/tracing_sysview.h @@ -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) \ diff --git a/subsys/tracing/test/tracing_test.h b/subsys/tracing/test/tracing_test.h index 6cf3ee6e583..71b63a762c5 100644 --- a/subsys/tracing/test/tracing_test.h +++ b/subsys/tracing/test/tracing_test.h @@ -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) diff --git a/subsys/tracing/user/tracing_user.h b/subsys/tracing/user/tracing_user.h index ddc6668d68a..c4231503d70 100644 --- a/subsys/tracing/user/tracing_user.h +++ b/subsys/tracing/user/tracing_user.h @@ -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) diff --git a/tests/subsys/pm/device_runtime_api/src/main.c b/tests/subsys/pm/device_runtime_api/src/main.c index 57fd7d8bcc8..292d90e66cf 100644 --- a/tests/subsys/pm/device_runtime_api/src/main.c +++ b/tests/subsys/pm/device_runtime_api/src/main.c @@ -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);