1111#include <zephyr/drivers/gpio.h>
1212#include <zephyr/dt-bindings/gpio/nordic-nrf-gpio.h>
1313#include <zephyr/irq.h>
14+ #include <zephyr/pm/device.h>
15+ #include <zephyr/pm/device_runtime.h>
1416
1517#include <zephyr/drivers/gpio/gpio_utils.h>
1618
@@ -62,53 +64,37 @@ static nrf_gpio_pin_pull_t get_pull(gpio_flags_t flags)
6264 return NRF_GPIO_PIN_NOPULL ;
6365}
6466
65- static int gpio_nrfx_gpd_retain_set (const struct device * port , uint32_t mask , gpio_flags_t flags )
67+ static void gpio_nrfx_gpd_retain_set (const struct device * port , uint32_t mask , gpio_flags_t flags )
6668{
6769#ifdef CONFIG_SOC_NRF54H20_GPD
6870 const struct gpio_nrfx_cfg * cfg = get_port_cfg (port );
6971
70- if (cfg -> pad_pd == NRF_GPD_FAST_ACTIVE1 ) {
71- int ret ;
72-
73- if (flags & GPIO_OUTPUT ) {
74- nrf_gpio_port_retain_enable (cfg -> port , mask );
75- }
76-
77- ret = nrf_gpd_release (NRF_GPD_FAST_ACTIVE1 );
78- if (ret < 0 ) {
79- return ret ;
80- }
72+ if (cfg -> pad_pd != NRF_GPD_FAST_ACTIVE1 || !(flags & GPIO_OUTPUT )) {
73+ return ;
8174 }
75+
76+ nrf_gpio_port_retain_enable (cfg -> port , mask );
8277#else
8378 ARG_UNUSED (port );
8479 ARG_UNUSED (mask );
8580 ARG_UNUSED (flags );
8681#endif
87-
88- return 0 ;
8982}
9083
91- static int gpio_nrfx_gpd_retain_clear (const struct device * port , uint32_t mask )
84+ static void gpio_nrfx_gpd_retain_clear (const struct device * port , uint32_t mask )
9285{
9386#ifdef CONFIG_SOC_NRF54H20_GPD
9487 const struct gpio_nrfx_cfg * cfg = get_port_cfg (port );
9588
96- if (cfg -> pad_pd == NRF_GPD_FAST_ACTIVE1 ) {
97- int ret ;
98-
99- ret = nrf_gpd_request (NRF_GPD_FAST_ACTIVE1 );
100- if (ret < 0 ) {
101- return ret ;
102- }
103-
104- nrf_gpio_port_retain_disable (cfg -> port , mask );
89+ if (cfg -> pad_pd != NRF_GPD_FAST_ACTIVE1 ) {
90+ return ;
10591 }
92+
93+ nrf_gpio_port_retain_disable (cfg -> port , mask );
10694#else
10795 ARG_UNUSED (port );
10896 ARG_UNUSED (mask );
10997#endif
110-
111- return 0 ;
11298}
11399
114100static int gpio_nrfx_pin_configure (const struct device * port , gpio_pin_t pin ,
@@ -152,11 +138,13 @@ static int gpio_nrfx_pin_configure(const struct device *port, gpio_pin_t pin,
152138 return - EINVAL ;
153139 }
154140
155- ret = gpio_nrfx_gpd_retain_clear (port , BIT ( pin ) );
141+ ret = pm_device_runtime_get (port );
156142 if (ret < 0 ) {
157143 return ret ;
158144 }
159145
146+ gpio_nrfx_gpd_retain_clear (port , BIT (pin ));
147+
160148 if (flags & GPIO_OUTPUT_INIT_HIGH ) {
161149 nrf_gpio_port_out_set (cfg -> port , BIT (pin ));
162150 } else if (flags & GPIO_OUTPUT_INIT_LOW ) {
@@ -237,8 +225,8 @@ static int gpio_nrfx_pin_configure(const struct device *port, gpio_pin_t pin,
237225 }
238226
239227end :
240- ( void ) gpio_nrfx_gpd_retain_set (port , BIT (pin ), flags );
241- return ret ;
228+ gpio_nrfx_gpd_retain_set (port , BIT (pin ), flags );
229+ return pm_device_runtime_put ( port ) ;
242230}
243231
244232static int gpio_nrfx_port_get_raw (const struct device * port ,
@@ -261,15 +249,16 @@ static int gpio_nrfx_port_set_masked_raw(const struct device *port,
261249 const uint32_t set_mask = value & mask ;
262250 const uint32_t clear_mask = (~set_mask ) & mask ;
263251
264- ret = gpio_nrfx_gpd_retain_clear (port , mask );
252+ ret = pm_device_runtime_get (port );
265253 if (ret < 0 ) {
266254 return ret ;
267255 }
268256
257+ gpio_nrfx_gpd_retain_clear (port , mask );
269258 nrf_gpio_port_out_set (reg , set_mask );
270259 nrf_gpio_port_out_clear (reg , clear_mask );
271-
272- return gpio_nrfx_gpd_retain_set (port , mask , GPIO_OUTPUT );
260+ gpio_nrfx_gpd_retain_set ( port , mask , GPIO_OUTPUT );
261+ return pm_device_runtime_put (port );
273262}
274263
275264static int gpio_nrfx_port_set_bits_raw (const struct device * port ,
@@ -278,14 +267,15 @@ static int gpio_nrfx_port_set_bits_raw(const struct device *port,
278267 NRF_GPIO_Type * reg = get_port_cfg (port )-> port ;
279268 int ret ;
280269
281- ret = gpio_nrfx_gpd_retain_clear (port , mask );
270+ ret = pm_device_runtime_get (port );
282271 if (ret < 0 ) {
283272 return ret ;
284273 }
285274
275+ gpio_nrfx_gpd_retain_clear (port , mask );
286276 nrf_gpio_port_out_set (reg , mask );
287-
288- return gpio_nrfx_gpd_retain_set (port , mask , GPIO_OUTPUT );
277+ gpio_nrfx_gpd_retain_set ( port , mask , GPIO_OUTPUT );
278+ return pm_device_runtime_put (port );
289279}
290280
291281static int gpio_nrfx_port_clear_bits_raw (const struct device * port ,
@@ -294,14 +284,15 @@ static int gpio_nrfx_port_clear_bits_raw(const struct device *port,
294284 NRF_GPIO_Type * reg = get_port_cfg (port )-> port ;
295285 int ret ;
296286
297- ret = gpio_nrfx_gpd_retain_clear (port , mask );
287+ ret = pm_device_runtime_get (port );
298288 if (ret < 0 ) {
299289 return ret ;
300290 }
301291
292+ gpio_nrfx_gpd_retain_clear (port , mask );
302293 nrf_gpio_port_out_clear (reg , mask );
303-
304- return gpio_nrfx_gpd_retain_set (port , mask , GPIO_OUTPUT );
294+ gpio_nrfx_gpd_retain_set ( port , mask , GPIO_OUTPUT );
295+ return pm_device_runtime_put (port );
305296}
306297
307298static int gpio_nrfx_port_toggle_bits (const struct device * port ,
@@ -313,15 +304,16 @@ static int gpio_nrfx_port_toggle_bits(const struct device *port,
313304 const uint32_t clear_mask = (~value ) & mask ;
314305 int ret ;
315306
316- ret = gpio_nrfx_gpd_retain_clear (port , mask );
307+ ret = pm_device_runtime_get (port );
317308 if (ret < 0 ) {
318309 return ret ;
319310 }
320311
312+ gpio_nrfx_gpd_retain_clear (port , mask );
321313 nrf_gpio_port_out_set (reg , set_mask );
322314 nrf_gpio_port_out_clear (reg , clear_mask );
323-
324- return gpio_nrfx_gpd_retain_set (port , mask , GPIO_OUTPUT );
315+ gpio_nrfx_gpd_retain_set ( port , mask , GPIO_OUTPUT );
316+ return pm_device_runtime_put (port );
325317}
326318
327319#ifdef CONFIG_GPIO_NRFX_INTERRUPT
@@ -480,17 +472,68 @@ static void nrfx_gpio_handler(nrfx_gpiote_pin_t abs_pin,
480472 IRQ_CONNECT(DT_IRQN(node_id), DT_IRQ(node_id, priority), nrfx_isr, \
481473 NRFX_CONCAT(nrfx_gpiote_, DT_PROP(node_id, instance), _irq_handler), 0);
482474
475+ static int gpio_nrfx_pm_suspend (const struct device * port )
476+ {
477+ #ifdef CONFIG_SOC_NRF54H20_GPD
478+ const struct gpio_nrfx_cfg * cfg = get_port_cfg (port );
479+
480+ if (cfg -> pad_pd != NRF_GPD_FAST_ACTIVE1 ) {
481+ return 0 ;
482+ }
483+
484+ return nrf_gpd_release (NRF_GPD_FAST_ACTIVE1 );
485+ #else
486+ ARG_UNUSED (port );
487+ return 0 ;
488+ #endif
489+ }
490+
491+ static int gpio_nrfx_pm_resume (const struct device * port )
492+ {
493+ #ifdef CONFIG_SOC_NRF54H20_GPD
494+ const struct gpio_nrfx_cfg * cfg = get_port_cfg (port );
495+
496+ if (cfg -> pad_pd != NRF_GPD_FAST_ACTIVE1 ) {
497+ return 0 ;
498+ }
499+
500+ return nrf_gpd_request (NRF_GPD_FAST_ACTIVE1 );
501+ #else
502+ ARG_UNUSED (port );
503+ return 0 ;
504+ #endif
505+ }
506+
507+ static int gpio_nrfx_pm_hook (const struct device * port , enum pm_device_action action )
508+ {
509+ int ret ;
510+
511+ switch (action ) {
512+ case PM_DEVICE_ACTION_SUSPEND :
513+ ret = gpio_nrfx_pm_suspend (port );
514+ break ;
515+ case PM_DEVICE_ACTION_RESUME :
516+ ret = gpio_nrfx_pm_resume (port );
517+ break ;
518+ default :
519+ ret = - ENOTSUP ;
520+ break ;
521+ }
522+
523+ return ret ;
524+ }
525+
483526static int gpio_nrfx_init (const struct device * port )
484527{
485528 const struct gpio_nrfx_cfg * cfg = get_port_cfg (port );
486529 nrfx_err_t err ;
487530
488531 if (!has_gpiote (cfg )) {
489- return 0 ;
532+ goto pm_init ;
490533 }
491534
492535 if (nrfx_gpiote_init_check (& cfg -> gpiote )) {
493- return 0 ;
536+ goto pm_init ;
494537 }
495538
496539 err = nrfx_gpiote_init (& cfg -> gpiote , 0 /*not used*/ );
@@ -503,7 +546,8 @@ static int gpio_nrfx_init(const struct device *port)
503546 DT_FOREACH_STATUS_OKAY (nordic_nrf_gpiote , GPIOTE_IRQ_HANDLER_CONNECT );
504547#endif /* CONFIG_GPIO_NRFX_INTERRUPT */
505548
506- return 0 ;
549+ pm_init :
550+ return pm_device_driver_init (port , gpio_nrfx_pm_hook );
507551}
508552
509553static DEVICE_API (gpio , gpio_nrfx_drv_api_funcs ) = {
@@ -565,8 +609,10 @@ static DEVICE_API(gpio, gpio_nrfx_drv_api_funcs) = {
565609 \
566610 static struct gpio_nrfx_data gpio_nrfx_p##id##_data; \
567611 \
612+ PM_DEVICE_DT_INST_DEFINE(id, gpio_nrfx_pm_hook); \
613+ \
568614 DEVICE_DT_INST_DEFINE(id, gpio_nrfx_init, \
569- NULL, \
615+ PM_DEVICE_DT_INST_GET(id), \
570616 &gpio_nrfx_p##id##_data, \
571617 &gpio_nrfx_p##id##_cfg, \
572618 PRE_KERNEL_1, \
0 commit comments