@@ -14,6 +14,9 @@ LOG_MODULE_REGISTER(spi_cc23x0, CONFIG_SPI_LOG_LEVEL);
14
14
#include <zephyr/drivers/pinctrl.h>
15
15
#include <zephyr/drivers/spi.h>
16
16
#include <zephyr/irq.h>
17
+ #include <zephyr/pm/device.h>
18
+ #include <zephyr/pm/device_runtime.h>
19
+ #include <zephyr/pm/policy.h>
17
20
#include <zephyr/sys/util.h>
18
21
19
22
#include <driverlib/clkctl.h>
@@ -63,13 +66,31 @@ struct spi_cc23x0_data {
63
66
#endif
64
67
};
65
68
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
+
66
85
static void spi_cc23x0_isr (const struct device * dev )
67
86
{
68
87
const struct spi_cc23x0_config * cfg = dev -> config ;
69
88
struct spi_cc23x0_data * data = dev -> data ;
70
89
struct spi_context * ctx = & data -> ctx ;
71
90
uint32_t status ;
72
- #ifndef CONFIG_SPI_CC23X0_DMA_DRIVEN
91
+ #ifdef CONFIG_SPI_CC23X0_DMA_DRIVEN
92
+ int ret ;
93
+ #else
73
94
uint32_t txd = 0 , rxd ;
74
95
#endif
75
96
@@ -79,6 +100,13 @@ static void spi_cc23x0_isr(const struct device *dev)
79
100
#ifdef CONFIG_SPI_CC23X0_DMA_DRIVEN
80
101
if (status & SPI_DMA_DONE_RX ) {
81
102
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
+
82
110
spi_context_complete (ctx , dev , 0 );
83
111
}
84
112
#else
@@ -307,6 +335,8 @@ static int spi_cc23x0_transceive(const struct device *dev,
307
335
};
308
336
#endif
309
337
338
+ spi_cc23x0_pm_policy_state_lock_get ();
339
+
310
340
spi_context_lock (ctx , false, NULL , NULL , config );
311
341
312
342
ret = spi_cc23x0_configure (dev , config );
@@ -339,6 +369,12 @@ static int spi_cc23x0_transceive(const struct device *dev,
339
369
block_cfg_rx .dest_addr_adj = DMA_ADDR_ADJ_INCREMENT ;
340
370
block_cfg_rx .block_size = SPI_CC23_DFS * data -> tx_len_left ;
341
371
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
+
342
378
ret = dma_config (cfg -> dma_dev , cfg -> dma_channel_tx , & dma_cfg_tx );
343
379
if (ret ) {
344
380
LOG_ERR ("Failed to configure DMA TX channel" );
@@ -388,6 +424,7 @@ static int spi_cc23x0_transceive(const struct device *dev,
388
424
389
425
ctx_release :
390
426
spi_context_release (ctx , ret );
427
+ spi_cc23x0_pm_policy_state_lock_put ();
391
428
return ret ;
392
429
}
393
430
@@ -434,6 +471,12 @@ static int spi_cc23x0_init(const struct device *dev)
434
471
LOG_ERR ("DMA not ready" );
435
472
return - ENODEV ;
436
473
}
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
+ }
437
480
#endif
438
481
439
482
ret = spi_context_cs_configure_all (& data -> ctx );
@@ -446,6 +489,29 @@ static int spi_cc23x0_init(const struct device *dev)
446
489
return 0 ;
447
490
}
448
491
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
+
449
515
#ifdef CONFIG_SPI_CC23X0_DMA_DRIVEN
450
516
#define SPI_CC23X0_DMA_INIT (n ) \
451
517
.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)
459
525
460
526
#define SPI_CC23X0_INIT (n ) \
461
527
PINCTRL_DT_INST_DEFINE(n); \
528
+ PM_DEVICE_DT_INST_DEFINE(n, spi_cc23x0_pm_action); \
462
529
\
463
530
static void spi_irq_config_func_##n(void) \
464
531
{ \
@@ -484,7 +551,7 @@ static int spi_cc23x0_init(const struct device *dev)
484
551
\
485
552
DEVICE_DT_INST_DEFINE(n, \
486
553
spi_cc23x0_init, \
487
- NULL, \
554
+ PM_DEVICE_DT_INST_GET(n), \
488
555
&spi_cc23x0_data_##n, \
489
556
&spi_cc23x0_config_##n, \
490
557
POST_KERNEL, \
0 commit comments