diff --git a/drivers/gpio/gpio_silabs_siwx91x.c b/drivers/gpio/gpio_silabs_siwx91x.c index e13fc6e0cd070..94b2269821d48 100644 --- a/drivers/gpio/gpio_silabs_siwx91x.c +++ b/drivers/gpio/gpio_silabs_siwx91x.c @@ -207,6 +207,29 @@ static int gpio_siwx91x_pm_action(const struct device *dev, enum pm_device_actio return 0; } + +static int gpio_siwx91x_port_pm_action(const struct device *dev, enum pm_device_action action) +{ + const struct gpio_siwx91x_port_config *port_cfg = dev->config; + const struct device *parent = port_cfg->parent; + + switch (action) { + case PM_DEVICE_ACTION_TURN_ON: + break; + case PM_DEVICE_ACTION_TURN_OFF: + break; + case PM_DEVICE_ACTION_RESUME: + pm_device_runtime_get(parent); + break; + case PM_DEVICE_ACTION_SUSPEND: + pm_device_runtime_put(parent); + break; + default: + return -ENOTSUP; + } + return 0; +} + static int gpio_siwx91x_port_get(const struct device *port, gpio_port_value_t *value) { const struct gpio_siwx91x_port_config *port_cfg = port->config; @@ -378,7 +401,7 @@ static inline int gpio_siwx91x_init_port(const struct device *port) __ASSERT(port_cfg->port < cfg->port_count, "Too many ports"); data->ports[port_cfg->port] = port; - return 0; + return pm_device_driver_init(port, gpio_siwx91x_port_pm_action); } static void gpio_siwx91x_isr(const struct device *parent) @@ -449,10 +472,10 @@ static DEVICE_API(gpio, gpio_siwx91x_api) = { .pin_config_info = pin_config_info_##n, \ .total_pin_cnt = __builtin_popcount(GPIO_PORT_PIN_MASK_FROM_DT_NODE(n)), \ }; \ - \ - DEVICE_DT_DEFINE(n, gpio_siwx91x_init_port, NULL, &gpio_siwx91x_port_data##n, \ - &gpio_siwx91x_port_config##n, PRE_KERNEL_1, CONFIG_GPIO_INIT_PRIORITY, \ - &gpio_siwx91x_api); + PM_DEVICE_DT_DEFINE(n, gpio_siwx91x_port_pm_action); \ + DEVICE_DT_DEFINE(n, gpio_siwx91x_init_port, PM_DEVICE_DT_GET(n), \ + &gpio_siwx91x_port_data##n, &gpio_siwx91x_port_config##n, PRE_KERNEL_1, \ + CONFIG_GPIO_INIT_PRIORITY, &gpio_siwx91x_api); #define CONFIGURE_SHARED_INTERRUPT(node_id, prop, idx) \ IRQ_CONNECT(DT_IRQ_BY_IDX(node_id, idx, irq), DT_IRQ_BY_IDX(node_id, idx, priority), \ diff --git a/dts/arm/silabs/siwg917.dtsi b/dts/arm/silabs/siwg917.dtsi index 4fb4caa937c4d..2e0815bd35669 100644 --- a/dts/arm/silabs/siwg917.dtsi +++ b/dts/arm/silabs/siwg917.dtsi @@ -205,6 +205,7 @@ ngpios = <16>; gpio-reserved-ranges = <0 6>; silabs,pads = [ff ff ff ff ff ff 01 02 03 04 05 06 07 ff ff 08]; + zephyr,pm-device-runtime-auto; status = "okay"; }; @@ -215,6 +216,7 @@ #gpio-cells = <2>; ngpios = <16>; silabs,pads = [ff ff ff ff ff ff ff ff ff 00 00 00 00 00 00 09]; + zephyr,pm-device-runtime-auto; status = "okay"; }; @@ -225,6 +227,7 @@ #gpio-cells = <2>; ngpios = <16>; silabs,pads = [09 09 09 ff ff ff ff ff ff ff ff ff ff ff 0a 0b]; + zephyr,pm-device-runtime-auto; status = "okay"; }; @@ -235,6 +238,7 @@ #gpio-cells = <2>; ngpios = <10>; silabs,pads = [0c 0d 0e 0f 10 11 12 13 14 15 ff ff ff ff ff ff]; + zephyr,pm-device-runtime-auto; status = "okay"; }; }; @@ -259,6 +263,7 @@ ngpios = <12>; gpio-reserved-ranges = <3 1>; silabs,pads = [16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 ff ff ff ff]; + zephyr,pm-device-runtime-auto; status = "okay"; }; }; diff --git a/tests/drivers/gpio/gpio_basic_api/src/main.c b/tests/drivers/gpio/gpio_basic_api/src/main.c index e82e9918652d4..25e9fad4c5ce7 100644 --- a/tests/drivers/gpio/gpio_basic_api/src/main.c +++ b/tests/drivers/gpio/gpio_basic_api/src/main.c @@ -5,6 +5,7 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include #include "test_gpio.h" /* Grotesque hack for pinmux boards */ @@ -77,21 +78,33 @@ static void board_setup(void) static void *gpio_basic_setup(void) { board_setup(); - + (void)pm_device_runtime_get(DEVICE_DT_GET(DEV)); +#ifdef CONFIG_UART_CONSOLE + (void)pm_device_runtime_get(DEVICE_DT_GET(DT_CHOSEN(zephyr_console))); +#endif return NULL; } +void gpio_basic_teardown(void *args) +{ + (void)args; + (void)pm_device_runtime_put(DEVICE_DT_GET(DEV)); +#ifdef CONFIG_UART_CONSOLE + (void)pm_device_runtime_put(DEVICE_DT_GET(DT_CHOSEN(zephyr_console))); +#endif +} + /* Test GPIO port configuration */ -ZTEST_SUITE(gpio_port, NULL, gpio_basic_setup, NULL, NULL, NULL); +ZTEST_SUITE(gpio_port, NULL, gpio_basic_setup, NULL, NULL, gpio_basic_teardown); /* Test GPIO callback management */ -ZTEST_SUITE(gpio_port_cb_mgmt, NULL, gpio_basic_setup, NULL, NULL, NULL); +ZTEST_SUITE(gpio_port_cb_mgmt, NULL, gpio_basic_setup, NULL, NULL, gpio_basic_teardown); /* Test GPIO callbacks */ -ZTEST_SUITE(gpio_port_cb_vari, NULL, gpio_basic_setup, NULL, NULL, NULL); +ZTEST_SUITE(gpio_port_cb_vari, NULL, gpio_basic_setup, NULL, NULL, gpio_basic_teardown); /* Test GPIO port configuration influence on callbacks. Want to run just * after flash, hence the name starting in 'a' */ ZTEST_SUITE(after_flash_gpio_config_trigger, NULL, gpio_basic_setup, NULL, NULL, - NULL); + gpio_basic_teardown); diff --git a/tests/drivers/gpio/gpio_basic_api/testcase.yaml b/tests/drivers/gpio/gpio_basic_api/testcase.yaml index f411e63aac87f..1f506509d959c 100644 --- a/tests/drivers/gpio/gpio_basic_api/testcase.yaml +++ b/tests/drivers/gpio/gpio_basic_api/testcase.yaml @@ -142,3 +142,10 @@ tests: extra_args: "DTC_OVERLAY_FILE=boards/frdm_rw612_hsgpio.overlay" harness_config: fixture: hsgpio_loopback + drivers.gpio.device_runtime_pm: + platform_allow: + - siwx917_rb4338a + extra_configs: + - CONFIG_PM=y + - CONFIG_PM_DEVICE=y + - CONFIG_ZTEST_NO_YIELD=n