Skip to contentSkip to conversation

dmaengine: dw-edma: Enable HDMA 64R/W Channels

PATCH RESEND Superseded Devendra K Verma 4 participants 5 messages Jun 23 – Jun 26

Subsystems (2)

v4 of 7 Superseded Latest is v7 →

lore
Share & tools
lore
#0 lore raw

PATCH RESEND v4 1/1 dmaengine: dw-edma: Enable HDMA 64R/W Channels

As per 'Designware Cores PCI Express Controller Databook', Section 7.1 - Overview, HDMA supports 64 Read and 64 Write channels. Current controller driver supports up to 8 read and write channels only. In order to utilize all the channels the controller driver need to have the channel related structs and variables as per the number of channels supported by IP. Following changes are made to enable 64 Read / 64 Write channel support:

o Defined HDMA specific macros to reflect the channel count.
o The count of ll_regions and dt_regions in dw_edma_chip and dw_edma_pcie_data shall be in accordance to number of read and write channels.
o In dw_edma_probe() configure the channels as per the channels of the IP used.
o Changed mask types to u64 for higher channel counts.

---
Changes in v3:
o Reverted the FIX for AI reported GET_CH_32() issue, as per the recommendation of reviewers, need to create separate patch for it.

Changes in v2:
o Fixed the pre-existing bug related to GET_CH_32 interchanging the channel direction and id. This bug was not caused by any version of this patch.
o Fixed the issue when using for_each_set_bit() for mask of u64 type.

Changes in v1:
o On review recommendation of sashiko bot, in the function dw_hdma_v0_core_off(), the loop iterates over registers as per the number of channels enabled and not on total number of channels supported.
o Changed mask types to u64 for higher channel counts.

---
 drivers/dma/dw-edma/dw-edma-core.c    | 19 ++++++++++-----
 drivers/dma/dw-edma/dw-edma-core.h    |  4 ++--
 drivers/dma/dw-edma/dw-edma-pcie.c    |  8 +++----
 drivers/dma/dw-edma/dw-hdma-v0-core.c | 33 ++++++++++++++++++++-------
 drivers/dma/dw-edma/dw-hdma-v0-regs.h |  2 +-
 include/linux/dma/edma.h              | 10 ++++----
 6 files changed, 51 insertions(+), 25 deletions(-)
drivers/dma/dw-edma/dw-edma-core.c +13 -6
index c2feb3adc79f..adf1b3939f96 100644
@@ -925,9 +925,9 @@ static int dw_edma_channel_setup(struct dw_edma *dw, u32 wr_alloc, u32 rd_alloc)
 		irq = &dw->irq[pos];
 
 		if (chan->dir == EDMA_DIR_WRITE)
-			irq->wr_mask |= BIT(chan->id);
+			irq->wr_mask |= BIT_ULL(chan->id);
 		else
-			irq->rd_mask |= BIT(chan->id);
+			irq->rd_mask |= BIT_ULL(chan->id);
 
 		irq->dw = dw;
 		memcpy(&chan->msi, &irq->msi, sizeof(chan->msi));
@@ -1079,6 +1079,8 @@ int dw_edma_probe(struct dw_edma_chip *chip)
 	struct dw_edma *dw;
 	u32 wr_alloc = 0;
 	u32 rd_alloc = 0;
+	u16 max_wr_cnt;
+	u16 max_rd_cnt;
 	int i, err;
 
 	if (!chip)
@@ -1094,20 +1096,25 @@ int dw_edma_probe(struct dw_edma_chip *chip)
 
 	dw->chip = chip;
 
-	if (dw->chip->mf == EDMA_MF_HDMA_NATIVE)
+	if (dw->chip->mf == EDMA_MF_HDMA_NATIVE) {
 		dw_hdma_v0_core_register(dw);
-	else
+		max_wr_cnt = HDMA_MAX_WR_CH;
+		max_rd_cnt = HDMA_MAX_RD_CH;
+	} else {
 		dw_edma_v0_core_register(dw);
+		max_wr_cnt = EDMA_MAX_WR_CH;
+		max_rd_cnt = EDMA_MAX_RD_CH;
+	}
 
 	raw_spin_lock_init(&dw->lock);
 
 	dw->wr_ch_cnt = min_t(u16, chip->ll_wr_cnt,
 			      dw_edma_core_ch_count(dw, EDMA_DIR_WRITE));
