@@ -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+ }
375391int_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
389405ctx_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, \
0 commit comments