Skip to content

Commit e7f089c

Browse files
committed
[nrf fromlist] drivers: gpio: nrf: align to nrfx_gpiote extracted control block
Align GPIOTE shim to changes in nrfx instantiation. Upstream PR #: 98527 Signed-off-by: Nikodem Kastelik <[email protected]>
1 parent ea3b856 commit e7f089c

File tree

2 files changed

+91
-56
lines changed

2 files changed

+91
-56
lines changed

drivers/gpio/gpio_nrfx.c

Lines changed: 64 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@
77
#define DT_DRV_COMPAT nordic_nrf_gpio
88

99
#include <nrfx_gpiote.h>
10+
#include <gpiote_nrfx.h>
1011
#include <string.h>
1112
#include <zephyr/drivers/gpio.h>
13+
#include <zephyr/drivers/gpio/gpio_nrf.h>
1214
#include <zephyr/dt-bindings/gpio/nordic-nrf-gpio.h>
1315
#include <zephyr/irq.h>
1416
#include <zephyr/pm/device.h>
@@ -52,9 +54,9 @@ struct gpio_nrfx_cfg {
5254
/* gpio_driver_config needs to be first */
5355
struct gpio_driver_config common;
5456
NRF_GPIO_Type *port;
57+
nrfx_gpiote_t *gpiote;
5558
uint32_t edge_sense;
5659
uint8_t port_num;
57-
nrfx_gpiote_t gpiote;
5860
#if GPIO_HAS_PAD_GROUP
5961
const struct device *pad_group;
6062
#endif
@@ -73,9 +75,16 @@ static inline const struct gpio_nrfx_cfg *get_port_cfg(const struct device *port
7375
return port->config;
7476
}
7577

78+
void * gpio_nrf_gpiote_by_port_get(const struct device *port)
79+
{
80+
const struct gpio_nrfx_cfg *cfg = get_port_cfg(port);
81+
82+
return cfg->gpiote;
83+
}
84+
7685
static bool has_gpiote(const struct gpio_nrfx_cfg *cfg)
7786
{
78-
return cfg->gpiote.p_reg != NULL;
87+
return cfg->gpiote != NULL;
7988
}
8089

8190
static nrf_gpio_pin_pull_t get_pull(gpio_flags_t flags)
@@ -93,7 +102,7 @@ static int gpio_nrfx_pin_configure(const struct device *port, gpio_pin_t pin,
93102
gpio_flags_t flags)
94103
{
95104
int ret = 0;
96-
nrfx_err_t err = NRFX_SUCCESS;
105+
int err = 0;
97106
uint8_t ch;
98107
bool free_ch = false;
99108
const struct gpio_nrfx_cfg *cfg = get_port_cfg(port);
@@ -159,13 +168,13 @@ static int gpio_nrfx_pin_configure(const struct device *port, gpio_pin_t pin,
159168
* to be freed when the pin is reconfigured or disconnected.
160169
*/
161170
if (IS_ENABLED(CONFIG_GPIO_NRFX_INTERRUPT)) {
162-
err = nrfx_gpiote_channel_get(&cfg->gpiote, abs_pin, &ch);
163-
free_ch = (err == NRFX_SUCCESS);
171+
err = nrfx_gpiote_channel_get(cfg->gpiote, abs_pin, &ch);
172+
free_ch = (err == 0);
164173
}
165174

166175
if ((flags & (GPIO_INPUT | GPIO_OUTPUT)) == GPIO_DISCONNECTED) {
167176
/* Ignore the error code. The pin may not have been used. */
168-
(void)nrfx_gpiote_pin_uninit(&cfg->gpiote, abs_pin);
177+
(void)nrfx_gpiote_pin_uninit(cfg->gpiote, abs_pin);
169178
} else {
170179
/* Remove previously configured trigger when pin is reconfigured. */
171180
if (IS_ENABLED(CONFIG_GPIO_NRFX_INTERRUPT)) {
@@ -176,11 +185,9 @@ static int gpio_nrfx_pin_configure(const struct device *port, gpio_pin_t pin,
176185
.p_trigger_config = &trigger_config,
177186
};
178187

179-
err = nrfx_gpiote_input_configure(&cfg->gpiote,
188+
err = nrfx_gpiote_input_configure(cfg->gpiote,
180189
abs_pin, &input_pin_config);
181-
if (err != NRFX_SUCCESS) {
182-
ret = -EINVAL;
183-
190+
if (err < 0) {
184191
goto end;
185192
}
186193
}
@@ -194,19 +201,18 @@ static int gpio_nrfx_pin_configure(const struct device *port, gpio_pin_t pin,
194201
.pull = pull,
195202
};
196203

197-
err = nrfx_gpiote_output_configure(&cfg->gpiote,
204+
err = nrfx_gpiote_output_configure(cfg->gpiote,
198205
abs_pin, &output_config, NULL);
199206
} else {
200207
nrfx_gpiote_input_pin_config_t input_pin_config = {
201208
.p_pull_config = &pull,
202209
};
203210

204-
err = nrfx_gpiote_input_configure(&cfg->gpiote,
211+
err = nrfx_gpiote_input_configure(cfg->gpiote,
205212
abs_pin, &input_pin_config);
206213
}
207214

208-
if (err != NRFX_SUCCESS) {
209-
ret = -EINVAL;
215+
if (err < 0) {
210216
goto end;
211217
}
212218
}
@@ -218,8 +224,8 @@ static int gpio_nrfx_pin_configure(const struct device *port, gpio_pin_t pin,
218224
goto end;
219225
}
220226
#endif
221-
err = nrfx_gpiote_channel_free(&cfg->gpiote, ch);
222-
__ASSERT_NO_MSG(err == NRFX_SUCCESS);
227+
err = nrfx_gpiote_channel_free(cfg->gpiote, ch);
228+
__ASSERT_NO_MSG(err == 0);
223229
}
224230

225231
end:
@@ -393,7 +399,7 @@ static nrfx_gpiote_trigger_t get_trigger(enum gpio_int_mode mode,
393399
NRFX_GPIOTE_TRIGGER_LOTOHI;
394400
}
395401

396-
static nrfx_err_t chan_alloc(const struct gpio_nrfx_cfg *cfg, gpio_pin_t pin, uint8_t *ch)
402+
static int chan_alloc(const struct gpio_nrfx_cfg *cfg, gpio_pin_t pin, uint8_t *ch)
397403
{
398404
#ifdef GPIOTE_FEATURE_FLAG
399405
if (cfg->flags & GPIOTE_FLAG_FIXED_CHAN) {
@@ -403,25 +409,25 @@ static nrfx_err_t chan_alloc(const struct gpio_nrfx_cfg *cfg, gpio_pin_t pin, ui
403409
* - P1: channel => pin - 4, e.g. P1.4 => channel 0, P1.5 => channel 1
404410
* - P2: channel => pin % 8, e.g. P2.0 => channel 0, P2.8 => channel 0
405411
*/
406-
nrfx_err_t err = NRFX_SUCCESS;
412+
int err = 0;
407413

408414
if (cfg->port_num == 1) {
409415
if (pin < 4) {
410-
err = NRFX_ERROR_INVALID_PARAM;
416+
err = -EINVAL;
411417
} else {
412418
*ch = pin - 4;
413419
}
414420
} else if (cfg->port_num == 2) {
415421
*ch = pin & 0x7;
416422
} else {
417-
err = NRFX_ERROR_INVALID_PARAM;
423+
err = -EINVAL;
418424
}
419425

420426
return err;
421427
}
422428
#endif
423429

424-
return nrfx_gpiote_channel_alloc(&cfg->gpiote, ch);
430+
return nrfx_gpiote_channel_alloc(cfg->gpiote, ch);
425431
}
426432

427433
static int gpio_nrfx_pin_interrupt_configure(const struct device *port,
@@ -431,15 +437,15 @@ static int gpio_nrfx_pin_interrupt_configure(const struct device *port,
431437
{
432438
const struct gpio_nrfx_cfg *cfg = get_port_cfg(port);
433439
uint32_t abs_pin = NRF_GPIO_PIN_MAP(cfg->port_num, pin);
434-
nrfx_err_t err;
440+
int err;
435441
uint8_t ch;
436442

437443
if (!has_gpiote(cfg)) {
438444
return -ENOTSUP;
439445
}
440446

441447
if (mode == GPIO_INT_MODE_DISABLED) {
442-
nrfx_gpiote_trigger_disable(&cfg->gpiote, abs_pin);
448+
nrfx_gpiote_trigger_disable(cfg->gpiote, abs_pin);
443449

444450
return 0;
445451
}
@@ -457,11 +463,11 @@ static int gpio_nrfx_pin_interrupt_configure(const struct device *port,
457463
if (!(BIT(pin) & cfg->edge_sense) &&
458464
(mode == GPIO_INT_MODE_EDGE) &&
459465
(nrf_gpio_pin_dir_get(abs_pin) == NRF_GPIO_PIN_DIR_INPUT)) {
460-
err = nrfx_gpiote_channel_get(&cfg->gpiote, abs_pin, &ch);
461-
if (err == NRFX_ERROR_INVALID_PARAM) {
466+
err = nrfx_gpiote_channel_get(cfg->gpiote, abs_pin, &ch);
467+
if (err == -EINVAL) {
462468
err = chan_alloc(cfg, pin, &ch);
463-
if (err != NRFX_SUCCESS) {
464-
return -ENOMEM;
469+
if (err < 0) {
470+
return err;
465471
}
466472
}
467473

@@ -475,19 +481,19 @@ static int gpio_nrfx_pin_interrupt_configure(const struct device *port,
475481
/* If edge mode with channel was previously used and we are changing to sense or
476482
* level triggered, we must free the channel.
477483
*/
478-
err = nrfx_gpiote_channel_get(&cfg->gpiote, abs_pin, &ch);
479-
if (err == NRFX_SUCCESS) {
480-
err = nrfx_gpiote_channel_free(&cfg->gpiote, ch);
481-
__ASSERT_NO_MSG(err == NRFX_SUCCESS);
484+
err = nrfx_gpiote_channel_get(cfg->gpiote, abs_pin, &ch);
485+
if (err == 0) {
486+
err = nrfx_gpiote_channel_free(cfg->gpiote, ch);
487+
__ASSERT_NO_MSG(err == 0);
482488
}
483489
}
484490

485-
err = nrfx_gpiote_input_configure(&cfg->gpiote, abs_pin, &input_pin_config);
486-
if (err != NRFX_SUCCESS) {
487-
return -EINVAL;
491+
err = nrfx_gpiote_input_configure(cfg->gpiote, abs_pin, &input_pin_config);
492+
if (err < 0) {
493+
return err;
488494
}
489495

490-
nrfx_gpiote_trigger_enable(&cfg->gpiote, abs_pin, true);
496+
nrfx_gpiote_trigger_enable(cfg->gpiote, abs_pin, true);
491497

492498
return 0;
493499
}
@@ -576,9 +582,12 @@ static void nrfx_gpio_handler(nrfx_gpiote_pin_t abs_pin,
576582
}
577583
#endif /* CONFIG_GPIO_NRFX_INTERRUPT */
578584

579-
#define GPIOTE_IRQ_HANDLER_CONNECT(node_id) \
580-
IRQ_CONNECT(DT_IRQN(node_id), DT_IRQ(node_id, priority), nrfx_isr, \
581-
NRFX_CONCAT(nrfx_gpiote_, DT_PROP(node_id, instance), _irq_handler), 0);
585+
#define GPIOTE_IRQ_HANDLER_CONNECT(node_id) \
586+
IRQ_CONNECT(DT_IRQN(node_id), \
587+
DT_IRQ(node_id, priority), \
588+
nrfx_gpiote_irq_handler, \
589+
&GPIOTE_NRFX_INST_BY_NODE(node_id), \
590+
0);
582591

583592
static int gpio_nrfx_pm_suspend(const struct device *port)
584593
{
@@ -626,23 +635,23 @@ static int gpio_nrfx_pm_hook(const struct device *port, enum pm_device_action ac
626635
static int gpio_nrfx_init(const struct device *port)
627636
{
628637
const struct gpio_nrfx_cfg *cfg = get_port_cfg(port);
629-
nrfx_err_t err;
638+
int err;
630639

631640
if (!has_gpiote(cfg)) {
632641
goto pm_init;
633642
}
634643

635-
if (nrfx_gpiote_init_check(&cfg->gpiote)) {
644+
if (nrfx_gpiote_init_check(cfg->gpiote)) {
636645
goto pm_init;
637646
}
638647

639-
err = nrfx_gpiote_init(&cfg->gpiote, 0 /*not used*/);
640-
if (err != NRFX_SUCCESS) {
648+
err = nrfx_gpiote_init(cfg->gpiote, 0 /*not used*/);
649+
if (err != 0) {
641650
return -EIO;
642651
}
643652

644653
#ifdef CONFIG_GPIO_NRFX_INTERRUPT
645-
nrfx_gpiote_global_callback_set(&cfg->gpiote, nrfx_gpio_handler, NULL);
654+
nrfx_gpiote_global_callback_set(cfg->gpiote, nrfx_gpio_handler, NULL);
646655
DT_FOREACH_STATUS_OKAY(nordic_nrf_gpiote, GPIOTE_IRQ_HANDLER_CONNECT);
647656
#endif /* CONFIG_GPIO_NRFX_INTERRUPT */
648657

@@ -669,24 +678,24 @@ static DEVICE_API(gpio, gpio_nrfx_drv_api_funcs) = {
669678
#endif
670679
};
671680

672-
#define GPIOTE_INST(id) DT_PROP(GPIOTE_PHANDLE(id), instance)
673-
674-
#define GPIOTE_INSTANCE(id) \
675-
COND_CODE_1(DT_INST_NODE_HAS_PROP(id, gpiote_instance), \
676-
(NRFX_GPIOTE_INSTANCE(GPIOTE_INST(id))), \
677-
({ .p_reg = NULL }))
678-
679681
/* Device instantiation is done with node labels because 'port_num' is
680682
* the peripheral number by SoC numbering. We therefore cannot use
681683
* DT_INST APIs here without wider changes.
682684
*/
683685

686+
#define HAS_GPIOTE(id) DT_INST_NODE_HAS_PROP(id, gpiote_instance)
687+
684688
#define GPIOTE_CHECK(id) \
685-
COND_CODE_1(DT_INST_NODE_HAS_PROP(id, gpiote_instance), \
686-
(BUILD_ASSERT(DT_NODE_HAS_STATUS_OKAY(GPIOTE_PHANDLE(id)), \
689+
COND_CODE_1(HAS_GPIOTE(id), \
690+
(BUILD_ASSERT(DT_NODE_HAS_STATUS_OKAY(GPIOTE_PHANDLE(id)), \
687691
"Please enable GPIOTE instance for used GPIO port!")), \
688692
())
689693

694+
#define GPIOTE_REF(id) \
695+
COND_CODE_1(HAS_GPIOTE(id), \
696+
(&GPIOTE_NRFX_INST_BY_NODE(GPIOTE_PHANDLE(id))), \
697+
(NULL))
698+
690699
#if GPIO_HAS_PAD_GROUP
691700
#define GPIO_NRF_PAD_GROUP_INIT(id) \
692701
.pad_group = DEVICE_DT_GET(DT_INST_CHILD(id, pad_group)),
@@ -696,15 +705,16 @@ static DEVICE_API(gpio, gpio_nrfx_drv_api_funcs) = {
696705

697706
#define GPIO_NRF_DEVICE(id) \
698707
GPIOTE_CHECK(id); \
708+
static struct gpio_nrfx_data gpio_nrfx_p##id##_data; \
699709
static const struct gpio_nrfx_cfg gpio_nrfx_p##id##_cfg = { \
700710
.common = { \
701711
.port_pin_mask = \
702712
GPIO_PORT_PIN_MASK_FROM_DT_INST(id), \
703713
}, \
704714
.port = _CONCAT(NRF_P, DT_INST_PROP(id, port)), \
705-
.port_num = DT_INST_PROP(id, port), \
715+
.gpiote = GPIOTE_REF(id), \
706716
.edge_sense = DT_INST_PROP_OR(id, sense_edge_mask, 0), \
707-
.gpiote = GPIOTE_INSTANCE(id), \
717+
.port_num = DT_INST_PROP(id, port), \
708718
GPIO_NRF_PAD_GROUP_INIT(id) \
709719
IF_ENABLED(GPIOTE_FEATURE_FLAG, \
710720
(.flags = \
@@ -715,8 +725,6 @@ static DEVICE_API(gpio, gpio_nrfx_drv_api_funcs) = {
715725
) \
716726
}; \
717727
\
718-
static struct gpio_nrfx_data gpio_nrfx_p##id##_data; \
719-
\
720728
PM_DEVICE_DT_INST_DEFINE(id, gpio_nrfx_pm_hook); \
721729
\
722730
DEVICE_DT_INST_DEFINE(id, gpio_nrfx_init, \
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* Copyright (c) 2025 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#ifndef ZEPHYR_INCLUDE_DRIVERS_GPIO_GPIO_NRF_H
8+
#define ZEPHYR_INCLUDE_DRIVERS_GPIO_GPIO_NRF_H
9+
10+
#ifdef __cplusplus
11+
extern "C" {
12+
#endif
13+
14+
/** @brief Get pointer to GPIOTE driver instance
15+
* associated with specified port device node.
16+
*
17+
* @param port Pointer to port device node.
18+
*
19+
* @return Pointer to GPIOTE driver instance. NULL if not found.
20+
*/
21+
void * gpio_nrf_gpiote_by_port_get(const struct device *port);
22+
23+
#ifdef __cplusplus
24+
}
25+
#endif
26+
27+
#endif /* ZEPHYR_INCLUDE_DRIVERS_GPIO_GPIO_NRF_H */

0 commit comments

Comments
 (0)