11
11
#include <zephyr/drivers/gpio.h>
12
12
#include <zephyr/dt-bindings/gpio/nordic-nrf-gpio.h>
13
13
#include <zephyr/irq.h>
14
+ #include <zephyr/pm/device.h>
15
+ #include <zephyr/pm/device_runtime.h>
14
16
15
17
#include <zephyr/drivers/gpio/gpio_utils.h>
16
18
@@ -62,53 +64,37 @@ static nrf_gpio_pin_pull_t get_pull(gpio_flags_t flags)
62
64
return NRF_GPIO_PIN_NOPULL ;
63
65
}
64
66
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 )
66
68
{
67
69
#ifdef CONFIG_SOC_NRF54H20_GPD
68
70
const struct gpio_nrfx_cfg * cfg = get_port_cfg (port );
69
71
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 ;
81
74
}
75
+
76
+ nrf_gpio_port_retain_enable (cfg -> port , mask );
82
77
#else
83
78
ARG_UNUSED (port );
84
79
ARG_UNUSED (mask );
85
80
ARG_UNUSED (flags );
86
81
#endif
87
-
88
- return 0 ;
89
82
}
90
83
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 )
92
85
{
93
86
#ifdef CONFIG_SOC_NRF54H20_GPD
94
87
const struct gpio_nrfx_cfg * cfg = get_port_cfg (port );
95
88
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 ;
105
91
}
92
+
93
+ nrf_gpio_port_retain_disable (cfg -> port , mask );
106
94
#else
107
95
ARG_UNUSED (port );
108
96
ARG_UNUSED (mask );
109
97
#endif
110
-
111
- return 0 ;
112
98
}
113
99
114
100
static 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,
152
138
return - EINVAL ;
153
139
}
154
140
155
- ret = gpio_nrfx_gpd_retain_clear (port , BIT ( pin ) );
141
+ ret = pm_device_runtime_get (port );
156
142
if (ret < 0 ) {
157
143
return ret ;
158
144
}
159
145
146
+ gpio_nrfx_gpd_retain_clear (port , BIT (pin ));
147
+
160
148
if (flags & GPIO_OUTPUT_INIT_HIGH ) {
161
149
nrf_gpio_port_out_set (cfg -> port , BIT (pin ));
162
150
} 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,
237
225
}
238
226
239
227
end :
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 ) ;
242
230
}
243
231
244
232
#ifdef CONFIG_GPIO_GET_CONFIG
@@ -331,15 +319,16 @@ static int gpio_nrfx_port_set_masked_raw(const struct device *port,
331
319
const uint32_t set_mask = value & mask ;
332
320
const uint32_t clear_mask = (~set_mask ) & mask ;
333
321
334
- ret = gpio_nrfx_gpd_retain_clear (port , mask );
322
+ ret = pm_device_runtime_get (port );
335
323
if (ret < 0 ) {
336
324
return ret ;
337
325
}
338
326
327
+ gpio_nrfx_gpd_retain_clear (port , mask );
339
328
nrf_gpio_port_out_set (reg , set_mask );
340
329
nrf_gpio_port_out_clear (reg , clear_mask );
341
-
342
- return gpio_nrfx_gpd_retain_set (port , mask , GPIO_OUTPUT );
330
+ gpio_nrfx_gpd_retain_set ( port , mask , GPIO_OUTPUT );
331
+ return pm_device_runtime_put (port );
343
332
}
344
333
345
334
static int gpio_nrfx_port_set_bits_raw (const struct device * port ,
@@ -348,14 +337,15 @@ static int gpio_nrfx_port_set_bits_raw(const struct device *port,
348
337
NRF_GPIO_Type * reg = get_port_cfg (port )-> port ;
349
338
int ret ;
350
339
351
- ret = gpio_nrfx_gpd_retain_clear (port , mask );
340
+ ret = pm_device_runtime_get (port );
352
341
if (ret < 0 ) {
353
342
return ret ;
354
343
}
355
344
345
+ gpio_nrfx_gpd_retain_clear (port , mask );
356
346
nrf_gpio_port_out_set (reg , mask );
357
-
358
- return gpio_nrfx_gpd_retain_set (port , mask , GPIO_OUTPUT );
347
+ gpio_nrfx_gpd_retain_set ( port , mask , GPIO_OUTPUT );
348
+ return pm_device_runtime_put (port );
359
349
}
360
350
361
351
static int gpio_nrfx_port_clear_bits_raw (const struct device * port ,
@@ -364,14 +354,15 @@ static int gpio_nrfx_port_clear_bits_raw(const struct device *port,
364
354
NRF_GPIO_Type * reg = get_port_cfg (port )-> port ;
365
355
int ret ;
366
356
367
- ret = gpio_nrfx_gpd_retain_clear (port , mask );
357
+ ret = pm_device_runtime_get (port );
368
358
if (ret < 0 ) {
369
359
return ret ;
370
360
}
371
361
362
+ gpio_nrfx_gpd_retain_clear (port , mask );
372
363
nrf_gpio_port_out_clear (reg , mask );
373
-
374
- return gpio_nrfx_gpd_retain_set (port , mask , GPIO_OUTPUT );
364
+ gpio_nrfx_gpd_retain_set ( port , mask , GPIO_OUTPUT );
365
+ return pm_device_runtime_put (port );
375
366
}
376
367
377
368
static int gpio_nrfx_port_toggle_bits (const struct device * port ,
@@ -383,15 +374,16 @@ static int gpio_nrfx_port_toggle_bits(const struct device *port,
383
374
const uint32_t clear_mask = (~value ) & mask ;
384
375
int ret ;
385
376
386
- ret = gpio_nrfx_gpd_retain_clear (port , mask );
377
+ ret = pm_device_runtime_get (port );
387
378
if (ret < 0 ) {
388
379
return ret ;
389
380
}
390
381
382
+ gpio_nrfx_gpd_retain_clear (port , mask );
391
383
nrf_gpio_port_out_set (reg , set_mask );
392
384
nrf_gpio_port_out_clear (reg , clear_mask );
393
-
394
- return gpio_nrfx_gpd_retain_set (port , mask , GPIO_OUTPUT );
385
+ gpio_nrfx_gpd_retain_set ( port , mask , GPIO_OUTPUT );
386
+ return pm_device_runtime_put (port );
395
387
}
396
388
397
389
#ifdef CONFIG_GPIO_NRFX_INTERRUPT
@@ -550,17 +542,68 @@ static void nrfx_gpio_handler(nrfx_gpiote_pin_t abs_pin,
550
542
IRQ_CONNECT(DT_IRQN(node_id), DT_IRQ(node_id, priority), nrfx_isr, \
551
543
NRFX_CONCAT(nrfx_gpiote_, DT_PROP(node_id, instance), _irq_handler), 0);
552
544
545
+ static int gpio_nrfx_pm_suspend (const struct device * port )
546
+ {
547
+ #ifdef CONFIG_SOC_NRF54H20_GPD
548
+ const struct gpio_nrfx_cfg * cfg = get_port_cfg (port );
549
+
550
+ if (cfg -> pad_pd != NRF_GPD_FAST_ACTIVE1 ) {
551
+ return 0 ;
552
+ }
553
+
554
+ return nrf_gpd_release (NRF_GPD_FAST_ACTIVE1 );
555
+ #else
556
+ ARG_UNUSED (port );
557
+ return 0 ;
558
+ #endif
559
+ }
560
+
561
+ static int gpio_nrfx_pm_resume (const struct device * port )
562
+ {
563
+ #ifdef CONFIG_SOC_NRF54H20_GPD
564
+ const struct gpio_nrfx_cfg * cfg = get_port_cfg (port );
565
+
566
+ if (cfg -> pad_pd != NRF_GPD_FAST_ACTIVE1 ) {
567
+ return 0 ;
568
+ }
569
+
570
+ return nrf_gpd_request (NRF_GPD_FAST_ACTIVE1 );
571
+ #else
572
+ ARG_UNUSED (port );
573
+ return 0 ;
574
+ #endif
575
+ }
576
+
577
+ static int gpio_nrfx_pm_hook (const struct device * port , enum pm_device_action action )
578
+ {
579
+ int ret ;
580
+
581
+ switch (action ) {
582
+ case PM_DEVICE_ACTION_SUSPEND :
583
+ ret = gpio_nrfx_pm_suspend (port );
584
+ break ;
585
+ case PM_DEVICE_ACTION_RESUME :
586
+ ret = gpio_nrfx_pm_resume (port );
587
+ break ;
588
+ default :
589
+ ret = - ENOTSUP ;
590
+ break ;
591
+ }
592
+
593
+ return ret ;
594
+ }
595
+
553
596
static int gpio_nrfx_init (const struct device * port )
554
597
{
555
598
const struct gpio_nrfx_cfg * cfg = get_port_cfg (port );
556
599
nrfx_err_t err ;
557
600
558
601
if (!has_gpiote (cfg )) {
559
- return 0 ;
602
+ goto pm_init ;
560
603
}
561
604
562
605
if (nrfx_gpiote_init_check (& cfg -> gpiote )) {
563
- return 0 ;
606
+ goto pm_init ;
564
607
}
565
608
566
609
err = nrfx_gpiote_init (& cfg -> gpiote , 0 /*not used*/ );
@@ -573,7 +616,8 @@ static int gpio_nrfx_init(const struct device *port)
573
616
DT_FOREACH_STATUS_OKAY (nordic_nrf_gpiote , GPIOTE_IRQ_HANDLER_CONNECT );
574
617
#endif /* CONFIG_GPIO_NRFX_INTERRUPT */
575
618
576
- return 0 ;
619
+ pm_init :
620
+ return pm_device_driver_init (port , gpio_nrfx_pm_hook );
577
621
}
578
622
579
623
static DEVICE_API (gpio , gpio_nrfx_drv_api_funcs ) = {
@@ -638,8 +682,10 @@ static DEVICE_API(gpio, gpio_nrfx_drv_api_funcs) = {
638
682
\
639
683
static struct gpio_nrfx_data gpio_nrfx_p##id##_data; \
640
684
\
685
+ PM_DEVICE_DT_INST_DEFINE(id, gpio_nrfx_pm_hook); \
686
+ \
641
687
DEVICE_DT_INST_DEFINE(id, gpio_nrfx_init, \
642
- NULL, \
688
+ PM_DEVICE_DT_INST_GET(id), \
643
689
&gpio_nrfx_p##id##_data, \
644
690
&gpio_nrfx_p##id##_cfg, \
645
691
PRE_KERNEL_1, \
0 commit comments