From db501ed584e388c249c30bee68f64d466fe08a4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Wed, 10 Jan 2024 11:03:03 +0100 Subject: [PATCH] tests: pm: device_runtime_api: Extend with synchronous device MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extended test to support case when PM device is defined as synchronous. Signed-off-by: Krzysztof Chruściński --- tests/subsys/pm/device_runtime_api/Kconfig | 8 + tests/subsys/pm/device_runtime_api/src/main.c | 160 +++++++++--------- .../pm/device_runtime_api/src/test_driver.c | 18 +- .../pm/device_runtime_api/testcase.yaml | 6 + 4 files changed, 109 insertions(+), 83 deletions(-) create mode 100644 tests/subsys/pm/device_runtime_api/Kconfig diff --git a/tests/subsys/pm/device_runtime_api/Kconfig b/tests/subsys/pm/device_runtime_api/Kconfig new file mode 100644 index 000000000000000..196533c863a6523 --- /dev/null +++ b/tests/subsys/pm/device_runtime_api/Kconfig @@ -0,0 +1,8 @@ +# Copyright 2024 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 + +source "Kconfig.zephyr" + +config TEST_PM_DEVICE_SYNC + bool "Use synchronous PM for the test" diff --git a/tests/subsys/pm/device_runtime_api/src/main.c b/tests/subsys/pm/device_runtime_api/src/main.c index 186ad7e6c783ede..bd7f48315c108ea 100644 --- a/tests/subsys/pm/device_runtime_api/src/main.c +++ b/tests/subsys/pm/device_runtime_api/src/main.c @@ -141,105 +141,111 @@ ZTEST(device_runtime_api, test_api) ret = pm_device_runtime_put_async(test_dev, K_NO_WAIT); zassert_equal(ret, 0); - (void)pm_device_state_get(test_dev, &state); - zassert_equal(state, PM_DEVICE_STATE_SUSPENDING); - - /* usage: 0, -1, suspend: no (unbalanced call) */ - ret = pm_device_runtime_put(test_dev); - zassert_equal(ret, -EALREADY); - - /* usage: 0, -1, suspend: no (unbalanced call) */ - ret = pm_device_runtime_put_async(test_dev, K_NO_WAIT); - zassert_equal(ret, -EALREADY); + if (IS_ENABLED(CONFIG_TEST_PM_DEVICE_SYNC)) { + /* In sync mode async put is equivalent as normal put. */ + (void)pm_device_state_get(test_dev, &state); + zassert_equal(state, PM_DEVICE_STATE_SUSPENDED); + } else { + (void)pm_device_state_get(test_dev, &state); + zassert_equal(state, PM_DEVICE_STATE_SUSPENDING); + + /* usage: 0, -1, suspend: no (unbalanced call) */ + ret = pm_device_runtime_put(test_dev); + zassert_equal(ret, -EALREADY); + + /* usage: 0, -1, suspend: no (unbalanced call) */ + ret = pm_device_runtime_put_async(test_dev, K_NO_WAIT); + zassert_equal(ret, -EALREADY); + + /* unblock test driver and let it finish */ + test_driver_pm_done(test_dev); + k_yield(); - /* unblock test driver and let it finish */ - test_driver_pm_done(test_dev); - k_yield(); + (void)pm_device_state_get(test_dev, &state); + zassert_equal(state, PM_DEVICE_STATE_SUSPENDED); - (void)pm_device_state_get(test_dev, &state); - zassert_equal(state, PM_DEVICE_STATE_SUSPENDED); + /*** get + asynchronous put + get (while suspend still ongoing) ***/ - /*** get + asynchronous put + get (while suspend still ongoing) ***/ + /* usage: 0, +1, resume: yes */ + ret = pm_device_runtime_get(test_dev); + zassert_equal(ret, 0); - /* usage: 0, +1, resume: yes */ - ret = pm_device_runtime_get(test_dev); - zassert_equal(ret, 0); + (void)pm_device_state_get(test_dev, &state); + zassert_equal(state, PM_DEVICE_STATE_ACTIVE); - (void)pm_device_state_get(test_dev, &state); - zassert_equal(state, PM_DEVICE_STATE_ACTIVE); + test_driver_pm_async(test_dev); - test_driver_pm_async(test_dev); + /* usage: 1, -1, suspend: yes (queued) */ + ret = pm_device_runtime_put_async(test_dev, K_NO_WAIT); + zassert_equal(ret, 0); - /* usage: 1, -1, suspend: yes (queued) */ - ret = pm_device_runtime_put_async(test_dev, K_NO_WAIT); - zassert_equal(ret, 0); + (void)pm_device_state_get(test_dev, &state); + zassert_equal(state, PM_DEVICE_STATE_SUSPENDING); - (void)pm_device_state_get(test_dev, &state); - zassert_equal(state, PM_DEVICE_STATE_SUSPENDING); + /* let suspension start */ + k_yield(); - /* let suspension start */ - k_yield(); + /* create and start get_runner thread + * get_runner thread is used to test synchronous path while asynchronous + * is ongoing. It is important to set its priority >= to the system work + * queue to make sure sync path run by the thread is forced to wait. + */ + k_thread_create(&get_runner_td, get_runner_stack, + K_THREAD_STACK_SIZEOF(get_runner_stack), get_runner, + NULL, NULL, NULL, CONFIG_SYSTEM_WORKQUEUE_PRIORITY, 0, + K_NO_WAIT); + k_yield(); - /* create and start get_runner thread - * get_runner thread is used to test synchronous path while asynchronous - * is ongoing. It is important to set its priority >= to the system work - * queue to make sure sync path run by the thread is forced to wait. - */ - k_thread_create(&get_runner_td, get_runner_stack, - K_THREAD_STACK_SIZEOF(get_runner_stack), get_runner, - NULL, NULL, NULL, CONFIG_SYSTEM_WORKQUEUE_PRIORITY, 0, - K_NO_WAIT); - k_yield(); - - /* let driver suspend to finish and wait until get_runner finishes - * resuming the driver - */ - test_driver_pm_done(test_dev); - k_thread_join(&get_runner_td, K_FOREVER); + /* let driver suspend to finish and wait until get_runner finishes + * resuming the driver + */ + test_driver_pm_done(test_dev); + k_thread_join(&get_runner_td, K_FOREVER); - (void)pm_device_state_get(test_dev, &state); - zassert_equal(state, PM_DEVICE_STATE_ACTIVE); + (void)pm_device_state_get(test_dev, &state); + zassert_equal(state, PM_DEVICE_STATE_ACTIVE); - /* Test if getting a device before an async operation starts does - * not trigger any device pm action. - */ - size_t count = test_driver_pm_count(test_dev); + /* Test if getting a device before an async operation starts does + * not trigger any device pm action. + */ + size_t count = test_driver_pm_count(test_dev); - ret = pm_device_runtime_put_async(test_dev, K_MSEC(10)); - zassert_equal(ret, 0); + ret = pm_device_runtime_put_async(test_dev, K_MSEC(10)); + zassert_equal(ret, 0); - (void)pm_device_state_get(test_dev, &state); - zassert_equal(state, PM_DEVICE_STATE_SUSPENDING); + (void)pm_device_state_get(test_dev, &state); + zassert_equal(state, PM_DEVICE_STATE_SUSPENDING); - ret = pm_device_runtime_get(test_dev); - zassert_equal(ret, 0); + ret = pm_device_runtime_get(test_dev); + zassert_equal(ret, 0); - /* Now lets check if the calls above have triggered a device - * pm action - */ - zassert_equal(count, test_driver_pm_count(test_dev)); + /* Now lets check if the calls above have triggered a device + * pm action + */ + zassert_equal(count, test_driver_pm_count(test_dev)); - /* - * test if async put with a delay respects the given time. - */ - ret = pm_device_runtime_put_async(test_dev, K_MSEC(100)); + /* + * test if async put with a delay respects the given time. + */ + ret = pm_device_runtime_put_async(test_dev, K_MSEC(100)); - (void)pm_device_state_get(test_dev, &state); - zassert_equal(state, PM_DEVICE_STATE_SUSPENDING); + (void)pm_device_state_get(test_dev, &state); + zassert_equal(state, PM_DEVICE_STATE_SUSPENDING); - k_sleep(K_MSEC(80)); + k_sleep(K_MSEC(80)); - /* It should still be suspending since we have waited less than - * the delay we've set. - */ - (void)pm_device_state_get(test_dev, &state); - zassert_equal(state, PM_DEVICE_STATE_SUSPENDING); + /* It should still be suspending since we have waited less than + * the delay we've set. + */ + (void)pm_device_state_get(test_dev, &state); + zassert_equal(state, PM_DEVICE_STATE_SUSPENDING); - k_sleep(K_MSEC(30)); + k_sleep(K_MSEC(30)); - /* Now it should be already suspended */ - (void)pm_device_state_get(test_dev, &state); - zassert_equal(state, PM_DEVICE_STATE_SUSPENDED); + /* Now it should be already suspended */ + (void)pm_device_state_get(test_dev, &state); + zassert_equal(state, PM_DEVICE_STATE_SUSPENDED); + } /* Put operation should fail due the state be locked. */ ret = pm_device_runtime_disable(test_dev); diff --git a/tests/subsys/pm/device_runtime_api/src/test_driver.c b/tests/subsys/pm/device_runtime_api/src/test_driver.c index d7c06f9cddb0c06..bd2104e2e8bc5cf 100644 --- a/tests/subsys/pm/device_runtime_api/src/test_driver.c +++ b/tests/subsys/pm/device_runtime_api/src/test_driver.c @@ -21,14 +21,16 @@ static int test_driver_action(const struct device *dev, { struct test_driver_data *data = dev->data; - data->ongoing = true; + if (!IS_ENABLED(CONFIG_TEST_PM_DEVICE_SYNC)) { + data->ongoing = true; - if (data->async) { - k_sem_take(&data->sync, K_FOREVER); - data->async = false; - } + if (data->async) { + k_sem_take(&data->sync, K_FOREVER); + data->async = false; + } - data->ongoing = false; + data->ongoing = false; + } data->count++; @@ -72,7 +74,11 @@ int test_driver_init(const struct device *dev) return 0; } +#if CONFIG_TEST_PM_DEVICE_SYNC +PM_DEVICE_SYNC_DEFINE(test_driver, test_driver_action); +#else PM_DEVICE_DEFINE(test_driver, test_driver_action); +#endif static struct test_driver_data data; diff --git a/tests/subsys/pm/device_runtime_api/testcase.yaml b/tests/subsys/pm/device_runtime_api/testcase.yaml index 72c9c51294288b2..7f453511d2758a1 100644 --- a/tests/subsys/pm/device_runtime_api/testcase.yaml +++ b/tests/subsys/pm/device_runtime_api/testcase.yaml @@ -3,3 +3,9 @@ tests: tags: pm integration_platforms: - native_sim + pm.device_runtime.sync.api: + tags: pm + integration_platforms: + - native_sim + extra_configs: + - CONFIG_TEST_PM_DEVICE_SYNC=y