-	dw->wr_ch_cnt = min_t(u16, dw->wr_ch_cnt, EDMA_MAX_WR_CH);
+	dw->wr_ch_cnt = min_t(u16, dw->wr_ch_cnt, max_wr_cnt);
 
 	dw->rd_ch_cnt = min_t(u16, chip->ll_rd_cnt,
 			      dw_edma_core_ch_count(dw, EDMA_DIR_READ));
-	dw->rd_ch_cnt = min_t(u16, dw->rd_ch_cnt, EDMA_MAX_RD_CH);
+	dw->rd_ch_cnt = min_t(u16, dw->rd_ch_cnt, max_rd_cnt);
 
 	if (!dw->wr_ch_cnt && !dw->rd_ch_cnt)
 		return -EINVAL;
drivers/dma/dw-edma/dw-edma-core.h +2 -2
index 902574b1ba86..d12fefbf3952 100644
@@ -91,8 +91,8 @@ struct dw_edma_chan {
 
 struct dw_edma_irq {
 	struct msi_msg                  msi;
-	u32				wr_mask;
-	u32				rd_mask;
+	u64				wr_mask;
+	u64				rd_mask;
 	struct dw_edma			*dw;
 };
 
drivers/dma/dw-edma/dw-edma-pcie.c +4 -4
index 0b30ce138503..79f653da8e0f 100644
@@ -61,11 +61,11 @@ struct dw_edma_pcie_data {
 	/* eDMA registers location */
 	struct dw_edma_block		rg;
 	/* eDMA memory linked list location */
-	struct dw_edma_block		ll_wr[EDMA_MAX_WR_CH];
-	struct dw_edma_block		ll_rd[EDMA_MAX_RD_CH];
+	struct dw_edma_block		ll_wr[HDMA_MAX_WR_CH];
+	struct dw_edma_block		ll_rd[HDMA_MAX_RD_CH];
 	/* eDMA memory data location */
-	struct dw_edma_block		dt_wr[EDMA_MAX_WR_CH];
-	struct dw_edma_block		dt_rd[EDMA_MAX_RD_CH];
+	struct dw_edma_block		dt_wr[HDMA_MAX_WR_CH];
+	struct dw_edma_block		dt_rd[HDMA_MAX_RD_CH];
 	/* Other */
 	enum dw_edma_map_format		mf;
 	u8				irqs;
drivers/dma/dw-edma/dw-hdma-v0-core.c +25 -8
index 632abb8b481c..84b0076f78bf 100644
@@ -53,13 +53,24 @@ __dw_ch_regs(struct dw_edma *dw, enum dw_edma_dir dir, u16 ch)
 static void dw_hdma_v0_core_off(struct dw_edma *dw)
 {
 	int id;
+	enum dw_edma_dir dir;
+
+	dir = EDMA_DIR_WRITE;
+	for (id = 0; id < dw->wr_ch_cnt; id++) {
+		SET_CH_32(dw, dir, id, int_setup,
+			  HDMA_V0_STOP_INT_MASK | HDMA_V0_ABORT_INT_MASK);
+		SET_CH_32(dw, dir, id, int_clear,
+			  HDMA_V0_STOP_INT_MASK | HDMA_V0_ABORT_INT_MASK);
+		SET_CH_32(dw, dir, id, ch_en, 0);
+	}
 
-	for (id = 0; id < HDMA_V0_MAX_NR_CH; id++) {
-		SET_BOTH_CH_32(dw, id, int_setup,
-			       HDMA_V0_STOP_INT_MASK | HDMA_V0_ABORT_INT_MASK);
-		SET_BOTH_CH_32(dw, id, int_clear,
-			       HDMA_V0_STOP_INT_MASK | HDMA_V0_ABORT_INT_MASK);
-		SET_BOTH_CH_32(dw, id, ch_en, 0);
+	dir = EDMA_DIR_READ;
+	for (id = 0; id < dw->rd_ch_cnt; id++) {
+		SET_CH_32(dw, dir, id, int_setup,
+			  HDMA_V0_STOP_INT_MASK | HDMA_V0_ABORT_INT_MASK);
+		SET_CH_32(dw, dir, id, int_clear,
+			  HDMA_V0_STOP_INT_MASK | HDMA_V0_ABORT_INT_MASK);
+		SET_CH_32(dw, dir, id, ch_en, 0);
 	}
 }
 
@@ -118,7 +129,8 @@ dw_hdma_v0_core_handle_int(struct dw_edma_irq *dw_irq, enum dw_edma_dir dir,
 	unsigned long total, pos, val;
 	irqreturn_t ret = IRQ_NONE;
 	struct dw_edma_chan *chan;
-	unsigned long off, mask;
+	unsigned long off;
+	u64 mask;
 
 	if (dir == EDMA_DIR_WRITE) {
 		total = dw->wr_ch_cnt;
@@ -130,7 +142,11 @@ dw_hdma_v0_core_handle_int(struct dw_edma_irq *dw_irq, enum dw_edma_dir dir,
 		mask = dw_irq->rd_mask;
 	}
 
-	for_each_set_bit(pos, &mask, total) {
+	while (mask) {
+		pos = __ffs64(mask);
+		if (pos >= total)
+			break;
+
 		chan = &dw->chan[pos + off];
 
 		val = dw_hdma_v0_core_status_int(chan);
@@ -147,6 +163,7 @@ dw_hdma_v0_core_handle_int(struct dw_edma_irq *dw_irq, enum dw_edma_dir dir,
 
 			ret = IRQ_HANDLED;
 		}
+		mask &= mask - 1;
 	}
 
 	return ret;
drivers/dma/dw-edma/dw-hdma-v0-regs.h +1 -1
index 7759ba9b4850..48e40efceb2e 100644
@@ -11,7 +11,7 @@
 
 #include <linux/dmaengine.h>
 
-#define HDMA_V0_MAX_NR_CH			8
+#define HDMA_V0_MAX_NR_CH			64
 #define HDMA_V0_CH_EN				BIT(0)
 #define HDMA_V0_LOCAL_ABORT_INT_EN		BIT(6)
 #define HDMA_V0_REMOTE_ABORT_INT_EN		BIT(5)
include/linux/dma/edma.h +6 -4
index 1fafd5b0e315..da7a5cc93ad4 100644
@@ -14,6 +14,8 @@
 
 #define EDMA_MAX_WR_CH                                  8
 #define EDMA_MAX_RD_CH                                  8
+#define HDMA_MAX_WR_CH                                  64
+#define HDMA_MAX_RD_CH                                  64
 
 struct dw_edma;
 
@@ -89,12 +91,12 @@ struct dw_edma_chip {
 	u16			ll_wr_cnt;
 	u16			ll_rd_cnt;
 	/* link list address */
-	struct dw_edma_region	ll_region_wr[EDMA_MAX_WR_CH];
-	struct dw_edma_region	ll_region_rd[EDMA_MAX_RD_CH];
+	struct dw_edma_region	ll_region_wr[HDMA_MAX_WR_CH];
+	struct dw_edma_region	ll_region_rd[HDMA_MAX_RD_CH];
 
 	/* data region */
-	struct dw_edma_region	dt_region_wr[EDMA_MAX_WR_CH];
-	struct dw_edma_region	dt_region_rd[EDMA_MAX_RD_CH];
+	struct dw_edma_region	dt_region_wr[HDMA_MAX_WR_CH];
+	struct dw_edma_region	dt_region_rd[HDMA_MAX_RD_CH];
 
 	/* interrupt emulation */
 	int			db_irq;
Signature · 1 line
2.43.0
#1 lore raw
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:

New issues:
- [Medium] The 64-channel HDMA feature is unreachable due to hardcoded legacy limits in the driver bindings.

Pre-existing issues:
- [High] Potential NULL pointer dereference if a shared IRQ fires before dw_irq->dw is initialized. --

commit ae4f94060e0e6e5d4419cd4f95926541afa41dd0
Author: Devendra K Verma <[email protected]>

dmaengine: dw-edma: Enable HDMA 64R/W Channels

This patch expands the designware eDMA driver to support up to 64 read and 64 write channels for the HDMA controller, aligning with the hardware databook. It introduces new macros for the HDMA channel counts, expands the layout of the channel-related structures, updates channel masks to 64-bit, and updates the probe sequence to configure the core based on the controller type.

Quoted 5 lines
drivers/dma/dw-edma/dw-edma-core.c +0 -0
index c2feb3adc79fa..adf1b3939f96c 100644

drivers/dma/dw-edma/dw-edma-core.c static int dw_edma_channel_setup(struct dw_edma *dw, u32 wr_alloc, u32 rd_alloc) · line 932

Quoted 10 lines
drivers/dma/dw-edma/dw-edma-core.c +2 -2
@@ -925,9 +925,9 @@ static int dw_edma_channel_setup(struct dw_edma *dw, u32 wr_alloc, u32 rd_alloc)
 		irq = &dw->irq[pos];
 
 		if (chan->dir == EDMA_DIR_WRITE)
-			irq->wr_mask |= BIT(chan->id);
+			irq->wr_mask |= BIT_ULL(chan->id);
 		else
-			irq->rd_mask |= BIT(chan->id);
+			irq->rd_mask |= BIT_ULL(chan->id);
 
 		irq->dw = dw;

[Severity: High]
This is a pre-existing issue, but could a shared interrupt fire before irq->dw is initialized here?

In dw_edma_probe(), dw_edma_irq_request() is called before dw_edma_channel_setup(). The IRQs are requested with IRQF_SHARED:

dw_edma_probe() {
    ...
    err = dw_edma_irq_request(dw, &wr_alloc, &rd_alloc);
    ...
    err = dw_edma_channel_setup(dw, wr_alloc, rd_alloc);
}

If the shared IRQ fires immediately after registration, the interrupt handler might dereference a NULL dw_irq->dw:

dw_edma_interrupt_write()
dw_edma_core_handle_int()

       return dw_irq->dw->core->handle_int(dw_irq, dir, done, abort);

Should irq->dw be initialized prior to calling request_irq()?

[ ... ]

include/linux/dma/edma.h line 18

Quoted 10 lines
include/linux/dma/edma.h +2 -0
index 1fafd5b0e3153..da7a5cc93ad43 100644
@@ -14,6 +14,8 @@
 
 #define EDMA_MAX_WR_CH                                  8
 #define EDMA_MAX_RD_CH                                  8
+#define HDMA_MAX_WR_CH                                  64
+#define HDMA_MAX_RD_CH                                  64

[Severity: Medium]
Will these expanded 64-channel limits actually be reachable with the current driver bindings?

Looking at drivers/pci/controller/dwc/pcie-designware.c, dw_pcie_edma_find_channels() still explicitly enforces the legacy 8-channel limit and returns -EINVAL if the configuration exceeds it:

    if (!pci->edma.ll_wr_cnt || pci->edma.ll_wr_cnt > EDMA_MAX_WR_CH ||
        !pci->edma.ll_rd_cnt || pci->edma.ll_rd_cnt > EDMA_MAX_RD_CH)
        return -EINVAL;

Similarly, in drivers/dma/dw-edma/dw-edma-pcie.c, the Xilinx MDB HDMA data statically declares 8 channels and dw_edma_pcie_get_xilinx_dma_data() caps the write channels:

    pdata->wr_ch_cnt = min(pdata->wr_ch_cnt,
                   FIELD_GET(DW_PCIE_XILINX_MDB_VSEC_DMA_WR_CH, val));

Do the hardcoded legacy limits in the driver bindings prevent the new 64-channel feature from being fully utilized?

Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=1
#2 lore raw

Hi

Please check my response inline.

regards,
Devendra

Quoted 35 lines · On 23-Jun-26 17:11, [email protected] wrote:

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:

New issues:
- [Medium] The 64-channel HDMA feature is unreachable due to hardcoded legacy limits in the driver bindings.

Pre-existing issues:
- [High] Potential NULL pointer dereference if a shared IRQ fires before dw_irq->dw is initialized. --

commit ae4f94060e0e6e5d4419cd4f95926541afa41dd0
Author: Devendra K Verma <[email protected]>

dmaengine: dw-edma: Enable HDMA 64R/W Channels

This patch expands the designware eDMA driver to support up to 64 read and 64 write channels for the HDMA controller, aligning with the hardware databook. It introduces new macros for the HDMA channel counts, expands the layout of the channel-related structures, updates channel masks to 64-bit, and updates the probe sequence to configure the core based on the controller type.

Quoted 14 lines
drivers/dma/dw-edma/dw-edma-core.c +2 -2
index c2feb3adc79fa..adf1b3939f96c 100644
@@ -925,9 +925,9 @@ static int dw_edma_channel_setup(struct dw_edma *dw, u32 wr_alloc, u32 rd_alloc)
  		irq = &dw->irq[pos];
 
  		if (chan->dir == EDMA_DIR_WRITE)
-			irq->wr_mask |= BIT(chan->id);
+			irq->wr_mask |= BIT_ULL(chan->id);
  		else
-			irq->rd_mask |= BIT(chan->id);
+			irq->rd_mask |= BIT_ULL(chan->id);
 
Quoted 6 lines

drivers/dma/dw-edma/dw-edma-core.c static int dw_edma_channel_setup(struct dw_edma *dw, u32 wr_alloc, u32 rd_alloc) · line 932

Quoted 1 line
drivers/dma/dw-edma/dw-edma-core.c +0 -0
  		irq->dw = dw;

[Severity: High]
This is a pre-existing issue, but could a shared interrupt fire before irq->dw is initialized here?

As this is pre-existing issue it shall be taken in a separate patch series.

Quoted 13 lines

In dw_edma_probe(), dw_edma_irq_request() is called before dw_edma_channel_setup(). The IRQs are requested with IRQF_SHARED:

dw_edma_probe() {
     ...
     err = dw_edma_irq_request(dw, &wr_alloc, &rd_alloc);
     ...
     err = dw_edma_channel_setup(dw, wr_alloc, rd_alloc);
}

If the shared IRQ fires immediately after registration, the interrupt handler might dereference a NULL dw_irq->dw:

Quoted 7 lines

dw_edma_interrupt_write()

    dw_edma_core_handle_int()
        return dw_irq->dw->core->handle_int(dw_irq, dir, done, abort);

Should irq->dw be initialized prior to calling request_irq()?

[ ... ]

As the issue existed before any fix of this patch, it shall be taken in a separate patch series.

Quoted 16 lines

include/linux/dma/edma.h line 18

Quoted 11 lines
include/linux/dma/edma.h +2 -0
index 1fafd5b0e3153..da7a5cc93ad43 100644
@@ -14,6 +14,8 @@
 
  #define EDMA_MAX_WR_CH                                  8
  #define EDMA_MAX_RD_CH                                  8
+#define HDMA_MAX_WR_CH                                  64
+#define HDMA_MAX_RD_CH                                  64

[Severity: Medium]
Will these expanded 64-channel limits actually be reachable with the current driver bindings?

Quoted 8 lines

Looking at drivers/pci/controller/dwc/pcie-designware.c, dw_pcie_edma_find_channels() still explicitly enforces the legacy 8-channel limit and returns -EINVAL if the configuration exceeds it:

     if (!pci->edma.ll_wr_cnt || pci->edma.ll_wr_cnt > EDMA_MAX_WR_CH ||
         !pci->edma.ll_rd_cnt || pci->edma.ll_rd_cnt > EDMA_MAX_RD_CH)
         return -EINVAL;

This particular function targets non-HDMA platforms which suggests that increasing the channel limit will not affect anything here. This code shall be retained as is. It is not affected by increase in limit for HDMA channels.

Quoted 10 lines

Similarly, in drivers/dma/dw-edma/dw-edma-pcie.c, the Xilinx MDB HDMA data statically declares 8 channels and dw_edma_pcie_get_xilinx_dma_data() caps the write channels:

     pdata->wr_ch_cnt = min(pdata->wr_ch_cnt,
                    FIELD_GET(DW_PCIE_XILINX_MDB_VSEC_DMA_WR_CH, val));

Do the hardcoded legacy limits in the driver bindings prevent the new 64-channel feature from being fully utilized?

It depends on the user, how many channels it enables. If user wishes to enable more that 8 channels, be it read/write, then the current code limits the channels to a ceiling of 8 channels which is a case of under-utilization of HDMA channels. This patch enables the code to handle the max supported HDMA channels which is 64 Read/Write. Thus, using any number of channels below <= 64 is fine when using this patch. This patch would not create any issue for the existing use cases.

#3 lore raw
In reply to Devendra K Verma
Quoted 19 lines · Devendra K Verma

As per 'Designware Cores PCI Express Controller Databook', Section 7.1 - Overview, HDMA supports 64 Read and 64 Write channels. Current controller driver supports up to 8 read and write channels only. In order to utilize all the channels the controller driver need to have the channel related structs and variables as per the number of channels supported by IP. Following changes are made to enable 64 Read / 64 Write channel support:

o Defined HDMA specific macros to reflect the channel count.
o The count of ll_regions and dt_regions in dw_edma_chip and dw_edma_pcie_data shall be in accordance to number of read and write channels.
o In dw_edma_probe() configure the channels as per the channels of the IP used.
o Changed mask types to u64 for higher channel counts.

---

...

Quoted 12 lines
drivers/dma/dw-edma/dw-hdma-v0-core.c +2 -1
@@ -118,7 +129,8 @@ dw_hdma_v0_core_handle_int(struct dw_edma_irq *dw_irq, enum dw_edma_dir dir,
 	unsigned long total, pos, val;
 	irqreturn_t ret = IRQ_NONE;
 	struct dw_edma_chan *chan;
-	unsigned long off, mask;
+	unsigned long off;
+	u64 mask;
 
 	if (dir == EDMA_DIR_WRITE) {
 		total = dw->wr_ch_cnt;

drivers/dma/dw-edma/dw-hdma-v0-core.c dw_hdma_v0_core_handle_int(struct dw_edma_irq *dw_irq, enum dw_edma_dir dir, · line 145

Quoted 5 lines
drivers/dma/dw-edma/dw-hdma-v0-core.c +1 -1
@@ -130,7 +142,11 @@ dw_hdma_v0_core_handle_int(struct dw_edma_irq *dw_irq, enum dw_edma_dir dir,
 		mask = dw_irq->rd_mask;
 	}
 
-	for_each_set_bit(pos, &mask, total) {
+	while (mask) {

can you use DECLARE_BITMAP(status_mask, 64); and keep original for_each_set_bit() ref:

https://lore.kernel.org/dmaengine/aj1JrufD1vIZH06s@lizhi-Precision-Tower-5810/T/#u

Frank

#4 lore raw
Quoted 42 lines · Frank Li
Quoted 19 lines · Devendra K Verma

As per 'Designware Cores PCI Express Controller Databook', Section 7.1 - Overview, HDMA supports 64 Read and 64 Write channels. Current controller driver supports up to 8 read and write channels only. In order to utilize all the channels the controller driver need to have the channel related structs and variables as per the number of channels supported by IP. Following changes are made to enable 64 Read / 64 Write channel support:

o Defined HDMA specific macros to reflect the channel count.
o The count of ll_regions and dt_regions in dw_edma_chip and dw_edma_pcie_data shall be in accordance to number of read and write channels.
o In dw_edma_probe() configure the channels as per the channels of the IP used.
o Changed mask types to u64 for higher channel counts.

---

...

Quoted 12 lines
drivers/dma/dw-edma/dw-hdma-v0-core.c +2 -1
@@ -118,7 +129,8 @@ dw_hdma_v0_core_handle_int(struct dw_edma_irq *dw_irq, enum dw_edma_dir dir,
  	unsigned long total, pos, val;
  	irqreturn_t ret = IRQ_NONE;
  	struct dw_edma_chan *chan;
-	unsigned long off, mask;
+	unsigned long off;
+	u64 mask;
 
  	if (dir == EDMA_DIR_WRITE) {
  		total = dw->wr_ch_cnt;

drivers/dma/dw-edma/dw-hdma-v0-core.c dw_hdma_v0_core_handle_int(struct dw_edma_irq *dw_irq, enum dw_edma_dir dir, · line 145

Quoted 5 lines
drivers/dma/dw-edma/dw-hdma-v0-core.c +1 -1
@@ -130,7 +142,11 @@ dw_hdma_v0_core_handle_int(struct dw_edma_irq *dw_irq, enum dw_edma_dir dir,
  		mask = dw_irq->rd_mask;
  	}
 
-	for_each_set_bit(pos, &mask, total) {
+	while (mask) {

can you use DECLARE_BITMAP(status_mask, 64); and keep original for_each_set_bit() ref:

Quoted 4 lines

https://lore.kernel.org/dmaengine/aj1JrufD1vIZH06s@lizhi-Precision-Tower-5810/T/#u

Frank

Hi Frank, thank you for the suggestion!
This is also appreciation comment in the way you review and provide example for the ease of reviewer and patch developers which helps in speed up evaluation and implementation for that particular suggestion.

I will push the changes in next review.

-Devendra