8
8
#include <zephyr/irq.h>
9
9
#include <zephyr/cache.h>
10
10
#include <zephyr/logging/log.h>
11
+ #include <zephyr/pm/device_runtime.h>
12
+ #include <zephyr/pm/device.h>
13
+ #include <zephyr/drivers/clock_control.h>
11
14
#include "fsl_sdma.h"
12
15
13
16
LOG_MODULE_REGISTER (nxp_sdma );
@@ -23,6 +26,8 @@ AT_NONCACHEABLE_SECTION_ALIGN(static sdma_context_data_t
23
26
struct sdma_dev_cfg {
24
27
SDMAARM_Type * base ;
25
28
void (* irq_config )(void );
29
+ const struct device * clk_dev ;
30
+ uint32_t bus_clk_id ;
26
31
};
27
32
28
33
struct sdma_channel_data {
@@ -422,9 +427,66 @@ static bool sdma_channel_filter(const struct device *dev, int chan_id, void *par
422
427
dev_data -> chan [chan_id ].event_source = * ((int * )param );
423
428
dev_data -> chan [chan_id ].index = chan_id ;
424
429
430
+ if (pm_device_runtime_get (dev ) < 0 ) {
431
+ LOG_ERR ("failed to runtime get" );
432
+ return false;
433
+ }
434
+
425
435
return true;
426
436
}
427
437
438
+ static void sdma_channel_release (const struct device * dev , uint32_t chan_id )
439
+ {
440
+ if (chan_id == 0 ) {
441
+ return ;
442
+ }
443
+
444
+ if (chan_id >= FSL_FEATURE_SDMA_MODULE_CHANNEL ) {
445
+ return ;
446
+ }
447
+
448
+ if (pm_device_runtime_put (dev ) < 0 ) {
449
+ LOG_ERR ("failed to runtime put" );
450
+ return ;
451
+ }
452
+ }
453
+
454
+ static int sdma_bus_clk_enable_disable (const struct device * dev , bool enable )
455
+ {
456
+ const struct sdma_dev_cfg * cfg = dev -> config ;
457
+
458
+ if (!cfg -> clk_dev ) {
459
+ return - ENODEV ;
460
+ }
461
+
462
+ if (enable ) {
463
+ return clock_control_on (cfg -> clk_dev ,
464
+ UINT_TO_POINTER (cfg -> bus_clk_id ));
465
+ } else {
466
+ return clock_control_off (cfg -> clk_dev ,
467
+ UINT_TO_POINTER (cfg -> bus_clk_id ));
468
+ }
469
+ }
470
+
471
+ __maybe_unused static int sdma_pm_action (const struct device * dev ,
472
+ enum pm_device_action action )
473
+ {
474
+ bool enable = true;
475
+
476
+ switch (action ) {
477
+ case PM_DEVICE_ACTION_RESUME :
478
+ break ;
479
+ case PM_DEVICE_ACTION_SUSPEND :
480
+ enable = false;
481
+ break ;
482
+ case PM_DEVICE_ACTION_TURN_ON :
483
+ case PM_DEVICE_ACTION_TURN_OFF :
484
+ return 0 ;
485
+ }
486
+
487
+ return sdma_bus_clk_enable_disable (dev , enable );
488
+ }
489
+
428
490
static DEVICE_API (dma , sdma_api ) = {
429
491
.reload = dma_nxp_sdma_reload ,
430
492
.config = dma_nxp_sdma_config ,
@@ -435,6 +497,7 @@ static DEVICE_API(dma, sdma_api) = {
435
497
.get_status = dma_nxp_sdma_get_status ,
436
498
.get_attribute = dma_nxp_sdma_get_attribute ,
437
499
.chan_filter = sdma_channel_filter ,
500
+ .chan_release = sdma_channel_release ,
438
501
};
439
502
440
503
static int dma_nxp_sdma_init (const struct device * dev )
@@ -450,12 +513,13 @@ static int dma_nxp_sdma_init(const struct device *dev)
450
513
SDMA_GetDefaultConfig (& defconfig );
451
514
defconfig .ratio = kSDMA_ARMClockFreq ;
452
515
516
+ /* this also ungates the bus clock */
453
517
SDMA_Init (cfg -> base , & defconfig );
454
518
455
519
/* configure interrupts */
456
520
cfg -> irq_config ();
457
521
458
- return 0 ;
522
+ return pm_device_runtime_enable ( dev ) ;
459
523
}
460
524
461
525
#define DMA_NXP_SDMA_INIT (inst ) \
@@ -468,6 +532,8 @@ static int dma_nxp_sdma_init(const struct device *dev)
468
532
static const struct sdma_dev_cfg sdma_cfg_##inst = { \
469
533
.base = (SDMAARM_Type *)DT_INST_REG_ADDR(inst), \
470
534
.irq_config = dma_nxp_sdma_##inst_irq_config, \
535
+ .clk_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(inst)), \
536
+ .bus_clk_id = DT_INST_CLOCKS_CELL(inst, name), \
471
537
}; \
472
538
static void dma_nxp_sdma_##inst_irq_config(void) \
473
539
{ \
@@ -476,7 +542,11 @@ static int dma_nxp_sdma_init(const struct device *dev)
476
542
dma_nxp_sdma_isr, DEVICE_DT_INST_GET(inst), 0); \
477
543
irq_enable(DT_INST_IRQN(inst)); \
478
544
} \
479
- DEVICE_DT_INST_DEFINE(inst, &dma_nxp_sdma_init, NULL, \
545
+ \
546
+ PM_DEVICE_DT_INST_DEFINE(inst, sdma_pm_action); \
547
+ \
548
+ DEVICE_DT_INST_DEFINE(inst, &dma_nxp_sdma_init, \
549
+ PM_DEVICE_DT_INST_GET(inst), \
480
550
&sdma_data_##inst, &sdma_cfg_##inst, \
481
551
PRE_KERNEL_1, CONFIG_DMA_INIT_PRIORITY, \
482
552
&sdma_api); \
0 commit comments