Skip to content

Device deinit driver support #2987

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
Open
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
21 changes: 6 additions & 15 deletions drivers/gpio/gpio_nrfx.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,20 +64,15 @@ static nrf_gpio_pin_pull_t get_pull(gpio_flags_t flags)
return NRF_GPIO_PIN_NOPULL;
}

static void gpio_nrfx_gpd_retain_set(const struct device *port, uint32_t mask, gpio_flags_t flags)
static void gpio_nrfx_gpd_retain_set(const struct device *port, uint32_t mask)
{
#ifdef CONFIG_SOC_NRF54H20_GPD
const struct gpio_nrfx_cfg *cfg = get_port_cfg(port);

if (cfg->pad_pd != NRF_GPD_FAST_ACTIVE1 || !(flags & GPIO_OUTPUT)) {
return;
}

nrf_gpio_port_retain_enable(cfg->port, mask);
#else
ARG_UNUSED(port);
ARG_UNUSED(mask);
ARG_UNUSED(flags);
#endif
}

Expand All @@ -86,10 +81,6 @@ static void gpio_nrfx_gpd_retain_clear(const struct device *port, uint32_t mask)
#ifdef CONFIG_SOC_NRF54H20_GPD
const struct gpio_nrfx_cfg *cfg = get_port_cfg(port);

if (cfg->pad_pd != NRF_GPD_FAST_ACTIVE1) {
return;
}

nrf_gpio_port_retain_disable(cfg->port, mask);
#else
ARG_UNUSED(port);
Expand Down Expand Up @@ -225,7 +216,7 @@ static int gpio_nrfx_pin_configure(const struct device *port, gpio_pin_t pin,
}

end:
gpio_nrfx_gpd_retain_set(port, BIT(pin), flags);
gpio_nrfx_gpd_retain_set(port, BIT(pin));
return pm_device_runtime_put(port);
}

Expand Down Expand Up @@ -329,7 +320,7 @@ static int gpio_nrfx_port_set_masked_raw(const struct device *port,
gpio_nrfx_gpd_retain_clear(port, mask);
nrf_gpio_port_out_set(reg, set_mask);
nrf_gpio_port_out_clear(reg, clear_mask);
gpio_nrfx_gpd_retain_set(port, mask, GPIO_OUTPUT);
gpio_nrfx_gpd_retain_set(port, mask);
return pm_device_runtime_put(port);
}

Expand All @@ -346,7 +337,7 @@ static int gpio_nrfx_port_set_bits_raw(const struct device *port,

gpio_nrfx_gpd_retain_clear(port, mask);
nrf_gpio_port_out_set(reg, mask);
gpio_nrfx_gpd_retain_set(port, mask, GPIO_OUTPUT);
gpio_nrfx_gpd_retain_set(port, mask);
return pm_device_runtime_put(port);
}

Expand All @@ -363,7 +354,7 @@ static int gpio_nrfx_port_clear_bits_raw(const struct device *port,

gpio_nrfx_gpd_retain_clear(port, mask);
nrf_gpio_port_out_clear(reg, mask);
gpio_nrfx_gpd_retain_set(port, mask, GPIO_OUTPUT);
gpio_nrfx_gpd_retain_set(port, mask);
return pm_device_runtime_put(port);
}

Expand All @@ -384,7 +375,7 @@ static int gpio_nrfx_port_toggle_bits(const struct device *port,
gpio_nrfx_gpd_retain_clear(port, mask);
nrf_gpio_port_out_set(reg, set_mask);
nrf_gpio_port_out_clear(reg, clear_mask);
gpio_nrfx_gpd_retain_set(port, mask, GPIO_OUTPUT);
gpio_nrfx_gpd_retain_set(port, mask);
return pm_device_runtime_put(port);
}

Expand Down
8 changes: 7 additions & 1 deletion drivers/i2c/i2c_nrfx_twim.c
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,11 @@
return i2c_nrfx_twim_common_init(dev);
}

static int i2c_nrfx_twim_deinit(const struct device *dev)
{
return i2c_nrfx_twim_common_deinit(dev);
}

