Skip to content

Commit a5cf757

Browse files
Dat-NguyenDuydleach02
authored andcommitted
drivers: dma_mcux_edma: improve interrupt handling
The current implementation iterates over all channels even if only several channels share the same irq. This introduces one more dt property to describe an offset between two channels share the same interrupt id. Beside that, the error interrupt must be put as last element of "interrupt" dt property. Signed-off-by: Dat Nguyen Duy <[email protected]>
1 parent 03b5ba5 commit a5cf757

File tree

4 files changed

+61
-54
lines changed

4 files changed

+61
-54
lines changed

drivers/dma/dma_mcux_edma.c

Lines changed: 51 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -137,23 +137,15 @@ static void nxp_edma_callback(edma_handle_t *handle, void *param, bool transferD
137137
data->dma_callback(data->dev, data->user_data, channel, ret);
138138
}
139139

140-
141-
static void dma_mcux_edma_irq_handler(const struct device *dev)
140+
static void dma_mcux_edma_irq_handler(const struct device *dev, uint32_t channel)
142141
{
143-
int i = 0;
144-
145-
LOG_DBG("IRQ CALLED");
146-
for (i = 0; i < DT_INST_PROP(0, dma_channels); i++) {
147-
uint32_t flag = EDMA_GetChannelStatusFlags(DEV_BASE(dev), i);
142+
uint32_t flag = EDMA_GetChannelStatusFlags(DEV_BASE(dev), channel);
148143

149-
if ((flag & (uint32_t)kEDMA_InterruptFlag) != 0U) {
150-
LOG_DBG("IRQ OCCURRED");
151-
EDMA_HandleIRQ(DEV_EDMA_HANDLE(dev, i));
152-
LOG_DBG("IRQ DONE");
153-
#if defined __CORTEX_M && (__CORTEX_M == 4U)
154-
barrier_dsync_fence_full();
155-
#endif
156-
}
144+
if (flag & kEDMA_InterruptFlag) {
145+
LOG_DBG("IRQ OCCURRED");
146+
/* EDMA interrupt flag is cleared here */
147+
EDMA_HandleIRQ(DEV_EDMA_HANDLE(dev, channel));
148+
LOG_DBG("IRQ DONE");
157149
}
158150
}
159151

@@ -162,18 +154,17 @@ static void dma_mcux_edma_error_irq_handler(const struct device *dev)
162154
int i = 0;
163155
uint32_t flag = 0;
164156

165-
for (i = 0; i < DT_INST_PROP(0, dma_channels); i++) {
157+
for (i = 0; i < DEV_CFG(dev)->dma_channels; i++) {
166158
if (DEV_CHANNEL_DATA(dev, i)->busy) {
167159
flag = EDMA_GetChannelStatusFlags(DEV_BASE(dev), i);
168-
LOG_INF("channel %d error status is 0x%x", i, flag);
169-
EDMA_ClearChannelStatusFlags(DEV_BASE(dev), i,
170-
0xFFFFFFFF);
160+
EDMA_ClearChannelStatusFlags(DEV_BASE(dev), i, 0xFFFFFFFF);
171161
EDMA_AbortTransfer(DEV_EDMA_HANDLE(dev, i));
172162
DEV_CHANNEL_DATA(dev, i)->busy = false;
163+
LOG_INF("channel %d error status is 0x%x", i, flag);
173164
}
174165
}
175166

176-
#if defined __CORTEX_M && (__CORTEX_M == 4U)
167+
#if defined(CONFIG_CPU_CORTEX_M4)
177168
barrier_dsync_fence_full();
178169
#endif
179170
}
@@ -525,40 +516,46 @@ static int dma_mcux_edma_init(const struct device *dev)
525516
return 0;
526517
}
527518

