From c86ba9f771dc3d0e3cc785121df3705329e06e1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Tue, 17 Sep 2024 11:43:35 +0200 Subject: [PATCH] tests: drivers: uart: async_dual: Add test cases with runtime PM MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add configurations in which runtime PM is enabled. There are 2 configurations: - Test does not call PM API for getting and putting the device. In that configuration UART device shall be suspended whenever not active. - Test is calling PM API which should keep device active as long as requested (e.g. during packet reception which consists of multiple chunks). Signed-off-by: Krzysztof Chruściński --- tests/drivers/uart/uart_async_dual/Kconfig | 5 ++ .../uart_async_dual/boards/nrf52_bsim.overlay | 1 + .../boards/nrf54h20dk_nrf54h20_common.dtsi | 3 + .../nrf54l15pdk_nrf54l15_cpuapp.overlay | 2 + tests/drivers/uart/uart_async_dual/src/main.c | 83 +++++++++++++++++++ .../uart/uart_async_dual/testcase.yaml | 29 +++++++ 6 files changed, 123 insertions(+) diff --git a/tests/drivers/uart/uart_async_dual/Kconfig b/tests/drivers/uart/uart_async_dual/Kconfig index d1c5ad6134b2aa8..6e80ec3a7957879 100644 --- a/tests/drivers/uart/uart_async_dual/Kconfig +++ b/tests/drivers/uart/uart_async_dual/Kconfig @@ -11,5 +11,10 @@ config UART_ASYNC_DUAL_TEST_TIMEOUT For how many loops will the stress test run. The higher this number the longer the test and therefore the higher likelihood an unlikely race/event will be triggered. +config PM_RUNTIME_IN_TEST + bool "Use runtime PM in the test" + select PM_DEVICE + select PM_DEVICE_RUNTIME + # Include Zephyr's Kconfig source "Kconfig" diff --git a/tests/drivers/uart/uart_async_dual/boards/nrf52_bsim.overlay b/tests/drivers/uart/uart_async_dual/boards/nrf52_bsim.overlay index afd9264d1901041..ddae6f682f97644 100644 --- a/tests/drivers/uart/uart_async_dual/boards/nrf52_bsim.overlay +++ b/tests/drivers/uart/uart_async_dual/boards/nrf52_bsim.overlay @@ -28,6 +28,7 @@ dut: &uart0 { pinctrl-1 = <&uart0_sleep>; pinctrl-names = "default", "sleep"; hw-flow-control; + zephyr,pm-device-runtime-auto; }; &timer0 { diff --git a/tests/drivers/uart/uart_async_dual/boards/nrf54h20dk_nrf54h20_common.dtsi b/tests/drivers/uart/uart_async_dual/boards/nrf54h20dk_nrf54h20_common.dtsi index f4b9df95aa2beaa..28c3879984aa61b 100644 --- a/tests/drivers/uart/uart_async_dual/boards/nrf54h20dk_nrf54h20_common.dtsi +++ b/tests/drivers/uart/uart_async_dual/boards/nrf54h20dk_nrf54h20_common.dtsi @@ -67,6 +67,7 @@ dut: &uart134 { pinctrl-1 = <&uart134_alt_sleep>; pinctrl-names = "default", "sleep"; hw-flow-control; + zephyr,pm-device-runtime-auto; }; dut_aux: &uart137 { @@ -76,6 +77,7 @@ dut_aux: &uart137 { pinctrl-1 = <&uart137_alt_sleep>; pinctrl-names = "default", "sleep"; hw-flow-control; + zephyr,pm-device-runtime-auto; }; dut2: &uart120 { @@ -85,6 +87,7 @@ dut2: &uart120 { pinctrl-names = "default", "sleep"; current-speed = <115200>; hw-flow-control; + zephyr,pm-device-runtime-auto; }; &timer137 { diff --git a/tests/drivers/uart/uart_async_dual/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay b/tests/drivers/uart/uart_async_dual/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay index cd06494115318b8..fe79690cbbadc28 100644 --- a/tests/drivers/uart/uart_async_dual/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay +++ b/tests/drivers/uart/uart_async_dual/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay @@ -45,6 +45,7 @@ dut: &uart21 { pinctrl-1 = <&uart21_sleep>; pinctrl-names = "default", "sleep"; hw-flow-control; + zephyr,pm-device-runtime-auto; }; dut_aux: &uart22 { @@ -54,6 +55,7 @@ dut_aux: &uart22 { pinctrl-1 = <&uart22_sleep>; pinctrl-names = "default", "sleep"; hw-flow-control; + zephyr,pm-device-runtime-auto; }; &timer20 { diff --git a/tests/drivers/uart/uart_async_dual/src/main.c b/tests/drivers/uart/uart_async_dual/src/main.c index 7f82e2807dfd80d..02f148eef6770ed 100644 --- a/tests/drivers/uart/uart_async_dual/src/main.c +++ b/tests/drivers/uart/uart_async_dual/src/main.c @@ -5,6 +5,8 @@ */ #include +#include +#include #include #include #include @@ -57,6 +59,40 @@ ZTEST_DMEM struct dut_data duts[] = { #endif }; +static void pm_check(const struct device *dev, const struct device *second_dev, bool exp_on, + int line) +{ + if (!IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) { + return; + } + + if (dev == second_dev) { + return; + } + + enum pm_device_state state; + int err; + int cnt; + + cnt = pm_device_runtime_usage(dev); + err = pm_device_state_get(dev, &state); + zassert_equal(err, 0); + + if (exp_on) { + zassert_not_equal(cnt, 0, "Wrong PM cnt:%d, line:%d", cnt, line); + zassert_equal(state, PM_DEVICE_STATE_ACTIVE, + "Wrong PM state %s, line:%d", pm_device_state_str(state), line); + return; + } + + /* Expect device to be off. */ + zassert_equal(cnt, 0, "Wrong PM count:%d, line:%d", cnt, line); + zassert_equal(state, PM_DEVICE_STATE_SUSPENDED, + "Wrong PM state %s, line:%d", pm_device_state_str(state), line); +} + +#define PM_CHECK(dev, second_dev, exp_on) pm_check(dev, second_dev, exp_on, __LINE__) + static const struct device *rx_dev; static const struct device *tx_dev; @@ -452,11 +488,20 @@ static void hci_like_callback(const struct device *dev, struct uart_event *evt, { switch (evt->type) { case UART_TX_DONE: + zassert_true(dev == tx_dev); + if (IS_ENABLED(CONFIG_PM_RUNTIME_IN_TEST)) { + PM_CHECK(tx_dev, rx_dev, true); + pm_device_runtime_put(tx_dev); + } + PM_CHECK(tx_dev, rx_dev, false); k_sem_give(&tx_data.sem); break; case UART_TX_ABORTED: zassert_true(dev == tx_dev); + if (IS_ENABLED(CONFIG_PM_RUNTIME_IN_TEST)) { + pm_device_runtime_put(tx_dev); + } zassert_false(tx_data.cont, "Unexpected TX abort, receiver not reading data on time"); break; @@ -568,6 +613,10 @@ static void hci_like_tx(struct test_tx_data *tx_data) uint8_t len = buf[4] + 5; int err; + if (IS_ENABLED(CONFIG_PM_RUNTIME_IN_TEST)) { + pm_device_runtime_get(tx_dev); + } + err = uart_tx(tx_dev, buf, len, TX_TIMEOUT); zassert_equal(err, 0, "Unexpected err:%d", err); } @@ -595,25 +644,57 @@ static void hci_like_rx(void) uint8_t last_hdr = 0xff; uint8_t len; bool cont; + bool explicit_pm = IS_ENABLED(CONFIG_PM_RUNTIME_IN_TEST); while (1) { + if (explicit_pm) { + pm_device_runtime_get(rx_dev); + } + cont = rx(rx_data.buf, 1); if (!cont) { + if (explicit_pm) { + pm_device_runtime_put(rx_dev); + } break; } check_pre_hdr(rx_data.buf, last_hdr); last_hdr = rx_data.buf[0]; + /* If explicitly requested device to stay on in should be on. + * If application did not touch PM, device should be off. + */ + PM_CHECK(rx_dev, tx_dev, explicit_pm); + cont = rx(rx_data.buf, 4); if (!cont) { + if (explicit_pm) { + pm_device_runtime_put(rx_dev); + } break; } len = get_len(rx_data.buf); + /* If explicitly requested device to stay on in should be on. + * If application did not touch PM, device should be off. + */ + PM_CHECK(rx_dev, tx_dev, explicit_pm); + cont = rx(rx_data.buf, len); if (!cont) { + if (explicit_pm) { + pm_device_runtime_put(rx_dev); + } break; } + + if (explicit_pm) { + pm_device_runtime_put(rx_dev); + } + + /* Device shall be released and off. */ + PM_CHECK(rx_dev, tx_dev, false); + check_payload(rx_data.buf, len); } } @@ -677,6 +758,8 @@ static void hci_like_test(uint32_t baudrate) /* Flush data. */ (void)uart_tx_abort(tx_dev); k_msleep(10); + PM_CHECK(tx_dev, rx_dev, false); + (void)uart_rx_enable(rx_dev, rx_data.buf, sizeof(rx_data.buf), RX_TIMEOUT); k_msleep(1); (void)uart_rx_disable(rx_dev); diff --git a/tests/drivers/uart/uart_async_dual/testcase.yaml b/tests/drivers/uart/uart_async_dual/testcase.yaml index 507899a9e2e8f5c..b191959d26e3341 100644 --- a/tests/drivers/uart/uart_async_dual/testcase.yaml +++ b/tests/drivers/uart/uart_async_dual/testcase.yaml @@ -30,3 +30,32 @@ tests: - nrf52_bsim extra_configs: - CONFIG_TEST_BUSY_SIM=y + drivers.uart.async_dual.pm_runtime: + harness: ztest + harness_config: + fixture: uart_loopback + depends_on: gpio + platform_allow: + - nrf54l15pdk/nrf54l15/cpuapp + - nrf54h20dk/nrf54h20/cpuapp + - nrf54h20dk/nrf54h20/cpurad + - nrf54h20dk/nrf54h20/cpuppr + - nrf9160dk/nrf9160 + - nrf52_bsim + extra_configs: + - CONFIG_PM_DEVICE_RUNTIME=y + - CONFIG_PM_DEVICE=y + drivers.uart.async_dual.pm_runtime.explicit: + harness: ztest + harness_config: + fixture: uart_loopback + depends_on: gpio + platform_allow: + - nrf54l15pdk/nrf54l15/cpuapp + - nrf54h20dk/nrf54h20/cpuapp + - nrf54h20dk/nrf54h20/cpurad + - nrf54h20dk/nrf54h20/cpuppr + - nrf9160dk/nrf9160 + - nrf52_bsim + extra_configs: + - CONFIG_PM_RUNTIME_IN_TEST=y