From 2313be11a7fc6e09af935de712bc634b31c19250 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Mon, 18 Nov 2024 09:33:30 +0100 Subject: [PATCH 1/2] drivers: serial: nrfx_uarte: Fix runtime PM for interrupt driven API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit TX part of interrupt driven API was not calling PM device runtime API. Additionally, when txstopped occurred after poll out it was not handled correctly. Signed-off-by: Krzysztof Chruściński (cherry picked from commit 13ed9e4210aeed179e9f302bb7fdb7c93af00c0d) --- drivers/serial/uart_nrfx_uarte.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/drivers/serial/uart_nrfx_uarte.c b/drivers/serial/uart_nrfx_uarte.c index e1af63b7993e7..d656583cfac95 100644 --- a/drivers/serial/uart_nrfx_uarte.c +++ b/drivers/serial/uart_nrfx_uarte.c @@ -353,16 +353,16 @@ static void uarte_nrfx_isr_int(const void *arg) if (txstopped && (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME) || LOW_POWER_ENABLED(config))) { unsigned int key = irq_lock(); - if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME) && - (data->flags & UARTE_FLAG_POLL_OUT)) { - data->flags &= ~UARTE_FLAG_POLL_OUT; - pm_device_runtime_put(dev); + if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) { + if (data->flags & UARTE_FLAG_POLL_OUT) { + data->flags &= ~UARTE_FLAG_POLL_OUT; + pm_device_runtime_put_async(dev, K_NO_WAIT); + } } else { nrf_uarte_disable(uarte); } - #ifdef UARTE_INTERRUPT_DRIVEN - if (!data->int_driven || data->int_driven->fifo_fill_lock == 0) + if (!data->int_driven) #endif { nrf_uarte_int_disable(uarte, NRF_UARTE_INT_TXSTOPPED_MASK); @@ -378,16 +378,20 @@ static void uarte_nrfx_isr_int(const void *arg) if (txstopped) { data->int_driven->fifo_fill_lock = 0; + if (!data->int_driven->tx_irq_enabled) { + + nrf_uarte_int_disable(uarte, NRF_UARTE_INT_TXSTOPPED_MASK); + } + if (data->int_driven->disable_tx_irq) { - nrf_uarte_int_disable(uarte, - NRF_UARTE_INT_TXSTOPPED_MASK); data->int_driven->disable_tx_irq = false; + if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) { + pm_device_runtime_put_async(dev, K_NO_WAIT); + } return; } - } - if (nrf_uarte_event_check(uarte, NRF_UARTE_EVENT_ERROR)) { nrf_uarte_event_clear(uarte, NRF_UARTE_EVENT_ERROR); } @@ -1892,6 +1896,11 @@ static void uarte_nrfx_irq_tx_enable(const struct device *dev) { NRF_UARTE_Type *uarte = get_uarte_instance(dev); struct uarte_nrfx_data *data = dev->data; + + if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) { + pm_device_runtime_get(dev); + } + unsigned int key = irq_lock(); data->int_driven->disable_tx_irq = false; From bea3554f1f847c1b5fb7281c4745a0011bcad2dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Mon, 18 Nov 2024 15:31:22 +0100 Subject: [PATCH 2/2] tests: drivers: uart: uart_elementary: Add runtime PM configuration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add configuration that uses device runtime PM. Signed-off-by: Krzysztof Chruściński (cherry picked from commit eae3891303f48bec958db157da2bdf611628ec26) --- ...f54h20dk_nrf54h20_cpuapp_dual_uart.overlay | 2 ++ tests/drivers/uart/uart_elementary/src/main.c | 28 +++++++++++++++++-- .../uart/uart_elementary/testcase.yaml | 9 ++++++ 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/tests/drivers/uart/uart_elementary/boards/nrf54h20dk_nrf54h20_cpuapp_dual_uart.overlay b/tests/drivers/uart/uart_elementary/boards/nrf54h20dk_nrf54h20_cpuapp_dual_uart.overlay index f544d609adacd..fb2f80460fe85 100644 --- a/tests/drivers/uart/uart_elementary/boards/nrf54h20dk_nrf54h20_cpuapp_dual_uart.overlay +++ b/tests/drivers/uart/uart_elementary/boards/nrf54h20dk_nrf54h20_cpuapp_dual_uart.overlay @@ -30,6 +30,7 @@ dut: &uart135 { pinctrl-1 = <&uart135_sleep_alt>; pinctrl-names = "default", "sleep"; current-speed = <115200>; + zephyr,pm-device-runtime-auto; }; &pinctrl { @@ -59,4 +60,5 @@ dut_aux: &uart137 { pinctrl-1 = <&uart137_sleep_alt>; pinctrl-names = "default", "sleep"; current-speed = <115200>; + zephyr,pm-device-runtime-auto; }; diff --git a/tests/drivers/uart/uart_elementary/src/main.c b/tests/drivers/uart/uart_elementary/src/main.c index 7d160c8b8f914..05d4d1a42c28d 100644 --- a/tests/drivers/uart/uart_elementary/src/main.c +++ b/tests/drivers/uart/uart_elementary/src/main.c @@ -12,6 +12,7 @@ */ #include +#include #include #if DT_NODE_EXISTS(DT_NODELABEL(dut)) @@ -268,15 +269,25 @@ ZTEST(uart_elementary, test_uart_dual_port_transmission) (void *)test_buffer_aux); zassert_equal(err, 0, "Unexpected error when setting user data for UART1 callback %d", err); + if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) { + int usage = pm_device_runtime_usage(uart_dev); + int usage_aux = pm_device_runtime_usage(uart_dev_aux); + + zassert_equal(usage, 0); + zassert_equal(usage_aux, 0); + pm_device_runtime_get(uart_dev); + pm_device_runtime_get(uart_dev_aux); + } + uart_irq_err_enable(uart_dev); uart_irq_err_enable(uart_dev_aux); - uart_irq_tx_enable(uart_dev); - uart_irq_tx_enable(uart_dev_aux); - uart_irq_rx_enable(uart_dev); uart_irq_rx_enable(uart_dev_aux); + uart_irq_tx_enable(uart_dev); + uart_irq_tx_enable(uart_dev_aux); + /* wait for the tramission to finish (no polling is intentional) */ k_sleep(K_USEC(100 * SLEEP_TIME_US)); @@ -287,6 +298,17 @@ ZTEST(uart_elementary, test_uart_dual_port_transmission) uart_irq_err_disable(uart_dev); uart_irq_err_disable(uart_dev_aux); + if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) { + pm_device_runtime_put(uart_dev); + pm_device_runtime_put(uart_dev_aux); + + int usage = pm_device_runtime_usage(uart_dev); + int usage_aux = pm_device_runtime_usage(uart_dev_aux); + + zassert_equal(usage, 0); + zassert_equal(usage_aux, 0); + } + #if defined(CONFIG_SETUP_MISMATCH_TEST) TC_PRINT("Mismatched configuration test\n"); zassert_not_equal(uart_error_counter + aux_uart_error_counter, 0, diff --git a/tests/drivers/uart/uart_elementary/testcase.yaml b/tests/drivers/uart/uart_elementary/testcase.yaml index e1ea05cddc1f5..359b98c79b16b 100644 --- a/tests/drivers/uart/uart_elementary/testcase.yaml +++ b/tests/drivers/uart/uart_elementary/testcase.yaml @@ -19,6 +19,15 @@ tests: extra_args: DTC_OVERLAY_FILE="boards/nrf54h20dk_nrf54h20_cpuapp_dual_uart.overlay" extra_configs: - CONFIG_DUAL_UART_TEST=y + drivers.uart.uart_elementary_dual_nrf54h.pm: + filter: CONFIG_SERIAL_SUPPORT_INTERRUPT + platform_allow: + - nrf54h20dk/nrf54h20/cpuapp + extra_args: DTC_OVERLAY_FILE="boards/nrf54h20dk_nrf54h20_cpuapp_dual_uart.overlay" + extra_configs: + - CONFIG_DUAL_UART_TEST=y + - CONFIG_PM_DEVICE=y + - CONFIG_PM_DEVICE_RUNTIME=y drivers.uart.uart_elementary_dual_setup_mismatch_nrf54h: filter: CONFIG_SERIAL_SUPPORT_INTERRUPT platform_allow: