Skip to content

Commit 052ded1

Browse files
jpanisbljhedberg
authored andcommitted
drivers: spi: cc23x0: Add power management
Add PM support to cc23x0 SPI module. This implies listing states which cause power loss and enabling device runtime PM for the DMA in the DT. Signed-off-by: Julien Panis <[email protected]>
1 parent 3574533 commit 052ded1

File tree

2 files changed

+49
-6
lines changed

2 files changed

+49
-6
lines changed

drivers/spi/spi_cc23x0.c

Lines changed: 47 additions & 6 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>
@@ -307,6 +310,8 @@ static int spi_cc23x0_transceive(const struct device *dev,
307310
};
308311
#endif
309312

313+
pm_policy_device_power_lock_get(dev);
314+
310315
spi_context_lock(ctx, false, NULL, NULL, config);
311316

312317
ret = spi_cc23x0_configure(dev, config);
@@ -339,16 +344,22 @@ static int spi_cc23x0_transceive(const struct device *dev,
339344
block_cfg_rx.dest_addr_adj = DMA_ADDR_ADJ_INCREMENT;
340345
block_cfg_rx.block_size = SPI_CC23_DFS * data->tx_len_left;
341346

342-
ret = dma_config(cfg->dma_dev, cfg->dma_channel_tx, &dma_cfg_tx);
347+
ret = pm_device_runtime_get(cfg->dma_dev);
343348
if (ret) {
344-
LOG_ERR("Failed to configure DMA TX channel");
349+
LOG_ERR("Failed to resume DMA (%d)", ret);
345350
goto int_disable;
346351
}
347352

353+
ret = dma_config(cfg->dma_dev, cfg->dma_channel_tx, &dma_cfg_tx);
354+
if (ret) {
355+
LOG_ERR("Failed to configure DMA TX channel (%d)", ret);
356+
goto dma_suspend;
357+
}
358+
348359
ret = dma_config(cfg->dma_dev, cfg->dma_channel_rx, &dma_cfg_rx);
349360
if (ret) {
350-
LOG_ERR("Failed to configure DMA RX channel");
351-
goto int_disable;
361+
LOG_ERR("Failed to configure DMA RX channel (%d)", ret);
362+
goto dma_suspend;
352363
}
353364

354365
/* Disable DMA triggers */
@@ -364,14 +375,19 @@ static int spi_cc23x0_transceive(const struct device *dev,
364375
ret = spi_context_wait_for_completion(&data->ctx);
365376
if (ret) {
366377
LOG_ERR("SPI transfer failed (%d)", ret);
367-
goto int_disable;
378+
goto dma_suspend;
368379
}
369380

370381
spi_context_update_tx(ctx, SPI_CC23_DFS, data->tx_len_left);
371382
spi_context_update_rx(ctx, SPI_CC23_DFS, data->tx_len_left);
372383

373384
LOG_DBG("SPI transfer completed");
374385

386+
dma_suspend:
387+
ret = pm_device_runtime_put(cfg->dma_dev);
388+
if (ret) {
389+
LOG_ERR("Failed to suspend DMA (%d)", ret);
390+
}
375391
int_disable:
376392
SPIDisableInt(cfg->base, SPI_CC23_INT_MASK);
377393
#else
@@ -388,6 +404,7 @@ static int spi_cc23x0_transceive(const struct device *dev,
388404

389405
ctx_release:
390406
spi_context_release(ctx, ret);
407+
pm_policy_device_power_lock_put(dev);
391408
return ret;
392409
}
393410

@@ -446,6 +463,29 @@ static int spi_cc23x0_init(const struct device *dev)
446463
return 0;
447464
}
448465

466+
#ifdef CONFIG_PM_DEVICE
467+
468+
static int spi_cc23x0_pm_action(const struct device *dev, enum pm_device_action action)
469+
{
470+
const struct spi_cc23x0_config *cfg = dev->config;
471+
struct spi_cc23x0_data *data = dev->data;
472+
473+
switch (action) {
474+
case PM_DEVICE_ACTION_SUSPEND:
475+
SPIDisable(cfg->base);
476+
CLKCTLDisable(CLKCTL_BASE, CLKCTL_SPI0);
477+
return 0;
478+
case PM_DEVICE_ACTION_RESUME:
479+
/* Force SPI to be reconfigured at next transfer */
480+
data->ctx.config = NULL;
481+
return 0;
482+
default:
483+
return -ENOTSUP;
484+
}
485+
}
486+
487+
#endif /* CONFIG_PM_DEVICE */
488+
449489
#ifdef CONFIG_SPI_CC23X0_DMA_DRIVEN
450490
#define SPI_CC23X0_DMA_INIT(n) \
451491
.dma_dev = DEVICE_DT_GET(TI_CC23X0_DT_INST_DMA_CTLR(n, tx)), \
@@ -459,6 +499,7 @@ static int spi_cc23x0_init(const struct device *dev)
459499

460500
#define SPI_CC23X0_INIT(n) \
461501
PINCTRL_DT_INST_DEFINE(n); \
502+
PM_DEVICE_DT_INST_DEFINE(n, spi_cc23x0_pm_action); \
462503
\
463504
static void spi_irq_config_func_##n(void) \
464505
{ \
@@ -484,7 +525,7 @@ static int spi_cc23x0_init(const struct device *dev)
484525
\
485526
DEVICE_DT_INST_DEFINE(n, \
486527
spi_cc23x0_init, \
487-
NULL, \
528+
PM_DEVICE_DT_INST_GET(n), \
488529
&spi_cc23x0_data_##n, \
489530
&spi_cc23x0_config_##n, \
490531
POST_KERNEL, \

dts/arm/ti/cc23x0.dtsi

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@
121121
reg = <0x40026000 0x524>;
122122
interrupts = <8 0>;
123123
#dma-cells = <2>;
124+
zephyr,pm-device-runtime-auto;
124125
status = "disabled";
125126
};
126127

@@ -132,6 +133,7 @@
132133
interrupts = <10 0>;
133134
dmas = <&dma 0 0>, <&dma 1 1>;
134135
dma-names = "tx", "rx";
136+
zephyr,disabling-power-states = <&state0 &state1>;
135137
status = "disabled";
136138
};
137139

0 commit comments

Comments
 (0)