Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
142 changes: 49 additions & 93 deletions drivers/gpio/gpio_nrfx.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,11 @@
#include <string.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/dt-bindings/gpio/nordic-nrf-gpio.h>
#include <zephyr/irq.h>
#include <zephyr/pm/device.h>
#include <zephyr/pm/device_runtime.h>
#include <zephyr/irq.h>

#include <zephyr/drivers/gpio/gpio_utils.h>

#if DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_gpio_pad_group)
#define GPIO_HAS_PAD_GROUP 1
#else
#define GPIO_HAS_PAD_GROUP 0
#endif

#define GPIOTE_PHANDLE(id) DT_INST_PHANDLE(id, gpiote_instance)
#define GPIOTE_PROP(idx, prop) DT_PROP(GPIOTE(idx), prop)

Expand Down Expand Up @@ -55,9 +48,6 @@ struct gpio_nrfx_cfg {
uint32_t edge_sense;
uint8_t port_num;
nrfx_gpiote_t gpiote;
#if GPIO_HAS_PAD_GROUP
const struct device *pad_group;
#endif
#if defined(GPIOTE_FEATURE_FLAG)
uint32_t flags;
#endif
Expand All @@ -78,6 +68,34 @@ static bool has_gpiote(const struct gpio_nrfx_cfg *cfg)
return cfg->gpiote.p_reg != NULL;
}

#if NRF_GPIO_HAS_RETENTION_SETCLEAR

static void port_retain_set(const struct gpio_nrfx_cfg *cfg, uint32_t mask)
{
nrf_gpio_port_retain_enable(cfg->port, mask);
}

static void port_retain_clear(const struct gpio_nrfx_cfg *cfg, uint32_t mask)
{
nrf_gpio_port_retain_disable(cfg->port, mask);
}

#else

static void port_retain_set(const struct gpio_nrfx_cfg *cfg, uint32_t mask)
{
ARG_UNUSED(cfg);
ARG_UNUSED(mask);
}

static void port_retain_clear(const struct gpio_nrfx_cfg *cfg, uint32_t mask)
{
ARG_UNUSED(cfg);
ARG_UNUSED(mask);
}

#endif

