Skip to content

Commit 47f7824

Browse files
[nrf fromlist] drivers: spi: nrfx_spis: impl pm device runtime
Implement PM device runtime in nrx spis device driver. Upstream PR #: 86709 Signed-off-by: Bjarki Arge Andreasen <[email protected]>
1 parent 6dc8dcd commit 47f7824

File tree

1 file changed

+63
-12
lines changed

1 file changed

+63
-12
lines changed

drivers/spi/spi_nrfx_spis.c

Lines changed: 63 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
#include <zephyr/drivers/gpio.h>
1111
#include <soc.h>
1212
#include <nrfx_spis.h>
13+
#include <zephyr/pm/device.h>
14+
#include <zephyr/pm/device_runtime.h>
1315

1416
#include <zephyr/logging/log.h>
1517
#include <zephyr/irq.h>
@@ -175,6 +177,10 @@ static int transceive(const struct device *dev,
175177
const struct spi_buf *rx_buf = rx_bufs ? rx_bufs->buffers : NULL;
176178
int error;
177179

180+
#if defined(CONFIG_PM_DEVICE_RUNTIME)
181+
pm_device_runtime_get(dev);
182+
#endif
183+
178184
spi_context_lock(&dev_data->ctx, asynchronous, cb, userdata, spi_cfg);
179185

180186
error = configure(dev, spi_cfg);
@@ -282,9 +288,53 @@ static void event_handler(const nrfx_spis_evt_t *p_event, void *p_context)
282288
if (p_event->evt_type == NRFX_SPIS_XFER_DONE) {
283289
spi_context_complete(&dev_data->ctx, dev_data->dev,
284290
p_event->rx_amount);
291+
292+
#if defined(CONFIG_PM_DEVICE_RUNTIME)
293+
pm_device_runtime_put(dev_data->dev);
294+
#endif
295+
}
296+
}
297+
298+
static void spi_nrfx_suspend(const struct device *dev)
299+
{
300+
const struct spi_nrfx_config *dev_config = dev->config;
301+
302+
if (dev_config->wake_gpio.port == NULL) {
303+
nrf_spis_disable(dev_config->spis.p_reg);
304+
}
305+
306+
(void)pinctrl_apply_state(dev_config->pcfg, PINCTRL_STATE_SLEEP);
307+
}
308+
309+
static void spi_nrfx_resume(const struct device *dev)
310+
{
311+
const struct spi_nrfx_config *dev_config = dev->config;
312+
313+
(void)pinctrl_apply_state(dev_config->pcfg, PINCTRL_STATE_DEFAULT);
314+
315+
if (dev_config->wake_gpio.port == NULL) {
316+
nrf_spis_enable(dev_config->spis.p_reg);
285317
}
286318
}
287319

320+
static int spi_nrfx_pm_action(const struct device *dev, enum pm_device_action action)
321+
{
322+
switch (action) {
323+
case PM_DEVICE_ACTION_SUSPEND:
324+
spi_nrfx_suspend(dev);
325+
return 0;
326+
327+
case PM_DEVICE_ACTION_RESUME:
328+
spi_nrfx_resume(dev);
329+
return 0;
330+
331+
default:
332+
break;
333+
}
334+
335+
return -ENOTSUP;
336+
}
337+
288338
static int spi_nrfx_init(const struct device *dev)
289339
{
290340
const struct spi_nrfx_config *dev_config = dev->config;
@@ -308,6 +358,16 @@ static int spi_nrfx_init(const struct device *dev)
308358
return -EBUSY;
309359
}
310360

361+
/* When the WAKE line is used, the SPIS peripheral is enabled
362+
* only after the master signals that it wants to perform a
363+
* transfer and it is disabled right after the transfer is done.
364+
* Waiting for the WAKE line to go high, what can be done using
365+
* the GPIO PORT event, instead of just waiting for the transfer
366+
* with the SPIS peripheral enabled, significantly reduces idle
367+
* power consumption.
368+
*/
369+
nrf_spis_disable(dev_config->spis.p_reg);
370+
311371
if (dev_config->wake_gpio.port) {
312372
if (!gpio_is_ready_dt(&dev_config->wake_gpio)) {
313373
return -ENODEV;
@@ -332,21 +392,11 @@ static int spi_nrfx_init(const struct device *dev)
332392
if (err < 0) {
333393
return err;
334394
}
335-
336-
/* When the WAKE line is used, the SPIS peripheral is enabled
337-
* only after the master signals that it wants to perform a
338-
* transfer and it is disabled right after the transfer is done.
339-
* Waiting for the WAKE line to go high, what can be done using
340-
* the GPIO PORT event, instead of just waiting for the transfer
341-
* with the SPIS peripheral enabled, significantly reduces idle
342-
* power consumption.
343-
*/
344-
nrf_spis_disable(dev_config->spis.p_reg);
345395
}
346396

347397
spi_context_unlock_unconditionally(&dev_data->ctx);
348398

349-
return 0;
399+
return pm_device_driver_init(dev, spi_nrfx_pm_action);
350400
}
351401

352402
/*
@@ -394,9 +444,10 @@ static int spi_nrfx_init(const struct device *dev)
394444
BUILD_ASSERT(!DT_NODE_HAS_PROP(SPIS(idx), wake_gpios) || \
395445
!(DT_GPIO_FLAGS(SPIS(idx), wake_gpios) & GPIO_ACTIVE_LOW),\
396446
"WAKE line must be configured as active high"); \
447+
PM_DEVICE_DT_DEFINE(SPIS(idx), spi_nrfx_pm_action, 1); \
397448
SPI_DEVICE_DT_DEFINE(SPIS(idx), \
398449
spi_nrfx_init, \
399-
NULL, \
450+
PM_DEVICE_DT_GET(SPIS(idx)), \
400451
&spi_##idx##_data, \
401452
&spi_##idx##z_config, \
402453
POST_KERNEL, \

0 commit comments

Comments
 (0)