static DEVICE_API(i2c, i2c_nrfx_twim_driver_api) = {
.configure = i2c_nrfx_twim_configure,
.transfer = i2c_nrfx_twim_transfer,
Expand Down Expand Up @@ -280,15 +285,16 @@
}; \
PM_DEVICE_DT_DEFINE(I2C(idx), twim_nrfx_pm_action, \
PM_DEVICE_ISR_SAFE); \
I2C_DEVICE_DT_DEFINE(I2C(idx), \
I2C_DEVICE_DT_DEINIT_DEFINE(I2C(idx), \
i2c_nrfx_twim_init, \
i2c_nrfx_twim_deinit, \
PM_DEVICE_DT_GET(I2C(idx)), \
&twim_##idx##_data, \
&twim_##idx##z_config, \
POST_KERNEL, \
CONFIG_I2C_INIT_PRIORITY, \
&i2c_nrfx_twim_driver_api)

Check notice on line 297 in drivers/i2c/i2c_nrfx_twim.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

drivers/i2c/i2c_nrfx_twim.c:297 -#define I2C_NRFX_TWIM_DEVICE(idx) \ - NRF_DT_CHECK_NODE_HAS_PINCTRL_SLEEP(I2C(idx)); \ - BUILD_ASSERT(I2C_FREQUENCY(idx) != \ - I2C_NRFX_TWIM_INVALID_FREQUENCY, \ - "Wrong I2C " #idx " frequency setting in dts"); \ - static void irq_connect##idx(void) \ - { \ - IRQ_CONNECT(DT_IRQN(I2C(idx)), DT_IRQ(I2C(idx), priority), \ - nrfx_isr, nrfx_twim_##idx##_irq_handler, 0); \ - } \ +#define I2C_NRFX_TWIM_DEVICE(idx) \ + NRF_DT_CHECK_NODE_HAS_PINCTRL_SLEEP(I2C(idx)); \ + BUILD_ASSERT(I2C_FREQUENCY(idx) != I2C_NRFX_TWIM_INVALID_FREQUENCY, \ + "Wrong I2C " #idx " frequency setting in dts"); \ + static void irq_connect##idx(void) \ + { \ + IRQ_CONNECT(DT_IRQN(I2C(idx)), DT_IRQ(I2C(idx), priority), nrfx_isr, \ + nrfx_twim_##idx##_irq_handler, 0); \ + } \ IF_ENABLED(USES_MSG_BUF(idx), \ (static uint8_t twim_##idx##_msg_buf[MSG_BUF_SIZE(idx)] \ - I2C_MEMORY_SECTION(idx);)) \ - static struct i2c_nrfx_twim_data twim_##idx##_data; \ - PINCTRL_DT_DEFINE(I2C(idx)); \ - static const \ - struct i2c_nrfx_twim_common_config twim_##idx##z_config = { \ - .twim = NRFX_TWIM_INSTANCE(idx), \ - .twim_config = { \ - .skip_gpio_cfg = true, \ - .skip_psel_cfg = true, \ - .frequency = I2C_FREQUENCY(idx), \ - }, \ - .event_handler = event_handler, \ - .msg_buf_size = MSG_BUF_SIZE(idx), \ - .irq_connect = irq_connect##idx, \ - .pcfg = PINCTRL_DT_DEV_CONFIG_GET(I2C(idx)), \ + I2C_MEMORY_SECTION(idx);)) \ + static struct i2c_nrfx_twim_data twim_##idx##_data; \ + PINCTRL_DT_DEFINE(I2C(idx)); \ + static const struct i2c_nrfx_twim_common_config twim_##idx##z_config = { \ + .twim = NRFX_TWIM_INSTANCE(idx), \ + .twim_config = \ + { \ + .skip_gpio_cfg = true, \ + .skip_psel_cfg = true, \ + .frequency = I2C_FREQUENCY(idx), \ + }, \ + .event_handler = event_handler, \ + .msg_buf_size = MSG_BUF_SIZE(idx), \ + .irq_connect = irq_connect##idx, \ + .pcfg = PINCTRL_DT_DEV_CONFIG_GET(I2C(idx)), \ IF_ENABLED(USES_MSG_BUF(idx), \ - (.msg_buf = twim_##idx##_msg_buf,)) \ - .max_transfer_size = BIT_MASK( \ - DT_PROP(I2C(idx), easydma_maxcnt_bits)), \ - }; \ - PM_DEVICE_DT_DEFINE(I2C(idx), twim_nrfx_pm_action, \ - PM_DEVICE_ISR_SAFE); \ - I2C_DEVICE_DT_DEINIT_DEFINE(I2C(idx), \ - i2c_nrfx_twim_init, \ - i2c_nrfx_twim_deinit, \ - PM_DEVICE_DT_GET(I2C(idx)), \ - &twim_##idx##_data, \ - &twim_##idx##z_config, \ - POST_KERNEL, \ - C
#define I2C_MEMORY_SECTION(idx) \
COND_CODE_1(I2C_HAS_PROP(idx, memory_regions), \
(__attribute__((__section__(LINKER_DT_NODE_REGION_NAME( \
Expand Down
50 changes: 45 additions & 5 deletions drivers/i2c/i2c_nrfx_twim_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,18 +102,30 @@
return ret;
}

int twim_nrfx_pm_action(const struct device *dev, enum pm_device_action action)
void twim_nrfx_pm_resume(const struct device *dev)
{
const struct i2c_nrfx_twim_common_config *config = dev->config;

(void)pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT);
nrfx_twim_enable(&config->twim);
}

void twim_nrfx_pm_suspend(const struct device *dev)
{
const struct i2c_nrfx_twim_common_config *config = dev->config;

nrfx_twim_disable(&config->twim);
(void)pinctrl_apply_state(config->pcfg, PINCTRL_STATE_SLEEP);
}

int twim_nrfx_pm_action(const struct device *dev, enum pm_device_action action)
{
switch (action) {
case PM_DEVICE_ACTION_RESUME:
(void)pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT);
nrfx_twim_enable(&config->twim);
twim_nrfx_pm_resume(dev);
break;
case PM_DEVICE_ACTION_SUSPEND:
nrfx_twim_disable(&config->twim);
(void)pinctrl_apply_state(config->pcfg, PINCTRL_STATE_SLEEP);
twim_nrfx_pm_suspend(dev);
break;
default:
return -ENOTSUP;
Expand All @@ -138,3 +150,31 @@

return pm_device_driver_init(dev, twim_nrfx_pm_action);
}

int i2c_nrfx_twim_common_deinit(const struct device *dev)
{
const struct i2c_nrfx_twim_common_config *config = dev->config;
#if CONFIG_PM_DEVICE
enum pm_device_state state;
#endif

#if CONFIG_PM_DEVICE
/*
* PM must have suspended the device before driver can
* be deinitialized
*/
(void)pm_device_state_get(dev, &state);
if (state != PM_DEVICE_STATE_SUSPENDED &&
state != PM_DEVICE_STATE_OFF) {
LOG_ERR("device active");

Check notice on line 169 in drivers/i2c/i2c_nrfx_twim_common.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

drivers/i2c/i2c_nrfx_twim_common.c:169 - if (state != PM_DEVICE_STATE_SUSPENDED && - state != PM_DEVICE_STATE_OFF) { + if (state != PM_DEVICE_STATE_SUSPENDED && state != PM_DEVICE_STATE_OFF) {
return -EBUSY;
}
#else
/* Suspend device */
twim_nrfx_pm_suspend(dev);
#endif

/* Uninit device hardware */
nrfx_twim_uninit(&config->twim);
return 0;
}
1 change: 1 addition & 0 deletions drivers/i2c/i2c_nrfx_twim_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ struct i2c_nrfx_twim_common_config {
};

int i2c_nrfx_twim_common_init(const struct device *dev);
int i2c_nrfx_twim_common_deinit(const struct device *dev);
int i2c_nrfx_twim_configure(const struct device *dev, uint32_t i2c_config);
int i2c_nrfx_twim_recover_bus(const struct device *dev);
int i2c_nrfx_twim_msg_transfer(const struct device *dev, uint8_t flags, uint8_t *buf,
Expand Down
14 changes: 10 additions & 4 deletions drivers/i2c/i2c_nrfx_twim_rtio.c
Original file line number Diff line number Diff line change
Expand Up @@ -203,14 +203,19 @@
.iodev_submit = i2c_nrfx_twim_rtio_submit,
};

int i2c_nrfx_twim_rtio_init(const struct device *dev)
static int i2c_nrfx_twim_rtio_init(const struct device *dev)
{
const struct i2c_nrfx_twim_rtio_config *config = dev->config;

i2c_rtio_init(config->ctx, dev);
return i2c_nrfx_twim_common_init(dev);
}

static int i2c_nrfx_twim_rtio_deinit(const struct device *dev)
{
return i2c_nrfx_twim_common_deinit(dev);
}

#define CONCAT_BUF_SIZE(idx) \
COND_CODE_1(DT_NODE_HAS_PROP(I2C(idx), zephyr_concat_buf_size), \
(DT_PROP(I2C(idx), zephyr_concat_buf_size)), (0))
Expand Down Expand Up @@ -282,10 +287,11 @@
.ctx = &_i2c##idx##_twim_rtio, \
}; \
PM_DEVICE_DT_DEFINE(I2C(idx), twim_nrfx_pm_action, PM_DEVICE_ISR_SAFE); \
I2C_DEVICE_DT_DEFINE(I2C(idx), i2c_nrfx_twim_rtio_init, PM_DEVICE_DT_GET(I2C(idx)), \
&twim_##idx##z_data, &twim_##idx##z_config, POST_KERNEL, \
CONFIG_I2C_INIT_PRIORITY, &i2c_nrfx_twim_driver_api);
I2C_DEVICE_DT_DEINIT_DEFINE(I2C(idx), i2c_nrfx_twim_rtio_init, i2c_nrfx_twim_rtio_deinit, \
PM_DEVICE_DT_GET(I2C(idx)), &twim_##idx##z_data, \
&twim_##idx##z_config, POST_KERNEL, CONFIG_I2C_INIT_PRIORITY, \
&i2c_nrfx_twim_driver_api);

Check notice on line 294 in drivers/i2c/i2c_nrfx_twim_rtio.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

drivers/i2c/i2c_nrfx_twim_rtio.c:294 - IF_ENABLED(USES_MSG_BUF(idx), (MSG_BUF_DEFINE(idx);)) \ + IF_ENABLED(USES_MSG_BUF(idx), (MSG_BUF_DEFINE(idx);)) \ I2C_RTIO_DEFINE(_i2c##idx##_twim_rtio, \ DT_INST_PROP_OR(n, sq_size, CONFIG_I2C_RTIO_SQ_SIZE), \ DT_INST_PROP_OR(n, cq_size, CONFIG_I2C_RTIO_CQ_SIZE)); \ PINCTRL_DT_DEFINE(I2C(idx)); \ static struct i2c_nrfx_twim_rtio_data twim_##idx##z_data; \ static const struct i2c_nrfx_twim_rtio_config twim_##idx##z_config = { \ - .common = \ - { \ - .twim = NRFX_TWIM_INSTANCE(idx), \ - .twim_config = \ - { \ - .skip_gpio_cfg = true, \ - .skip_psel_cfg = true, \ - .frequency = I2C_FREQUENCY(idx), \ - }, \ - .event_handler = event_handler, \ - .msg_buf_size = MSG_BUF_SIZE(idx), \ - .irq_connect = irq_connect##idx, \ - .pcfg = PINCTRL_DT_DEV_CONFIG_GET(I2C(idx)), \ - IF_ENABLED(USES_MSG_BUF(idx), (.msg_buf = MSG_BUF_SYM(idx),)) \ - .max_transfer_size = MAX_TRANSFER_SIZE(idx), \ - }, \ - .ctx = &_i2c##idx##_twim_rtio, \ + .common = { \ + .twim = NRFX_TWIM_INSTANCE(idx), \ + .twim_config = \ + { \ + .skip_gpio_cfg = true, \ + .skip_psel_cfg = true, \ + .frequency = I2C_FREQUENCY(idx), \ + }, \ + .event_handler = event_handler, \ + .msg_buf_size = MSG_BUF_SIZE(idx), \ + .irq_connect = irq_connect##idx, \ + .pcfg = PINCTRL_DT_DEV_CONFIG_GET(I2C(idx)), \ + IF_ENABLED(USES_MSG_BUF(idx), (.msg_buf = MSG_BUF_SYM(idx),)) .max_transfer_size = \ + MAX_TRANSFER_SIZE(idx), \ + }, \ + .ctx = &_i2c##idx##_twim_rtio, \ }; \ PM_DEVICE_DT_DEFINE(I2C(idx), twim_nrfx_pm_action, PM_DEVICE_ISR_SAFE); \ I2C_DEVICE_DT_DEINIT_DEFINE(I2C(idx), i2c_nrfx_twim_rtio_init, i2c_nrfx_twim_rtio_deinit, \ - PM_DEVICE_DT_GET(I2C(idx)), &twim_##idx##z_data, \ - &twim_##idx##z_config, POST_KERNEL, CONFIG_I2C_INIT_PRIORITY, \ - &i2c_nrfx_twim_driver_api); + PM_DEVICE_DT_GET(I2C(idx)), &twim_##idx##z_data, \ + &twim_##idx##z_config, POST_KERNEL, CONFIG_I2C_INIT_PRIORITY, \ + &i2c_nrfx_twim_driver_api);
#ifdef CONFIG_HAS_HW_NRF_TWIM0
I2C_NRFX_TWIM_RTIO_DEVICE(0);
#endif
Expand Down
43 changes: 41 additions & 2 deletions drivers/i2c/i2c_nrfx_twis.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,15 @@
(void)pm_device_state_get(dev, &state);
return state == PM_DEVICE_STATE_ACTIVE;
}

static bool shim_nrf_twis_is_suspended(const struct device *dev)
{
enum pm_device_state state;

(void)pm_device_state_get(dev, &state);
return state == PM_DEVICE_STATE_SUSPENDED ||
state == PM_DEVICE_STATE_OFF;
}

Check notice on line 84 in drivers/i2c/i2c_nrfx_twis.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

drivers/i2c/i2c_nrfx_twis.c:84 - return state == PM_DEVICE_STATE_SUSPENDED || - state == PM_DEVICE_STATE_OFF; + return state == PM_DEVICE_STATE_SUSPENDED || state == PM_DEVICE_STATE_OFF;
#else
static bool shim_nrf_twis_is_resumed(const struct device *dev)
{
Expand Down Expand Up @@ -199,7 +208,7 @@

#if CONFIG_PM_DEVICE
case PM_DEVICE_ACTION_SUSPEND:
shim_nrf_twis_disable();
shim_nrf_twis_disable(dev);
break;
#endif

Expand Down Expand Up @@ -283,6 +292,35 @@
return pm_device_driver_init(dev, shim_nrf_twis_pm_action_cb);
}

static int shim_nrf_twis_deinit(const struct device *dev)
{
const struct shim_nrf_twis_config *dev_config = dev->config;
struct shim_nrf_twis_data *dev_data = dev->data;

if (dev_data->target_config != NULL) {
LOG_ERR("target registered");
return -EPERM;
}

#if CONFIG_PM_DEVICE
/*
* PM must have suspended the device before driver can
* be deinitialized
*/
if (!shim_nrf_twis_is_suspended(dev)) {
LOG_ERR("device active");
return -EBUSY;
}
#else
/* Suspend device */
shim_nrf_twis_disable(dev);
#endif

/* Uninit device hardware */
nrfx_twis_uninit(&dev_config->twis);
return 0;
}

#define SHIM_NRF_TWIS_NAME(id, name) \
_CONCAT_4(shim_nrf_twis_, name, _, id)

Expand Down Expand Up @@ -323,9 +361,10 @@
shim_nrf_twis_pm_action_cb, \
); \
\
DEVICE_DT_DEFINE( \
DEVICE_DT_DEINIT_DEFINE( \
SHIM_NRF_TWIS_NODE(id), \
shim_nrf_twis_init, \
shim_nrf_twis_deinit, \
PM_DEVICE_DT_GET(SHIM_NRF_TWIS_NODE(id)), \
&SHIM_NRF_TWIS_NAME(id, data), \
&SHIM_NRF_TWIS_NAME(id, config), \
Expand All @@ -333,7 +372,7 @@
CONFIG_I2C_INIT_PRIORITY, \
&shim_nrf_twis_api \
);

Check notice on line 375 in drivers/i2c/i2c_nrfx_twis.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

drivers/i2c/i2c_nrfx_twis.c:375 -#define SHIM_NRF_TWIS_DEVICE_DEFINE(id) \ - static void SHIM_NRF_TWIS_NAME(id, irq_connect)(void) \ - { \ - IRQ_CONNECT( \ - SHIM_NRF_TWIS_IRQN(id), \ - SHIM_NRF_TWIS_IRQ_PRIO(id), \ - nrfx_isr, \ - SHIM_NRF_TWIS_IRQ_HANDLER(id), \ - 0 \ - ); \ - } \ - \ - static void SHIM_NRF_TWIS_NAME(id, event_handler)(nrfx_twis_evt_t const *event) \ - { \ - shim_nrf_twis_event_handler(SHIM_NRF_TWIS_DEVICE_GET(id), event); \ - } \ - \ - static struct shim_nrf_twis_data SHIM_NRF_TWIS_NAME(id, data); \ - \ - PINCTRL_DT_DEFINE(SHIM_NRF_TWIS_NODE(id)); \ - \ - static uint8_t SHIM_NRF_TWIS_NAME(id, buf) \ - [SHIM_NRF_TWIS_BUF_SIZE] SHIM_NRF_TWIS_BUF_ATTR(id); \ - \ - static const struct shim_nrf_twis_config SHIM_NRF_TWIS_NAME(id, config) = { \ - .twis = NRFX_TWIS_INSTANCE(id), \ - .irq_connect = SHIM_NRF_TWIS_NAME(id, irq_connect), \ - .event_handler = SHIM_NRF_TWIS_NAME(id, event_handler), \ - .pcfg = PINCTRL_DT_DEV_CONFIG_GET(SHIM_NRF_TWIS_NODE(id)), \ - .buf = SHIM_NRF_TWIS_NAME(id, buf), \ - }; \ - \ - PM_DEVICE_DT_DEFINE( \ - SHIM_NRF_TWIS_NODE(id), \ - shim_nrf_twis_pm_action_cb, \ - ); \ - \ - DEVICE_DT_DEINIT_DEFINE( \ - SHIM_NRF_TWIS_NODE(id), \ - shim_nrf_twis_init, \ - shim_nrf_twis_deinit, \ - PM_DEVICE_DT_GET(SHIM_NRF_TWIS_NODE(id)), \ - &SHIM_NRF_TWIS_NAME(id, data), \ - &SHIM_NRF_TWIS_NAME(id, config), \ - POST_KERNEL, \ - CONFIG_I2C_INIT_PRIORITY, \ - &shim_nrf_twis_api \ - ); +#define SHIM_NRF_TWIS_DEVICE_DEFINE(id) \ + static void SHIM_NRF_TWIS_NAME(id, irq_connect)(void) \ + { \ + IRQ_CONNECT(SHIM_NRF_TWIS_IRQN(id), SHIM_NRF_TWIS_IRQ_PRIO(id), nrfx_isr, \ + SHIM_NRF_TWIS_IRQ_HANDLER(id), 0); \ + } \ + \ + static void SHIM_NRF_TWIS_NAME(id, event_handler)(nrfx_twis_evt_t const *event) \ + { \ + shim_nrf_twis_event_handler(SHIM_NRF_TWIS_DEVICE_GET(id), event); \ + } \ + \ + static struct shim_nrf_twis_data SHIM_NRF_TWIS_NAME(id, data); \ + \ + PINCTRL_DT_DEFINE(SHIM_NRF_TWIS_NODE(id)); \ + \ + static uint8_t SHIM_NRF_TWIS_NAME(id, \ + buf)[SHIM_NRF_TWIS_BUF_SIZE] SHIM_NRF_TWIS_BUF_ATTR(id); \ + \ + static const struct shim_nrf_twis_config SHIM_NRF_TWIS_NAME(id, config) = { \ + .twis = NRFX_TWIS_INSTANCE(id), \ + .irq_connect = SHIM_NRF_TWIS_NAME(id, irq_connect), \ + .event_handler = SHIM_NRF_TWIS_NAME(id, event_handler), \ + .pcfg = PINCTRL_DT_DEV_CONFIG_GET(SHIM_NRF_TWIS_NODE(id)), \ + .buf = SHIM_NRF_TWIS_NAME(id, buf),
#ifdef CONFIG_HAS_HW_NRF_TWIS0
SHIM_NRF_TWIS_DEVICE_DEFINE(0);
#endif
Expand Down
16 changes: 13 additions & 3 deletions drivers/pinctrl/pinctrl_nrf.c
Original file line number Diff line number Diff line change
Expand Up @@ -516,9 +516,13 @@ int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt,
}
gpd_requested = true;
}

nrf_gpio_pin_retain_disable(pin);
}

/*
* Pad power domain now on, retain no longer needed
* as pad config will be persists as pad is powered.
*/
nrf_gpio_pin_retain_disable(pin);
#endif /* CONFIG_SOC_NRF54H20_GPD */

if (write != NO_WRITE) {
Expand All @@ -537,7 +541,13 @@ int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt,
nrf_gpio_pin_clock_set(pin, NRF_GET_CLOCKPIN_ENABLE(pins[i]));
#endif
#ifdef CONFIG_SOC_NRF54H20_GPD
if (NRF_GET_GPD_FAST_ACTIVE1(pins[i]) == 1U) {
if (NRF_GET_LP(pins[i]) == NRF_LP_ENABLE) {
/*
* Pad power domain may be turned off, and pad is not
* actively used as pincnf is low-power. Enable retain
* to ensure pad output and config persists if pad
* power domain is suspended.
*/
nrf_gpio_pin_retain_enable(pin);
}
#endif /* CONFIG_SOC_NRF54H20_GPD */
Expand Down
25 changes: 24 additions & 1 deletion drivers/spi/spi_nrfx_spim.c
Original file line number Diff line number Diff line change
Expand Up @@ -765,6 +765,28 @@
#endif
return pm_device_driver_init(dev, spim_nrfx_pm_action);
}

static int spi_nrfx_deinit(const struct device *dev)
{
#if defined(CONFIG_PM_DEVICE)
enum pm_device_state state;

/*
* PM must have suspended the device before driver can
* be deinitialized
*/
(void)pm_device_state_get(dev, &state);
return state == PM_DEVICE_STATE_SUSPENDED ||
state == PM_DEVICE_STATE_OFF ?
0 : -EBUSY;
#else

Check notice on line 782 in drivers/spi/spi_nrfx_spim.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

drivers/spi/spi_nrfx_spim.c:782 - return state == PM_DEVICE_STATE_SUSPENDED || - state == PM_DEVICE_STATE_OFF ? - 0 : -EBUSY; + return state == PM_DEVICE_STATE_SUSPENDED || state == PM_DEVICE_STATE_OFF ? 0 : -EBUSY;
/* PM suspend implementation does everything we need */
spim_suspend(dev);
#endif

return 0;
}

/*
* We use NODELABEL here because the nrfx API requires us to call
* functions which are named according to SoC peripheral instance
Expand Down Expand Up @@ -870,14 +892,15 @@
!(DT_GPIO_FLAGS(SPIM(idx), wake_gpios) & GPIO_ACTIVE_LOW),\
"WAKE line must be configured as active high"); \
PM_DEVICE_DT_DEFINE(SPIM(idx), spim_nrfx_pm_action); \
SPI_DEVICE_DT_DEFINE(SPIM(idx), \
SPI_DEVICE_DT_DEINIT_DEFINE(SPIM(idx), \
spi_nrfx_init, \
spi_nrfx_deinit, \
PM_DEVICE_DT_GET(SPIM(idx)), \
&spi_##idx##_data, \
&spi_##idx##z_config, \
POST_KERNEL, SPIM_INIT_PRIORITY(idx), \
&spi_nrfx_driver_api)

Check notice on line 903 in drivers/spi/spi_nrfx_spim.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

drivers/spi/spi_nrfx_spim.c:903 -#define SPI_NRFX_SPIM_DEFINE(idx) \ - NRF_DT_CHECK_NODE_HAS_PINCTRL_SLEEP(SPIM(idx)); \ - static void irq_connect##idx(void) \ - { \ - IRQ_CONNECT(DT_IRQN(SPIM(idx)), DT_IRQ(SPIM(idx), priority), \ - nrfx_isr, nrfx_spim_##idx##_irq_handler, 0); \ - } \ +#define SPI_NRFX_SPIM_DEFINE(idx) \ + NRF_DT_CHECK_NODE_HAS_PINCTRL_SLEEP(SPIM(idx)); \ + static void irq_connect##idx(void) \ + { \ + IRQ_CONNECT(DT_IRQN(SPIM(idx)), DT_IRQ(SPIM(idx), priority), nrfx_isr, \ + nrfx_spim_##idx##_irq_handler, 0); \ + } \ IF_ENABLED(SPI_BUFFER_IN_RAM, \ (static uint8_t spim_##idx##_tx_buffer \ [CONFIG_SPI_NRFX_RAM_BUFFER_SIZE] \ SPIM_MEMORY_SECTION(idx); \ static uint8_t spim_##idx##_rx_buffer \ [CONFIG_SPI_NRFX_RAM_BUFFER_SIZE] \ - SPIM_MEMORY_SECTION(idx);)) \ - static struct spi_nrfx_data spi_##idx##_data = { \ + SPIM_MEMORY_SECTION(idx);)) \ + static struct spi_nrfx_data spi_##idx##_data = { \ IF_ENABLED(CONFIG_MULTITHREADING, \ - (SPI_CONTEXT_INIT_LOCK(spi_##idx##_data, ctx),)) \ - IF_ENABLED(CONFIG_MULTITHREADING, \ - (SPI_CONTEXT_INIT_SYNC(spi_##idx##_data, ctx),)) \ - SPI_CONTEXT_CS_GPIOS_INITIALIZE(SPIM(idx), ctx) \ - IF_ENABLED(SPI_BUFFER_IN_RAM, \ + (SPI_CONTEXT_INIT_LOCK(spi_##idx##_data, ctx),)) \ + IF_ENABLED(CONFIG_MULTITHREADING, \ + (SPI_CONTEXT_INIT_SYNC(spi_##idx##_data, ctx),)) SPI_CONTEXT_CS_GPIOS_INITIALIZE(SPIM(idx), \ + ctx) \ + IF_ENABLED(SPI_BUFFER_IN_RAM, \ (.tx_buffer = spim_##idx##_tx_buffer, \ - .rx_buffer = spim_##idx##_rx_buffer,)) \ - .dev = DEVICE_DT_GET(SPIM(idx)), \ - .busy = false, \ - }; \ - PINCTRL_DT_DEFINE(SPIM(idx)); \ - static const struct spi_nrfx_config spi_##idx##z_config = { \ - .spim = { \ - .p_reg = (NRF_SPIM_Type *)DT_REG_ADDR(SPIM(idx)), \ - .drv_inst_idx = NRFX_SPIM##idx##_INST_IDX, \ - }, \ - .max_freq = SPIM_PROP(idx, max_frequency), \ - .def_config = { \ - .skip_gpio_cfg = true, \ - .skip_psel_cfg = true, \ - .ss_pin = NRF_SPIM_PIN_NOT_CONNECTED, \ - .orc = SPIM_PROP(idx, overrun_character), \ - SPI_NRFX_SPIM_EXTENDED_CONFIG(idx) \ - }, \ - .irq_connect = irq_connect##idx, \ - .pcfg = PINCTRL_DT_DEV_CONFIG_GET(SPIM(idx)), \ - .max_chunk_len = BIT_MASK(SPIM_PROP(idx, easydma_maxcnt_bits)),\ + .rx_buffer = spim_##idx##_rx_buffer,)) .dev = \ + DEVICE_DT_GET(SPIM(idx)), \ + .busy = false, \ + }; \ + PINCTRL_DT_DEFINE(SPIM(idx)); \ + static const struct spi_nrfx_config spi_##idx##z_config = { \ + .spim = \ + {
#define SPIM_MEMORY_SECTION(idx) \
COND_CODE_1(SPIM_HAS_PROP(idx, memory_regions), \
(__attribute__((__section__(LINKER_DT_NODE_REGION_NAME( \
Expand Down
Loading
Loading