528-
#define IRQ_CONFIG(n, idx, fn) \
529-
IF_ENABLED(DT_INST_IRQ_HAS_IDX(n, idx), ( \
530-
IRQ_CONNECT(DT_INST_IRQ_BY_IDX(n, idx, irq), \
531-
DT_INST_IRQ_BY_IDX(n, idx, priority), \
532-
fn, \
533-
DEVICE_DT_INST_GET(n), 0); \
534-
irq_enable(DT_INST_IRQ_BY_IDX(n, idx, irq)); \
535-
))
536-
537-
#define DMA_MCUX_EDMA_CONFIG_FUNC(n) \
538-
static void dma_imx_config_func_##n(const struct device *dev) \
539-
{ \
540-
ARG_UNUSED(dev); \
541-
\
542-
IRQ_CONFIG(n, 0, dma_mcux_edma_irq_handler); \
543-
IRQ_CONFIG(n, 1, dma_mcux_edma_irq_handler); \
544-
IRQ_CONFIG(n, 2, dma_mcux_edma_irq_handler); \
545-
IRQ_CONFIG(n, 3, dma_mcux_edma_irq_handler); \
546-
IRQ_CONFIG(n, 4, dma_mcux_edma_irq_handler); \
547-
IRQ_CONFIG(n, 5, dma_mcux_edma_irq_handler); \
548-
IRQ_CONFIG(n, 6, dma_mcux_edma_irq_handler); \
549-
IRQ_CONFIG(n, 7, dma_mcux_edma_irq_handler); \
550-
IRQ_CONFIG(n, 8, dma_mcux_edma_irq_handler); \
551-
IRQ_CONFIG(n, 9, dma_mcux_edma_irq_handler); \
552-
IRQ_CONFIG(n, 10, dma_mcux_edma_irq_handler); \
553-
IRQ_CONFIG(n, 11, dma_mcux_edma_irq_handler); \
554-
IRQ_CONFIG(n, 12, dma_mcux_edma_irq_handler); \
555-
IRQ_CONFIG(n, 13, dma_mcux_edma_irq_handler); \
556-
IRQ_CONFIG(n, 14, dma_mcux_edma_irq_handler); \
557-
IRQ_CONFIG(n, 15, dma_mcux_edma_irq_handler); \
558-
\
559-
IRQ_CONFIG(n, 16, dma_mcux_edma_error_irq_handler); \
560-
\
561-
LOG_DBG("install irq done"); \
519+
/* The shared error interrupt (if have) must be declared as the last element in devicetree */
520+
#define NUM_IRQS_WITHOUT_ERROR_IRQ(n) UTIL_DEC(DT_NUM_IRQS(DT_DRV_INST(n)))
521+
522+
#define IRQ_CONFIG(n, idx, fn) \
523+
{ \
524+
IRQ_CONNECT(DT_INST_IRQ_BY_IDX(n, idx, irq), \
525+
DT_INST_IRQ_BY_IDX(n, idx, priority), \
526+
fn, \
527+
DEVICE_DT_INST_GET(n), 0); \
528+
irq_enable(DT_INST_IRQ_BY_IDX(n, idx, irq)); \
529+
}
530+
531+
#define DMA_MCUX_EDMA_IRQ_DEFINE(idx, n) \
532+
static void dma_mcux_edma_##n##_irq_##idx(const struct device *dev) \
533+
{ \
534+
dma_mcux_edma_irq_handler(dev, idx); \
535+
\
536+
IF_ENABLED(UTIL_BOOL(DT_INST_PROP(n, irq_shared_offset)), \
537+
(dma_mcux_edma_irq_handler(dev, \
538+
idx + DT_INST_PROP(n, irq_shared_offset));)) \
539+
\
540+
IF_ENABLED(CONFIG_CPU_CORTEX_M4, (barrier_dsync_fence_full();)) \
541+
}
542+
543+
#define DMA_MCUX_EDMA_IRQ_CONFIG(idx, n) \
544+
IRQ_CONFIG(n, idx, dma_mcux_edma_##n##_irq_##idx)
545+
546+
#define DMA_MCUX_EDMA_CONFIG_FUNC(n) \
547+
LISTIFY(NUM_IRQS_WITHOUT_ERROR_IRQ(n), DMA_MCUX_EDMA_IRQ_DEFINE, (), n) \
548+
static void dma_imx_config_func_##n(const struct device *dev) \
549+
{ \
550+
ARG_UNUSED(dev); \
551+
\
552+
LISTIFY(NUM_IRQS_WITHOUT_ERROR_IRQ(n), \
553+
DMA_MCUX_EDMA_IRQ_CONFIG, (;), n) \
554+
\
555+
IRQ_CONFIG(n, NUM_IRQS_WITHOUT_ERROR_IRQ(n), \
556+
dma_mcux_edma_error_irq_handler); \
557+
\
558+
LOG_DBG("install irq done"); \
562559
}
563560

564561
#define DMA_MCUX_EDMA_MUX(idx, n) \

dts/arm/nxp/nxp_rt10xx.dtsi

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -856,6 +856,7 @@
856856
<8 0>, <9 0>, <10 0>, <11 0>,
857857
<12 0>, <13 0>, <14 0>, <15 0>,
858858
<16 0>;
859+
irq-shared-offset = <16>;
859860
clocks = <&ccm IMX_CCM_EDMA_CLK 0x7C 0x000000C0>;
860861
status = "disabled";
861862
};

dts/arm/nxp/nxp_rt11xx.dtsi

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -953,6 +953,7 @@
953953
<8 0>, <9 0>, <10 0>, <11 0>,
954954
<12 0>, <13 0>, <14 0>, <15 0>,
955955
<16 0>;
956+
irq-shared-offset = <16>;
956957
};
957958

958959
edma_lpsr0: dma-controller@40c14000 {
@@ -971,6 +972,7 @@
971972
<8 0>, <9 0>, <10 0>, <11 0>,
972973
<12 0>, <13 0>, <14 0>, <15 0>,
973974
<16 0>;
975+
irq-shared-offset = <16>;
974976
};
975977

976978
pxp: pxp@40814000 {

dts/bindings/dma/nxp,mcux-edma.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,13 @@ properties:
3131
type: boolean
3232
description: If the DMA controller supports always on
3333

34+
irq-shared-offset:
35+
type: int
36+
default: 0
37+
description: |
38+
Describes an offset between two channels share the same interrupt entry.
39+
Default value means each channel has separate interrupt entry.
40+
3441
"#dma-cells":
3542
type: int
3643
required: true

0 commit comments

Comments
 (0)