Skip to content

Commit b215104

Browse files
committed
drivers: spi: cc23x0: Add power management
Add PM support to cc23x0 SPI module. Signed-off-by: Julien Panis <jpanis@baylibre.com>
1 parent ba905d0 commit b215104

File tree

1 file changed

+69
-2
lines changed

1 file changed

+69
-2
lines changed

drivers/spi/spi_cc23x0.c

Lines changed: 69 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ LOG_MODULE_REGISTER(spi_cc23x0, CONFIG_SPI_LOG_LEVEL);
1414
#include <zephyr/drivers/pinctrl.h>
1515
#include <zephyr/drivers/spi.h>
1616
#include <zephyr/irq.h>
17+
#include <zephyr/pm/device.h>
18+
#include <zephyr/pm/device_runtime.h>
19+
#include <zephyr/pm/policy.h>
1720
#include <zephyr/sys/util.h>
1821

1922
#include <driverlib/clkctl.h>
@@ -63,13 +66,31 @@ struct spi_cc23x0_data {
6366
#endif
6467
};
6568

69+
static inline void spi_cc23x0_pm_policy_state_lock_get(void)
70+
{
71+
#ifdef CONFIG_PM_DEVICE
72+
pm_policy_state_lock_get(PM_STATE_RUNTIME_IDLE, PM_ALL_SUBSTATES);
73+
pm_policy_state_lock_get(PM_STATE_STANDBY, PM_ALL_SUBSTATES);
74+
#endif
75+
}
76+
77+
static inline void spi_cc23x0_pm_policy_state_lock_put(void)
78+
{
79+
#ifdef CONFIG_PM_DEVICE
80+
pm_policy_state_lock_put(PM_STATE_STANDBY, PM_ALL_SUBSTATES);
81+
pm_policy_state_lock_put(PM_STATE_RUNTIME_IDLE, PM_ALL_SUBSTATES);
82+
#endif
83+
}
84+
6685
static void spi_cc23x0_isr(const struct device *dev)
6786
{
6887
const struct spi_cc23x0_config *cfg = dev->config;
6988
struct spi_cc23x0_data *data = dev->data;
7089
struct spi_context *ctx = &data->ctx;
7190
uint32_t status;
72-
#ifndef CONFIG_SPI_CC23X0_DMA_DRIVEN
91+
#ifdef CONFIG_SPI_CC23X0_DMA_DRIVEN
92+
int ret;
93+
#else
7394
uint32_t txd = 0, rxd;
7495
#endif
7596

@@ -79,6 +100,13 @@ static void spi_cc23x0_isr(const struct device *dev)
79100
#ifdef CONFIG_SPI_CC23X0_DMA_DRIVEN
80101
if (status & SPI_DMA_DONE_RX) {
81102
SPIClearInt(cfg->base, SPI_DMA_DONE_RX);
103+
104+
ret = pm_device_runtime_put(cfg->dma_dev);
105+
if (ret) {
106+
LOG_ERR("Failed to suspend DMA (%d)", ret);
107+
return;
108+
}
109+
82110
spi_context_complete(ctx, dev, 0);
83111
}
84112
#else
@@ -307,6 +335,8 @@ static int spi_cc23x0_transceive(const struct device *dev,
307335
};
308336
#endif
309337

338+
spi_cc23x0_pm_policy_state_lock_get();
339+
310340
spi_context_lock(ctx, false, NULL, NULL, config);
311341

312342
ret = spi_cc23x0_configure(dev, config);
@@ -339,6 +369,12 @@ static int spi_cc23x0_transceive(const struct device *dev,
339369
block_cfg_rx.dest_addr_adj = DMA_ADDR_ADJ_INCREMENT;
340370
block_cfg_rx.block_size = SPI_CC23_DFS * data->tx_len_left;
341371

372+
ret = pm_device_runtime_get(cfg->dma_dev);
373+
if (ret) {
374+
LOG_ERR("Failed to resume DMA");
375+
goto int_disable;
376+
}
377+
342378
ret = dma_config(cfg->dma_dev, cfg->dma_channel_tx, &dma_cfg_tx);
343379
if (ret) {
344380
LOG_ERR("Failed to configure DMA TX channel");
@@ -388,6 +424,7 @@ static int spi_cc23x0_transceive(const struct device *dev,
388424

389425
ctx_release:
390426
spi_context_release(ctx, ret);
427+
spi_cc23x0_pm_policy_state_lock_put();
391428
return ret;
392429
}
393430

@@ -434,6 +471,12 @@ static int spi_cc23x0_init(const struct device *dev)
434471
LOG_ERR("DMA not ready");
435472
return -ENODEV;
436473
}
474+
475+
ret = pm_device_runtime_enable(cfg->dma_dev);
476+
if (ret) {
477+
LOG_ERR("Failed to enable DMA runtime PM");
478+
return ret;
479+
}
437480
#endif
438481

439482
ret = spi_context_cs_configure_all(&data->ctx);
@@ -446,6 +489,29 @@ static int spi_cc23x0_init(const struct device *dev)
446489
return 0;
447490
}
448491

492+
#ifdef CONFIG_PM_DEVICE
493+
494+
static int spi_cc23x0_pm_action(const struct device *dev, enum pm_device_action action)
495+
{
496+
const struct spi_cc23x0_config *cfg = dev->config;
497+
struct spi_cc23x0_data *data = dev->data;
498+
499+
switch (action) {
500+
case PM_DEVICE_ACTION_SUSPEND:
501+
SPIDisable(cfg->base);
502+
CLKCTLDisable(CLKCTL_BASE, CLKCTL_SPI0);
503+
return 0;
504+
case PM_DEVICE_ACTION_RESUME:
505+
/* Force SPI to be reconfigured at next transfer */
506+
data->ctx.config = NULL;
507+
return 0;
508+
default:
509+
return -ENOTSUP;
510+
}
511+
}
512+
513+
#endif /* CONFIG_PM_DEVICE */
514+
449515
#ifdef CONFIG_SPI_CC23X0_DMA_DRIVEN
450516
#define SPI_CC23X0_DMA_INIT(n) \
451517
.dma_dev = DEVICE_DT_GET(TI_CC23X0_DT_INST_DMA_CTLR(n, tx)), \
@@ -459,6 +525,7 @@ static int spi_cc23x0_init(const struct device *dev)
459525

460526
#define SPI_CC23X0_INIT(n) \
461527
PINCTRL_DT_INST_DEFINE(n); \
528+
PM_DEVICE_DT_INST_DEFINE(n, spi_cc23x0_pm_action); \
462529
\
463530
static void spi_irq_config_func_##n(void) \
464531
{ \
@@ -484,7 +551,7 @@ static int spi_cc23x0_init(const struct device *dev)
484551
\
485552
DEVICE_DT_INST_DEFINE(n, \
486553
spi_cc23x0_init, \
487-
NULL, \
554+
PM_DEVICE_DT_INST_GET(n), \
488555
&spi_cc23x0_data_##n, \
489556
&spi_cc23x0_config_##n, \
490557
POST_KERNEL, \

0 commit comments

Comments
 (0)