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
244232#ifdef CONFIG_GPIO_GET_CONFIG
@@ -328,15 +316,16 @@ static int gpio_nrfx_port_set_masked_raw(const struct device *port,
328316 const uint32_t set_mask = value & mask ;
329317 const uint32_t clear_mask = (~set_mask ) & mask ;
330318
331- ret = gpio_nrfx_gpd_retain_clear (port , mask );
319+ ret = pm_device_runtime_get (port );
332320 if (ret < 0 ) {
333321 return ret ;
334322 }
335323
324+ gpio_nrfx_gpd_retain_clear (port , mask );
336325 nrf_gpio_port_out_set (reg , set_mask );
337326 nrf_gpio_port_out_clear (reg , clear_mask );
338-
339- return gpio_nrfx_gpd_retain_set (port , mask , GPIO_OUTPUT );
327+ gpio_nrfx_gpd_retain_set ( port , mask , GPIO_OUTPUT );
328+ return pm_device_runtime_put (port );
340329}
341330
342331static int gpio_nrfx_port_set_bits_raw (const struct device * port ,
@@ -345,14 +334,15 @@ static int gpio_nrfx_port_set_bits_raw(const struct device *port,
345334 NRF_GPIO_Type * reg = get_port_cfg (port )-> port ;
346335 int ret ;
347336
348- ret = gpio_nrfx_gpd_retain_clear (port , mask );
337+ ret = pm_device_runtime_get (port );
349338 if (ret < 0 ) {
350339 return ret ;
351340 }
352341
342+ gpio_nrfx_gpd_retain_clear (port , mask );
353343 nrf_gpio_port_out_set (reg , mask );
354-
355- return gpio_nrfx_gpd_retain_set (port , mask , GPIO_OUTPUT );
344+ gpio_nrfx_gpd_retain_set ( port , mask , GPIO_OUTPUT );
345+ return pm_device_runtime_put (port );
356346}
357347
358348static int gpio_nrfx_port_clear_bits_raw (const struct device * port ,
@@ -361,14 +351,15 @@ static int gpio_nrfx_port_clear_bits_raw(const struct device *port,
361351 NRF_GPIO_Type * reg = get_port_cfg (port )-> port ;
362352 int ret ;
363353
364- ret = gpio_nrfx_gpd_retain_clear (port , mask );
354+ ret = pm_device_runtime_get (port );
365355 if (ret < 0 ) {
366356 return ret ;
367357 }
368358
359+ gpio_nrfx_gpd_retain_clear (port , mask );
369360 nrf_gpio_port_out_clear (reg , mask );
370-
371- return gpio_nrfx_gpd_retain_set (port , mask , GPIO_OUTPUT );
361+ gpio_nrfx_gpd_retain_set ( port , mask , GPIO_OUTPUT );
362+ return pm_device_runtime_put (port );
372363}
373364
374365static int gpio_nrfx_port_toggle_bits (const struct device * port ,
@@ -380,15 +371,16 @@ static int gpio_nrfx_port_toggle_bits(const struct device *port,
380371 const uint32_t clear_mask = (~value ) & mask ;
381372 int ret ;
382373
383- ret = gpio_nrfx_gpd_retain_clear (port , mask );
374+ ret = pm_device_runtime_get (port );
384375 if (ret < 0 ) {
385376 return ret ;
386377 }
387378
379+ gpio_nrfx_gpd_retain_clear (port , mask );
388380 nrf_gpio_port_out_set (reg , set_mask );
389381 nrf_gpio_port_out_clear (reg , clear_mask );
390-
391- return gpio_nrfx_gpd_retain_set (port , mask , GPIO_OUTPUT );
382+ gpio_nrfx_gpd_retain_set ( port , mask , GPIO_OUTPUT );
383+ return pm_device_runtime_put (port );
392384}
393385
394386#ifdef CONFIG_GPIO_NRFX_INTERRUPT
@@ -547,17 +539,68 @@ static void nrfx_gpio_handler(nrfx_gpiote_pin_t abs_pin,
547539 IRQ_CONNECT(DT_IRQN(node_id), DT_IRQ(node_id, priority), nrfx_isr, \
548540 NRFX_CONCAT(nrfx_gpiote_, DT_PROP(node_id, instance), _irq_handler), 0);
549541
542+ static int gpio_nrfx_pm_suspend (const struct device * port )
543+ {
544+ #ifdef CONFIG_SOC_NRF54H20_GPD
545+ const struct gpio_nrfx_cfg * cfg = get_port_cfg (port );
546+
547+ if (cfg -> pad_pd != NRF_GPD_FAST_ACTIVE1 ) {
548+ return 0 ;
549+ }
550+
551+ return nrf_gpd_release (NRF_GPD_FAST_ACTIVE1 );
552+ #else
553+ ARG_UNUSED (port );
554+ return 0 ;
555+ #endif
556+ }
557+
558+ static int gpio_nrfx_pm_resume (const struct device * port )
559+ {
560+ #ifdef CONFIG_SOC_NRF54H20_GPD
561+ const struct gpio_nrfx_cfg * cfg = get_port_cfg (port );
562+
563+ if (cfg -> pad_pd != NRF_GPD_FAST_ACTIVE1 ) {
564+ return 0 ;
565+ }
566+
567+ return nrf_gpd_request (NRF_GPD_FAST_ACTIVE1 );
568+ #else
569+ ARG_UNUSED (port );
570+ return 0 ;
571+ #endif
572+ }
573+
574+ static int gpio_nrfx_pm_hook (const struct device * port , enum pm_device_action action )
575+ {
576+ int ret ;
577+
578+ switch (action ) {
579+ case PM_DEVICE_ACTION_SUSPEND :
580+ ret = gpio_nrfx_pm_suspend (port );
581+ break ;
582+ case PM_DEVICE_ACTION_RESUME :
583+ ret = gpio_nrfx_pm_resume (port );
584+ break ;
585+ default :
586+ ret = - ENOTSUP ;
587+ break ;
588+ }
589+
590+ return ret ;
591+ }
592+
550593static int gpio_nrfx_init (const struct device * port )
551594{
552595 const struct gpio_nrfx_cfg * cfg = get_port_cfg (port );
553596 nrfx_err_t err ;
554597
555598 if (!has_gpiote (cfg )) {
556- return 0 ;
599+ goto pm_init ;
557600 }
558601
559602 if (nrfx_gpiote_init_check (& cfg -> gpiote )) {
560- return 0 ;
603+ goto pm_init ;
561604 }
562605
563606 err = nrfx_gpiote_init (& cfg -> gpiote , 0 /*not used*/ );
@@ -570,7 +613,8 @@ static int gpio_nrfx_init(const struct device *port)
570613 DT_FOREACH_STATUS_OKAY (nordic_nrf_gpiote , GPIOTE_IRQ_HANDLER_CONNECT );
571614#endif /* CONFIG_GPIO_NRFX_INTERRUPT */
572615
573- return 0 ;
616+ pm_init :
617+ return pm_device_driver_init (port , gpio_nrfx_pm_hook );
574618}
575619
576620static DEVICE_API (gpio , gpio_nrfx_drv_api_funcs ) = {
@@ -635,8 +679,10 @@ static DEVICE_API(gpio, gpio_nrfx_drv_api_funcs) = {
635679 \
636680 static struct gpio_nrfx_data gpio_nrfx_p##id##_data; \
637681 \
682+ PM_DEVICE_DT_INST_DEFINE(id, gpio_nrfx_pm_hook); \
683+ \
638684 DEVICE_DT_INST_DEFINE(id, gpio_nrfx_init, \
639- NULL, \
685+ PM_DEVICE_DT_INST_GET(id), \
640686 &gpio_nrfx_p##id##_data, \
641687 &gpio_nrfx_p##id##_cfg, \
642688 PRE_KERNEL_1, \
0 commit comments