static nrf_gpio_pin_pull_t get_pull(gpio_flags_t flags)
{
if (flags & GPIO_PULL_UP) {
Expand All @@ -100,7 +118,6 @@ static int gpio_nrfx_pin_configure(const struct device *port, gpio_pin_t pin,
nrfx_gpiote_pin_t abs_pin = NRF_GPIO_PIN_MAP(cfg->port_num, pin);
nrf_gpio_pin_pull_t pull = get_pull(flags);
nrf_gpio_pin_drive_t drive;
int pm_ret;

switch (flags & (NRF_GPIO_DRIVE_MSK | GPIO_OPEN_DRAIN)) {
case NRF_GPIO_DRIVE_S0S1:
Expand Down Expand Up @@ -131,10 +148,7 @@ static int gpio_nrfx_pin_configure(const struct device *port, gpio_pin_t pin,
return -EINVAL;
}

ret = pm_device_runtime_get(port);
if (ret < 0) {
return ret;
}
port_retain_clear(cfg, BIT(pin));

if (flags & GPIO_OUTPUT_INIT_HIGH) {
nrf_gpio_port_out_set(cfg->port, BIT(pin));
Expand Down Expand Up @@ -196,6 +210,8 @@ static int gpio_nrfx_pin_configure(const struct device *port, gpio_pin_t pin,

err = nrfx_gpiote_output_configure(&cfg->gpiote,
abs_pin, &output_config, NULL);

port_retain_set(cfg, BIT(pin));
} else {
nrfx_gpiote_input_pin_config_t input_pin_config = {
.p_pull_config = &pull,
Expand Down Expand Up @@ -223,11 +239,11 @@ static int gpio_nrfx_pin_configure(const struct device *port, gpio_pin_t pin,
}

end:
pm_ret = pm_device_runtime_put(port);

return (ret != 0) ? ret : pm_ret;
return ret;
}



#ifdef CONFIG_GPIO_GET_CONFIG
static int gpio_nrfx_pin_get_config(const struct device *port, gpio_pin_t pin,
gpio_flags_t *flags)
Expand Down Expand Up @@ -315,49 +331,37 @@ static int gpio_nrfx_port_set_masked_raw(const struct device *port,
gpio_port_value_t value)
{
NRF_GPIO_Type *reg = get_port_cfg(port)->port;
int ret;

const uint32_t set_mask = value & mask;
const uint32_t clear_mask = (~set_mask) & mask;

ret = pm_device_runtime_get(port);
if (ret < 0) {
return ret;
}

port_retain_clear(get_port_cfg(port), mask);
nrf_gpio_port_out_set(reg, set_mask);
nrf_gpio_port_out_clear(reg, clear_mask);
return pm_device_runtime_put(port);
port_retain_set(get_port_cfg(port), mask);
return 0;
}

static int gpio_nrfx_port_set_bits_raw(const struct device *port,
gpio_port_pins_t mask)
{
NRF_GPIO_Type *reg = get_port_cfg(port)->port;
int ret;

ret = pm_device_runtime_get(port);
if (ret < 0) {
return ret;
}

port_retain_clear(get_port_cfg(port), mask);
nrf_gpio_port_out_set(reg, mask);
return pm_device_runtime_put(port);
port_retain_set(get_port_cfg(port), mask);
return 0;
}

static int gpio_nrfx_port_clear_bits_raw(const struct device *port,
gpio_port_pins_t mask)
{
NRF_GPIO_Type *reg = get_port_cfg(port)->port;
int ret;

ret = pm_device_runtime_get(port);
if (ret < 0) {
return ret;
}

port_retain_clear(get_port_cfg(port), mask);
nrf_gpio_port_out_clear(reg, mask);
return pm_device_runtime_put(port);
port_retain_set(get_port_cfg(port), mask);
return 0;
}

static int gpio_nrfx_port_toggle_bits(const struct device *port,
Expand All @@ -367,16 +371,12 @@ static int gpio_nrfx_port_toggle_bits(const struct device *port,
const uint32_t value = nrf_gpio_port_out_read(reg) ^ mask;
const uint32_t set_mask = value & mask;
const uint32_t clear_mask = (~value) & mask;
int ret;

ret = pm_device_runtime_get(port);
if (ret < 0) {
return ret;
}

port_retain_clear(get_port_cfg(port), mask);
nrf_gpio_port_out_set(reg, set_mask);
nrf_gpio_port_out_clear(reg, clear_mask);
return pm_device_runtime_put(port);
port_retain_set(get_port_cfg(port), mask);
return 0;
}

#ifdef CONFIG_GPIO_NRFX_INTERRUPT
Expand Down Expand Up @@ -580,47 +580,11 @@ static void nrfx_gpio_handler(nrfx_gpiote_pin_t abs_pin,
IRQ_CONNECT(DT_IRQN(node_id), DT_IRQ(node_id, priority), nrfx_isr, \
NRFX_CONCAT(nrfx_gpiote_, DT_PROP(node_id, instance), _irq_handler), 0);

static int gpio_nrfx_pm_suspend(const struct device *port)
static int gpio_nrfx_pm_hook(const struct device *port, enum pm_device_action action)
{
#if GPIO_HAS_PAD_GROUP
const struct gpio_nrfx_cfg *cfg = get_port_cfg(port);

return pm_device_runtime_put(cfg->pad_group);
#else
ARG_UNUSED(port);
ARG_UNUSED(action);
return 0;
#endif
}

static int gpio_nrfx_pm_resume(const struct device *port)
{
#if GPIO_HAS_PAD_GROUP
const struct gpio_nrfx_cfg *cfg = get_port_cfg(port);

return pm_device_runtime_get(cfg->pad_group);
#else
ARG_UNUSED(port);
return 0;
#endif
}

static int gpio_nrfx_pm_hook(const struct device *port, enum pm_device_action action)
{
int ret;

switch (action) {
case PM_DEVICE_ACTION_SUSPEND:
ret = gpio_nrfx_pm_suspend(port);
break;
case PM_DEVICE_ACTION_RESUME:
ret = gpio_nrfx_pm_resume(port);
break;
default:
ret = -ENOTSUP;
break;
}

return ret;
}

static int gpio_nrfx_init(const struct device *port)
Expand Down Expand Up @@ -687,13 +651,6 @@ static DEVICE_API(gpio, gpio_nrfx_drv_api_funcs) = {
"Please enable GPIOTE instance for used GPIO port!")), \
())

#if GPIO_HAS_PAD_GROUP
#define GPIO_NRF_PAD_GROUP_INIT(id) \
.pad_group = DEVICE_DT_GET(DT_INST_CHILD(id, pad_group)),
#else
#define GPIO_NRF_PAD_GROUP_INIT(id)
#endif

#define GPIO_NRF_DEVICE(id) \
GPIOTE_CHECK(id); \
static const struct gpio_nrfx_cfg gpio_nrfx_p##id##_cfg = { \
Expand All @@ -705,7 +662,6 @@ static DEVICE_API(gpio, gpio_nrfx_drv_api_funcs) = {
.port_num = DT_INST_PROP(id, port), \
.edge_sense = DT_INST_PROP_OR(id, sense_edge_mask, 0), \
.gpiote = GPIOTE_INSTANCE(id), \
GPIO_NRF_PAD_GROUP_INIT(id) \
IF_ENABLED(GPIOTE_FEATURE_FLAG, \
(.flags = \
(DT_PROP_OR(GPIOTE_PHANDLE(id), no_port_event, 0) ? \
Expand Down
73 changes: 10 additions & 63 deletions drivers/pinctrl/pinctrl_nrf.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
*/

#include <zephyr/drivers/pinctrl.h>
#include <zephyr/pm/device_runtime.h>
#include <zephyr/sys/atomic.h>

#include <hal/nrf_gpio.h>
Expand Down Expand Up @@ -111,75 +110,23 @@ static const nrf_gpio_pin_drive_t drive_modes[NRF_DRIVE_COUNT] = {
#define NRF_PSEL_TDM(reg, line) ((NRF_TDM_Type *)reg)->PSEL.line
#endif

#if DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_gpio_pad_group)
#define GPIO_HAS_PAD_GROUP 1
#else
#define GPIO_HAS_PAD_GROUP 0
#endif

#if GPIO_HAS_PAD_GROUP

#define GPIO_PAD_GROUP_GET_OR_NULL(idx, _) \
DEVICE_DT_GET_OR_NULL(DT_NODELABEL(_CONCAT(gpio_pad_group, idx)))

static const struct device *const pad_groups[] = {
LISTIFY(10, GPIO_PAD_GROUP_GET_OR_NULL, (,))
};

static atomic_t pad_group_masks[ARRAY_SIZE(pad_groups)];

static int pad_group_request_pin(uint16_t pin_number)
{
uint8_t port_number = NRF_GET_PORT(pin_number);
uint8_t port_pin_number = NRF_GET_PORT_PIN(pin_number);
const struct device *pad_group = pad_groups[port_number];
atomic_t *pad_group_mask = &pad_group_masks[port_number];

if (atomic_test_and_set_bit(pad_group_mask, port_pin_number)) {
/* already requested */
return 0;
}

if (pm_device_runtime_get(pad_group)) {
atomic_clear_bit(pad_group_mask, port_pin_number);
return -EIO;
}

return 0;
}
#if NRF_GPIO_HAS_RETENTION_SETCLEAR

static int pad_group_release_pin(uint16_t pin_number)
static void port_pin_retain_set(uint16_t pin_number, bool enable)
{
uint8_t port_number = NRF_GET_PORT(pin_number);
uint8_t port_pin_number = NRF_GET_PORT_PIN(pin_number);
const struct device *pad_group = pad_groups[port_number];
atomic_t *pad_group_mask = &pad_group_masks[port_number];

if (!atomic_test_and_clear_bit(pad_group_mask, port_pin_number)) {
/* already released */
return 0;
}

if (pm_device_runtime_put(pad_group)) {
atomic_set_bit(pad_group_mask, port_pin_number);
return -EIO;
if (enable) {
nrf_gpio_pin_retain_enable(pin_number);
} else {
nrf_gpio_pin_retain_disable(pin_number);
}

return 0;
}

#else

static int pad_group_request_pin(uint16_t pin_number)
static void port_pin_retain_set(uint16_t pin_number, bool enable)
{
ARG_UNUSED(pin_number);
return 0;
}

static int pad_group_release_pin(uint16_t pin_number)
{
ARG_UNUSED(pin_number);
return 0;
ARG_UNUSED(enable);
}

#endif
Expand Down Expand Up @@ -577,7 +524,7 @@ int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt,
uint32_t pin = psel;

/* enable pin */
pad_group_request_pin(pin);
port_pin_retain_set(pin, false);

if (write != NO_WRITE) {
nrf_gpio_pin_write(pin, write);
Expand All @@ -595,7 +542,7 @@ int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt,

if (NRF_GET_LP(pins[i]) == NRF_LP_ENABLE) {
/* disable pin and pin clock */
pad_group_release_pin(pin);
port_pin_retain_set(pin, true);
port_pin_clock_set(pin, false);
} else {
/* configure pin clock */
Expand Down
1 change: 0 additions & 1 deletion drivers/power_domain/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ zephyr_library_sources_ifdef(CONFIG_POWER_DOMAIN_INTEL_ADSP power_domain_intel_a
zephyr_library_sources_ifdef(CONFIG_POWER_DOMAIN_NXP_SCU power_domain_nxp_scu.c)
zephyr_library_sources_ifdef(CONFIG_POWER_DOMAIN_NRFS_GDPWR power_domain_nrfs_gdpwr.c)
zephyr_library_sources_ifdef(CONFIG_POWER_DOMAIN_NRFS_SWEXT power_domain_nrfs_swext.c)
zephyr_library_sources_ifdef(CONFIG_POWER_DOMAIN_NRF_GPIO_PAD_GROUP power_domain_nrf_gpio_pad_group.c)
zephyr_library_sources_ifdef(CONFIG_POWER_DOMAIN_SOC_PM_STATE power_domain_soc_state_change.c)
zephyr_library_sources_ifdef(CONFIG_POWER_DOMAIN_TISCI power_domain_tisci.c)
zephyr_library_sources_ifdef(CONFIG_POWER_DOMAIN_SILABS_SIWX91X power_domain_silabs_siwx91x.c)
1 change: 0 additions & 1 deletion drivers/power_domain/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,6 @@ endif #POWER_DOMAIN_TISCI

rsource "Kconfig.nrfs_gdpwr"
rsource "Kconfig.nrfs_swext"
rsource "Kconfig.nrf_gpio_pad_group"
rsource "Kconfig.silabs_siwx91x"

endif
7 changes: 0 additions & 7 deletions drivers/power_domain/Kconfig.nrf_gpio_pad_group

This file was deleted.

Loading
Loading