From d18134a264932627bdf593a1c3b410e5268ce989 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Tue, 24 Jun 2025 12:37:25 +0200 Subject: [PATCH 1/2] [nrf fromlist] drivers: gpio: nrfx: extend pin retain to every pin The usage of nrf_gpio_port_retain_disable/_enable, in cases where the soc pins support retention, every pin must be retained/unretained regardless of what power domain the pad is in. This patch ensures retain is applied to all pins in all domains by the gpio_nrfx device driver, not only pins specifically in the fast_active_1 domain. Without this patch, pinctrl will correctly retain pins, while gpio_nrfx will fail to unretain them when again. We no longer check the output state either, which was passed with the flags arg of gpio_nrfx_gpd_retain_set() so this arg has been removed. Upstream PR#: 92085 Signed-off-by: Bjarki Arge Andreasen --- drivers/gpio/gpio_nrfx.c | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/drivers/gpio/gpio_nrfx.c b/drivers/gpio/gpio_nrfx.c index 39377d7b777..d5480c9149b 100644 --- a/drivers/gpio/gpio_nrfx.c +++ b/drivers/gpio/gpio_nrfx.c @@ -64,20 +64,15 @@ static nrf_gpio_pin_pull_t get_pull(gpio_flags_t flags) return NRF_GPIO_PIN_NOPULL; } -static void gpio_nrfx_gpd_retain_set(const struct device *port, uint32_t mask, gpio_flags_t flags) +static void gpio_nrfx_gpd_retain_set(const struct device *port, uint32_t mask) { #ifdef CONFIG_SOC_NRF54H20_GPD const struct gpio_nrfx_cfg *cfg = get_port_cfg(port); - if (cfg->pad_pd != NRF_GPD_FAST_ACTIVE1 || !(flags & GPIO_OUTPUT)) { - return; - } - nrf_gpio_port_retain_enable(cfg->port, mask); #else ARG_UNUSED(port); ARG_UNUSED(mask); - ARG_UNUSED(flags); #endif } @@ -86,10 +81,6 @@ static void gpio_nrfx_gpd_retain_clear(const struct device *port, uint32_t mask) #ifdef CONFIG_SOC_NRF54H20_GPD const struct gpio_nrfx_cfg *cfg = get_port_cfg(port); - if (cfg->pad_pd != NRF_GPD_FAST_ACTIVE1) { - return; - } - nrf_gpio_port_retain_disable(cfg->port, mask); #else ARG_UNUSED(port); @@ -225,7 +216,7 @@ static int gpio_nrfx_pin_configure(const struct device *port, gpio_pin_t pin, } end: - gpio_nrfx_gpd_retain_set(port, BIT(pin), flags); + gpio_nrfx_gpd_retain_set(port, BIT(pin)); return pm_device_runtime_put(port); } @@ -329,7 +320,7 @@ static int gpio_nrfx_port_set_masked_raw(const struct device *port, gpio_nrfx_gpd_retain_clear(port, mask); nrf_gpio_port_out_set(reg, set_mask); nrf_gpio_port_out_clear(reg, clear_mask); - gpio_nrfx_gpd_retain_set(port, mask, GPIO_OUTPUT); + gpio_nrfx_gpd_retain_set(port, mask); return pm_device_runtime_put(port); } @@ -346,7 +337,7 @@ static int gpio_nrfx_port_set_bits_raw(const struct device *port, gpio_nrfx_gpd_retain_clear(port, mask); nrf_gpio_port_out_set(reg, mask); - gpio_nrfx_gpd_retain_set(port, mask, GPIO_OUTPUT); + gpio_nrfx_gpd_retain_set(port, mask); return pm_device_runtime_put(port); } @@ -363,7 +354,7 @@ static int gpio_nrfx_port_clear_bits_raw(const struct device *port, gpio_nrfx_gpd_retain_clear(port, mask); nrf_gpio_port_out_clear(reg, mask); - gpio_nrfx_gpd_retain_set(port, mask, GPIO_OUTPUT); + gpio_nrfx_gpd_retain_set(port, mask); return pm_device_runtime_put(port); } @@ -384,7 +375,7 @@ static int gpio_nrfx_port_toggle_bits(const struct device *port, gpio_nrfx_gpd_retain_clear(port, mask); nrf_gpio_port_out_set(reg, set_mask); nrf_gpio_port_out_clear(reg, clear_mask); - gpio_nrfx_gpd_retain_set(port, mask, GPIO_OUTPUT); + gpio_nrfx_gpd_retain_set(port, mask); return pm_device_runtime_put(port); } From 2f336ac6f817f74a3d93115086d31055d3ab5d72 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Wed, 25 Jun 2025 15:55:03 +0200 Subject: [PATCH 2/2] [nrf fromlist] drivers: pinctrl: nrf: patch pin retain to follow lp mode Pins can be configured to retain their config even when the power domain they belong to is suspended. Update pinctrl_nrf to enable retain only if the pin has been configured and is not in use (pincnf is low-power/sleep), disable retain otherwise. Upstream PR#: 92085 Signed-off-by: Bjarki Arge Andreasen --- drivers/pinctrl/pinctrl_nrf.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/drivers/pinctrl/pinctrl_nrf.c b/drivers/pinctrl/pinctrl_nrf.c index 05c0ed9ac0b..34c0107b591 100644 --- a/drivers/pinctrl/pinctrl_nrf.c +++ b/drivers/pinctrl/pinctrl_nrf.c @@ -516,9 +516,13 @@ int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, } gpd_requested = true; } - - nrf_gpio_pin_retain_disable(pin); } + + /* + * Pad power domain now on, retain no longer needed + * as pad config will be persists as pad is powered. + */ + nrf_gpio_pin_retain_disable(pin); #endif /* CONFIG_SOC_NRF54H20_GPD */ if (write != NO_WRITE) { @@ -537,7 +541,13 @@ int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, nrf_gpio_pin_clock_set(pin, NRF_GET_CLOCKPIN_ENABLE(pins[i])); #endif #ifdef CONFIG_SOC_NRF54H20_GPD - if (NRF_GET_GPD_FAST_ACTIVE1(pins[i]) == 1U) { + if (NRF_GET_LP(pins[i]) == NRF_LP_ENABLE) { + /* + * Pad power domain may be turned off, and pad is not + * actively used as pincnf is low-power. Enable retain + * to ensure pad output and config persists if pad + * power domain is suspended. + */ nrf_gpio_pin_retain_enable(pin); } #endif /* CONFIG_SOC_NRF54H20_GPD */