All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/12] dmaengine: Add dmaengine API to avoid call DMA Engine callback directly
@ 2026-09-23 16:19 Frank.Li
  2026-09-23 16:19 ` [PATCH v2 01/12] async_tx: replace direct ->device_prep*() calls with standard DMA engine API Frank.Li
                   ` (12 more replies)
  0 siblings, 13 replies; 17+ messages in thread
From: Frank.Li @ 2026-09-23 16:19 UTC (permalink / raw)
  To: Vinod Koul, Frank Li, Dan Williams, Herbert Xu, David S. Miller,
	Jon Mason, Dave Jiang, Allen Hubbe
  Cc: dmaengine, linux-kernel, linux-crypto, imx, Frank Li, ntb

Add dmaengine APIs to avoid call DMA Engine callback directly. Prepare to
make dmaengine provider private.

Fix all under crypto/async_tx

Build pass under crypto/async_tx after change dma_device *device to _device.
to make sure all code use dmaengine APIs.

Assisted-by: LLM
Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
Changes in v2:
- Add more patch to cleanup crypto/async_tx
- collect https://lore.kernel.org/imx/b40fa0d7-fbd0-4ee8-b99c-781d08c18838@intel.com/T/#t
- first two patches can be applied without added new dmaengine apis.
- Link to v1: https://patch.msgid.link/20260921-dmaengine_prep_dma_pq-v1-0-9563ed448260@nxp.com

To: Dan Williams <djbw@kernel.org>
To: Herbert Xu <herbert@gondor.apana.org.au>
To: "David S. Miller" <davem@davemloft.net>
To: Vinod Koul <vkoul@kernel.org>
To: Frank Li <Frank.Li@kernel.org>
To: Jon Mason <jdmason@kudzu.us>
To: Dave Jiang <dave.jiang@intel.com>
To: Allen Hubbe <allenbh@gmail.com>
Cc: linux-crypto@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: dmaengine@vger.kernel.org
Cc: ntb@lists.linux.dev
dmaengine: change dmaengine_get_unmap_data() first arg to dma_chan into this series

---
Frank Li (12):
      async_tx: replace direct ->device_prep*() calls with standard DMA engine API
      async_tx: use dmaengine_get_dma_device() instead of chan->device->dev
      dmaengine: add dmaengine_prep_dma_(pq|pq_val|interrupt|xor)() API
      dmaengine: add dmaengine_is_*_aligned() helpers for DMA consumers
      dmaengine: add dmaengine_get_copy_align() and related alignment getter helpers
      dmaengine: add dmaengine_get_cap_mask() and dmaengine_has_cap() helpers
      dmaengine: add dmaengine_get_max_xor() helper
      dmaengine: change dmaengine_get_unmap_data() first arg to dma_chan
      dmaengine: replace dma_maxqp() with dmaengine_maxpq() taking struct dma_chan *
      async_tx: use dmaengine_prep_dma_(pq|pq_val|interrupt|xor) instead of direct callback
      async_tx: convert to dmaengine_is_*_aligned() helpers
      async_tx: replace open-coded cap_mask accesses with dmaengine_has_cap()

 crypto/async_tx/async_memcpy.c      |  18 +--
 crypto/async_tx/async_pq.c          |  60 ++++----
 crypto/async_tx/async_raid6_recov.c |  22 ++-
 crypto/async_tx/async_tx.c          |  19 +--
 crypto/async_tx/async_xor.c         |  58 ++++---
 drivers/dma/dmaengine.c             |   4 +-
 drivers/dma/dmatest.c               |   4 +-
 drivers/dma/mv_xor.c                |   4 +-
 drivers/ntb/ntb_transport.c         |   4 +-
 drivers/ntb/test/ntb_perf.c         |   2 +-
 include/linux/async_tx.h            |   8 +-
 include/linux/dmaengine.h           | 296 +++++++++++++++++++++++++++++++++++-
 12 files changed, 383 insertions(+), 116 deletions(-)
---
base-commit: 5c4d4169604b335c38bbc79bc1fc03042981fc6f
change-id: 20260921-dmaengine_prep_dma_pq-7eba91a609ed

Best regards,
--  
Frank Li <Frank.Li@nxp.com>


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH v2 01/12] async_tx: replace direct ->device_prep*() calls with standard DMA engine API
  2026-09-23 16:19 [PATCH v2 00/12] dmaengine: Add dmaengine API to avoid call DMA Engine callback directly Frank.Li
@ 2026-09-23 16:19 ` Frank.Li
  2026-09-23 16:19 ` [PATCH v2 02/12] async_tx: use dmaengine_get_dma_device() instead of chan->device->dev Frank.Li
                   ` (11 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: Frank.Li @ 2026-09-23 16:19 UTC (permalink / raw)
  To: Vinod Koul, Frank Li, Dan Williams, Herbert Xu, David S. Miller,
	Jon Mason, Dave Jiang, Allen Hubbe
  Cc: dmaengine, linux-kernel, linux-crypto, imx, Frank Li, ntb

From: Frank Li <Frank.Li@nxp.com>

DMA engine consumers must not call the channel's device_prep_*() function
pointers directly. Use the standard dmaengine wrapper APIs instead.

Assisted-by: LLM
Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
 crypto/async_tx/async_memcpy.c | 6 +++---
 crypto/async_tx/async_tx.c     | 4 ++--
 include/linux/async_tx.h       | 8 ++------
 3 files changed, 7 insertions(+), 11 deletions(-)

diff --git a/crypto/async_tx/async_memcpy.c b/crypto/async_tx/async_memcpy.c
index c538e30e99094..627b6ad9313e0 100644
--- a/crypto/async_tx/async_memcpy.c
+++ b/crypto/async_tx/async_memcpy.c
@@ -58,9 +58,9 @@ async_memcpy(struct page *dest, struct page *src, unsigned int dest_offset,
 					      DMA_FROM_DEVICE);
 		unmap->len = len;
 
-		tx = device->device_prep_dma_memcpy(chan, unmap->addr[1],
-						    unmap->addr[0], len,
-						    dma_prep_flags);
+		tx = dmaengine_prep_dma_memcpy(chan, unmap->addr[1],
+					       unmap->addr[0], len,
+					       dma_prep_flags);
 	}
 
 	if (tx) {
diff --git a/crypto/async_tx/async_tx.c b/crypto/async_tx/async_tx.c
index ad72057a5e0d7..01ef830675574 100644
--- a/crypto/async_tx/async_tx.c
+++ b/crypto/async_tx/async_tx.c
@@ -79,7 +79,7 @@ async_tx_channel_switch(struct dma_async_tx_descriptor *depend_tx,
 
 	/* attached dependency, flush the parent channel */
 	if (!intr_tx) {
-		device->device_issue_pending(chan);
+		dma_async_issue_pending(chan);
 		return;
 	}
 
@@ -113,7 +113,7 @@ async_tx_channel_switch(struct dma_async_tx_descriptor *depend_tx,
 			intr_tx->tx_submit(intr_tx);
 			async_tx_ack(intr_tx);
 		}
-		device->device_issue_pending(chan);
+		dma_async_issue_pending(chan);
 	} else {
 		if (dma_wait_for_async_tx(depend_tx) != DMA_COMPLETE)
 			panic("%s: DMA error waiting for depend_tx\n",
diff --git a/include/linux/async_tx.h b/include/linux/async_tx.h
index 1ca9f9e05f4f1..9f7fef19f2142 100644
--- a/include/linux/async_tx.h
+++ b/include/linux/async_tx.h
@@ -87,12 +87,8 @@ struct async_submit_ctl {
  */
 static inline void async_tx_issue_pending(struct dma_async_tx_descriptor *tx)
 {
-	if (likely(tx)) {
-		struct dma_chan *chan = tx->chan;
-		struct dma_device *dma = chan->device;
-
-		dma->device_issue_pending(chan);
-	}
+	if (likely(tx))
+		dma_async_issue_pending(tx->chan);
 }
 #ifdef CONFIG_ARCH_HAS_ASYNC_TX_FIND_CHANNEL
 #include <asm/async_tx.h>

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v2 02/12] async_tx: use dmaengine_get_dma_device() instead of chan->device->dev
  2026-09-23 16:19 [PATCH v2 00/12] dmaengine: Add dmaengine API to avoid call DMA Engine callback directly Frank.Li
  2026-09-23 16:19 ` [PATCH v2 01/12] async_tx: replace direct ->device_prep*() calls with standard DMA engine API Frank.Li
@ 2026-09-23 16:19 ` Frank.Li
  2026-09-23 16:19 ` [PATCH v2 03/12] dmaengine: add dmaengine_prep_dma_(pq|pq_val|interrupt|xor)() API Frank.Li
                   ` (10 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: Frank.Li @ 2026-09-23 16:19 UTC (permalink / raw)
  To: Vinod Koul, Frank Li, Dan Williams, Herbert Xu, David S. Miller,
	Jon Mason, Dave Jiang, Allen Hubbe
  Cc: dmaengine, linux-kernel, linux-crypto, imx, Frank Li, ntb

From: Frank Li <Frank.Li@nxp.com>

Replace direct dma_chan::device::dev access with the proper
dmaengine_get_dma_device() for consumer API.

chan->device->dev is not always the device used for DMA mapping. Some DMA
engines support per-channel IOMMU mappings, so different channels may use
different DMA devices.  dmaengine_get_dma_device() returns the correct
device for each channel.

Prepare for making the DMA engine provider data structures private. DMA
consumers should not access DMA engine internals directly.

Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
 crypto/async_tx/async_memcpy.c      | 5 +++--
 crypto/async_tx/async_pq.c          | 9 +++++----
 crypto/async_tx/async_raid6_recov.c | 4 ++--
 crypto/async_tx/async_xor.c         | 8 +++++---
 4 files changed, 15 insertions(+), 11 deletions(-)

diff --git a/crypto/async_tx/async_memcpy.c b/crypto/async_tx/async_memcpy.c
index 627b6ad9313e0..53277271f063a 100644
--- a/crypto/async_tx/async_memcpy.c
+++ b/crypto/async_tx/async_memcpy.c
@@ -44,6 +44,7 @@ async_memcpy(struct page *dest, struct page *src, unsigned int dest_offset,
 
 	if (unmap && is_dma_copy_aligned(device, src_offset, dest_offset, len)) {
 		unsigned long dma_prep_flags = 0;
+		struct device *dma_dev =  dmaengine_get_dma_device(chan);
 
 		if (submit->cb_fn)
 			dma_prep_flags |= DMA_PREP_INTERRUPT;
@@ -51,10 +52,10 @@ async_memcpy(struct page *dest, struct page *src, unsigned int dest_offset,
 			dma_prep_flags |= DMA_PREP_FENCE;
 
 		unmap->to_cnt = 1;
-		unmap->addr[0] = dma_map_page(device->dev, src, src_offset, len,
+		unmap->addr[0] = dma_map_page(dma_dev, src, src_offset, len,
 					      DMA_TO_DEVICE);
 		unmap->from_cnt = 1;
-		unmap->addr[1] = dma_map_page(device->dev, dest, dest_offset, len,
+		unmap->addr[1] = dma_map_page(dma_dev, dest, dest_offset, len,
 					      DMA_FROM_DEVICE);
 		unmap->len = len;
 
diff --git a/crypto/async_tx/async_pq.c b/crypto/async_tx/async_pq.c
index 27f99349e310b..3a7fd90556501 100644
--- a/crypto/async_tx/async_pq.c
+++ b/crypto/async_tx/async_pq.c
@@ -196,6 +196,7 @@ async_gen_syndrome(struct page **blocks, unsigned int *offsets, int disks,
 	     dma_maxpq(device, DMA_PREP_CONTINUE) > 0) &&
 	    is_dma_pq_aligned_offs(device, offsets, disks, len)) {
 		struct dma_async_tx_descriptor *tx;
+		struct device *dma_dev = dmaengine_get_dma_device(chan);
 		enum dma_ctrl_flags dma_flags = 0;
 		unsigned char coefs[MAX_DISKS];
 		int i, j;
@@ -211,7 +212,7 @@ async_gen_syndrome(struct page **blocks, unsigned int *offsets, int disks,
 		for (i = 0, j = 0; i < src_cnt; i++) {
 			if (blocks[i] == NULL)
 				continue;
-			unmap->addr[j] = dma_map_page(device->dev, blocks[i],
+			unmap->addr[j] = dma_map_page(dma_dev, blocks[i],
 						offsets[i], len, DMA_TO_DEVICE);
 			coefs[j] = raid6_gfexp[i];
 			unmap->to_cnt++;
@@ -224,7 +225,7 @@ async_gen_syndrome(struct page **blocks, unsigned int *offsets, int disks,
 		 */
 		unmap->bidi_cnt++;
 		if (P(blocks, disks))
-			unmap->addr[j++] = dma_map_page(device->dev, P(blocks, disks),
+			unmap->addr[j++] = dma_map_page(dma_dev, P(blocks, disks),
 							P(offsets, disks),
 							len, DMA_BIDIRECTIONAL);
 		else {
@@ -234,7 +235,7 @@ async_gen_syndrome(struct page **blocks, unsigned int *offsets, int disks,
 
 		unmap->bidi_cnt++;
 		if (Q(blocks, disks))
-			unmap->addr[j++] = dma_map_page(device->dev, Q(blocks, disks),
+			unmap->addr[j++] = dma_map_page(dma_dev, Q(blocks, disks),
 							Q(offsets, disks),
 							len, DMA_BIDIRECTIONAL);
 		else {
@@ -314,7 +315,7 @@ async_syndrome_val(struct page **blocks, unsigned int *offsets, int disks,
 
 	if (unmap && disks <= dma_maxpq(device, 0) &&
 	    is_dma_pq_aligned_offs(device, offsets, disks, len)) {
-		struct device *dev = device->dev;
+		struct device *dev = dmaengine_get_dma_device(chan);
 		dma_addr_t pq[2];
 		int i, j = 0, src_cnt = 0;
 
diff --git a/crypto/async_tx/async_raid6_recov.c b/crypto/async_tx/async_raid6_recov.c
index e53870d84bc55..ed5c5eb126990 100644
--- a/crypto/async_tx/async_raid6_recov.c
+++ b/crypto/async_tx/async_raid6_recov.c
@@ -32,7 +32,7 @@ async_sum_product(struct page *dest, unsigned int d_off,
 		unmap = dmaengine_get_unmap_data(dma->dev, 3, GFP_NOWAIT);
 
 	if (unmap) {
-		struct device *dev = dma->dev;
+		struct device *dev = dmaengine_get_dma_device(chan);
 		dma_addr_t pq[2];
 		struct dma_async_tx_descriptor *tx;
 		enum dma_ctrl_flags dma_flags = DMA_PREP_PQ_DISABLE_P;
@@ -101,7 +101,7 @@ async_mult(struct page *dest, unsigned int d_off, struct page *src,
 
 	if (unmap) {
 		dma_addr_t dma_dest[2];
-		struct device *dev = dma->dev;
+		struct device *dev = dmaengine_get_dma_device(chan);
 		struct dma_async_tx_descriptor *tx;
 		enum dma_ctrl_flags dma_flags = DMA_PREP_PQ_DISABLE_P;
 
diff --git a/crypto/async_tx/async_xor.c b/crypto/async_tx/async_xor.c
index 84458375b202b..06c48e8cce834 100644
--- a/crypto/async_tx/async_xor.c
+++ b/crypto/async_tx/async_xor.c
@@ -183,6 +183,7 @@ async_xor_offs(struct page *dest, unsigned int offset,
 
 	if (unmap && dma_xor_aligned_offsets(device, offset,
 				src_offs, src_cnt, len)) {
+		struct device *dma_dev = dmaengine_get_dma_device(chan);
 		struct dma_async_tx_descriptor *tx;
 		int i, j;
 
@@ -194,13 +195,13 @@ async_xor_offs(struct page *dest, unsigned int offset,
 			if (!src_list[i])
 				continue;
 			unmap->to_cnt++;
-			unmap->addr[j++] = dma_map_page(device->dev, src_list[i],
+			unmap->addr[j++] = dma_map_page(dma_dev, src_list[i],
 					src_offs ? src_offs[i] : offset,
 					len, DMA_TO_DEVICE);
 		}
 
 		/* map it bidirectional as it may be re-used as a source */
-		unmap->addr[j] = dma_map_page(device->dev, dest, offset, len,
+		unmap->addr[j] = dma_map_page(dma_dev, dest, offset, len,
 					      DMA_BIDIRECTIONAL);
 		unmap->bidi_cnt = 1;
 
@@ -316,6 +317,7 @@ async_xor_val_offs(struct page *dest, unsigned int offset,
 	if (unmap && src_cnt <= device->max_xor &&
 	    dma_xor_aligned_offsets(device, offset, src_offs, src_cnt, len)) {
 		unsigned long dma_prep_flags = 0;
+		struct device *dma_dev = dmaengine_get_dma_device(chan);
 		int i;
 
 		pr_debug("%s: (async) len: %zu\n", __func__, len);
@@ -326,7 +328,7 @@ async_xor_val_offs(struct page *dest, unsigned int offset,
 			dma_prep_flags |= DMA_PREP_FENCE;
 
 		for (i = 0; i < src_cnt; i++) {
-			unmap->addr[i] = dma_map_page(device->dev, src_list[i],
+			unmap->addr[i] = dma_map_page(dma_dev, src_list[i],
 					src_offs ? src_offs[i] : offset,
 					len, DMA_TO_DEVICE);
 			unmap->to_cnt++;

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v2 03/12] dmaengine: add dmaengine_prep_dma_(pq|pq_val|interrupt|xor)() API
  2026-09-23 16:19 [PATCH v2 00/12] dmaengine: Add dmaengine API to avoid call DMA Engine callback directly Frank.Li
  2026-09-23 16:19 ` [PATCH v2 01/12] async_tx: replace direct ->device_prep*() calls with standard DMA engine API Frank.Li
  2026-09-23 16:19 ` [PATCH v2 02/12] async_tx: use dmaengine_get_dma_device() instead of chan->device->dev Frank.Li
@ 2026-09-23 16:19 ` Frank.Li
  2026-09-23 16:26   ` sashiko-bot
  2026-09-23 16:19 ` [PATCH v2 04/12] dmaengine: add dmaengine_is_*_aligned() helpers for DMA consumers Frank.Li
                   ` (9 subsequent siblings)
  12 siblings, 1 reply; 17+ messages in thread
From: Frank.Li @ 2026-09-23 16:19 UTC (permalink / raw)
  To: Vinod Koul, Frank Li, Dan Williams, Herbert Xu, David S. Miller,
	Jon Mason, Dave Jiang, Allen Hubbe
  Cc: dmaengine, linux-kernel, linux-crypto, imx, Frank Li, ntb

From: Frank Li <Frank.Li@nxp.com>

Add dmaengine_prep_dma_(pq|pq_val|interrupt|xor)() as an inline
wrapper around the device_prep_dma_(pq|pq_val|interrupt|xor)() callback,
consistent with how other dmaengine prep helpers like
dmaengine_prep_dma_memcpy() are structured.

Provide a clean public API that hides the direct callback access and add
proper NULL-checks on chan, chan->device, and the callback pointer.

Assisted-by: LLM
Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
 include/linux/dmaengine.h | 134 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 134 insertions(+)

diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index c3a49a33307c6..6a187136f9493 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -1232,6 +1232,122 @@ static inline struct dma_async_tx_descriptor *dmaengine_prep_dma_memcpy(
 						    len, flags);
 }
 
+/**
+ * dmaengine_prep_dma_xor - prepare a DMA XOR operation
+ * @chan: the channel to use for this operation
+ * @dst: destination buffer address
+ * @src: array of source buffer addresses
+ * @src_cnt: number of source buffers
+ * @len: length in bytes of each source and destination buffer
+ * @flags: DMA engine flags (e.g. DMA_PREP_INTERRUPT)
+ *
+ * Prepare an XOR parity generation transaction.  The engine computes:
+ *   dst = src[0] XOR src[1] XOR ... XOR src[src_cnt - 1]
+ *
+ * Returns a descriptor on success, or NULL if the channel does not support
+ * this operation or the request could not be queued.
+ */
+static inline struct dma_async_tx_descriptor *
+dmaengine_prep_dma_xor(struct dma_chan *chan, dma_addr_t dst, dma_addr_t *src,
+		       unsigned int src_cnt, size_t len, unsigned long flags)
+{
+	if (!chan || !chan->device || !chan->device->device_prep_dma_xor)
+		return NULL;
+
+	return chan->device->device_prep_dma_xor(chan, dst, src,
+						 src_cnt, len, flags);
+}
+
+/**
+ * dmaengine_prep_dma_xor_val - prepare a DMA XOR zero-sum validation operation
+ * @chan: the channel to use for this operation
+ * @src: array of source buffer addresses
+ * @src_cnt: number of source buffers
+ * @len: length in bytes of each source buffer
+ * @result: output flag set to SUM_CHECK_P_RESULT if the XOR of all sources
+ *          is non-zero (i.e. parity error), cleared otherwise
+ * @flags: DMA engine flags (e.g. DMA_PREP_INTERRUPT)
+ *
+ * Prepare an XOR zero-sum validation transaction.  The engine XORs all
+ * source buffers and checks whether the result is zero.  The outcome is
+ * written to @result on completion.
+ *
+ * Returns a descriptor on success, or NULL if the channel does not support
+ * this operation or the request could not be queued.
+ */
+static inline struct dma_async_tx_descriptor *
+dmaengine_prep_dma_xor_val(struct dma_chan *chan, dma_addr_t *src,
+			   unsigned int src_cnt, size_t len,
+			   enum sum_check_flags *result, unsigned long flags)
+{
+	if (!chan || !chan->device || !chan->device->device_prep_dma_xor_val)
+		return NULL;
+
+	return chan->device->device_prep_dma_xor_val(chan, src, src_cnt,
+						     len, result, flags);
+}
+
+/**
+ * dmaengine_prep_dma_pq - prepare a DMA PQ (RAID-6 P+Q) operation
+ * @chan: the channel to use for this operation
+ * @dst: array of two destination addresses: dst[0] for P, dst[1] for Q
+ * @src: array of source buffer addresses
+ * @src_cnt: number of source buffers
+ * @scf: array of scaling coefficients, one per source buffer
+ * @len: length in bytes of each source and destination buffer
+ * @flags: DMA engine flags (e.g. DMA_PREP_INTERRUPT)
+ *
+ * Prepare a P+Q parity generation transaction.  The engine computes:
+ *   P = XOR of all source buffers
+ *   Q = Galois field sum of (scf[i] * src[i]) over all sources
+ *
+ * Returns a descriptor on success, or NULL if the channel does not support
+ * this operation or the request could not be queued.
+ */
+static inline struct dma_async_tx_descriptor *
+dmaengine_prep_dma_pq(struct dma_chan *chan, dma_addr_t *dst, dma_addr_t *src,
+		      unsigned int src_cnt, const unsigned char *scf,
+		      size_t len, unsigned long flags)
+{
+	if (!chan || !chan->device || !chan->device->device_prep_dma_pq)
+		return NULL;
+
+	return chan->device->device_prep_dma_pq(chan, dst, src,
+						src_cnt, scf, len, flags);
+}
+
+/**
+ * dmaengine_prep_dma_pq_val - prepare a DMA PQ validation operation
+ * @chan: the channel to use for this operation
+ * @pq: array of two addresses holding existing P and Q parity buffers
+ * @src: array of source buffer addresses
+ * @src_cnt: number of source buffers
+ * @scf: array of scaling coefficients, one per source buffer
+ * @len: length in bytes of each buffer
+ * @pqres: output flags indicating P and/or Q check results (SUM_CHECK_P_VALID,
+ *         SUM_CHECK_Q_VALID)
+ * @flags: DMA engine flags (e.g. DMA_PREP_INTERRUPT)
+ *
+ * Prepare a PQ validation transaction.  The engine recomputes P and Q from the
+ * source buffers and compares them against the existing parity stored at @pq.
+ * The result of each comparison is reported through @pqres.
+ *
+ * Returns a descriptor on success, or NULL if the channel does not support
+ * this operation or the request could not be queued.
+ */
+static inline struct dma_async_tx_descriptor *
+dmaengine_prep_dma_pq_val(struct dma_chan *chan, dma_addr_t *pq, dma_addr_t *src,
+			  unsigned int src_cnt, const unsigned char *scf,
+			  size_t len, enum sum_check_flags *pqres, unsigned long flags)
+{
+	if (!chan || !chan->device || !chan->device->device_prep_dma_pq_val)
+		return NULL;
+
+	return chan->device->device_prep_dma_pq_val(chan, pq, src,
+						    src_cnt, scf, len,
+						    pqres, flags);
+}
+
 static inline bool dmaengine_is_metadata_mode_supported(struct dma_chan *chan,
 		enum dma_desc_metadata_mode mode)
 {
@@ -1585,6 +1701,24 @@ __dma_has_cap(enum dma_transaction_type tx_type, dma_cap_mask_t *srcp)
 #define for_each_dma_cap_mask(cap, mask) \
 	for_each_set_bit(cap, mask.bits, DMA_TX_TYPE_END)
 
+/**
+ * dmaengine_prep_dma_interrupt() - Prepare a DMA interrupt descriptor.
+ * @chan: The channel to be used for this descriptor
+ * @flags: DMA engine flags
+ *
+ * Returns a descriptor for an interrupt transaction, or NULL if the
+ * channel does not support DMA_INTERRUPT.
+ */
+static inline struct dma_async_tx_descriptor *
+dmaengine_prep_dma_interrupt(struct dma_chan *chan, unsigned long flags)
+{
+	if (!chan || !chan->device || !chan->device->device_prep_dma_interrupt ||
+	    !dma_has_cap(DMA_INTERRUPT, chan->device->cap_mask))
+		return NULL;
+
+	return chan->device->device_prep_dma_interrupt(chan, flags);
+}
+
 /**
  * dma_async_issue_pending - flush pending transactions to HW
  * @chan: target DMA channel

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v2 04/12] dmaengine: add dmaengine_is_*_aligned() helpers for DMA consumers
  2026-09-23 16:19 [PATCH v2 00/12] dmaengine: Add dmaengine API to avoid call DMA Engine callback directly Frank.Li
                   ` (2 preceding siblings ...)
  2026-09-23 16:19 ` [PATCH v2 03/12] dmaengine: add dmaengine_prep_dma_(pq|pq_val|interrupt|xor)() API Frank.Li
@ 2026-09-23 16:19 ` Frank.Li
  2026-09-23 16:19 ` [PATCH v2 05/12] dmaengine: add dmaengine_get_copy_align() and related alignment getter helpers Frank.Li
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: Frank.Li @ 2026-09-23 16:19 UTC (permalink / raw)
  To: Vinod Koul, Frank Li, Dan Williams, Herbert Xu, David S. Miller,
	Jon Mason, Dave Jiang, Allen Hubbe
  Cc: dmaengine, linux-kernel, linux-crypto, imx, Frank Li, ntb

From: Frank Li <Frank.Li@nxp.com>

DMA engine consumers typically hold a struct dma_chan pointer and should
not need to reach into struct dma_device directly to check alignment
requirements.  Add dmaengine_is_copy_aligned(), dmaengine_is_xor_aligned(),
dmaengine_is_pq_aligned() and dmaengine_is_fill_aligned() as channel-based
counterparts to the existing is_dma_*_aligned() family.

Each wrapper calls dmaengine_check_align() directly with the alignment
value from chan->device, keeping struct dma_device opaque to consumers.

Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
 include/linux/dmaengine.h | 64 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 64 insertions(+)

diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index 6a187136f9493..1efb04e137673 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -1537,6 +1537,70 @@ static inline bool is_dma_fill_aligned(struct dma_device *dev, size_t off1,
 	return dmaengine_check_align(dev->fill_align, off1, off2, len);
 }
 
+/**
+ * dmaengine_is_copy_aligned - test copy alignment
+ * @chan: DMA channel
+ * @off1: first buffer offset
+ * @off2: second buffer offset
+ * @len: transfer length
+ *
+ * Return true if off1, off2 and len satisfy the copy alignment requirement of
+ * the DMA channel, false otherwise.
+ */
+static inline bool dmaengine_is_copy_aligned(struct dma_chan *chan, size_t off1,
+					     size_t off2, size_t len)
+{
+	return dmaengine_check_align(chan->device->copy_align, off1, off2, len);
+}
+
+/**
+ * dmaengine_is_xor_aligned - test xor alignment
+ * @chan: DMA channel
+ * @off1: first buffer offset
+ * @off2: second buffer offset
+ * @len: transfer length
+ *
+ * Return true if off1, off2 and len satisfy the xor alignment requirement of
+ * the DMA channel, false otherwise.
+ */
+static inline bool dmaengine_is_xor_aligned(struct dma_chan *chan, size_t off1,
+					    size_t off2, size_t len)
+{
+	return dmaengine_check_align(chan->device->xor_align, off1, off2, len);
+}
+
+/**
+ * dmaengine_is_pq_aligned - test pq alignment
+ * @chan: DMA channel
+ * @off1: first buffer offset
+ * @off2: second buffer offset
+ * @len: transfer length
+ *
+ * Return true if off1, off2 and len satisfy the pq alignment requirement of
+ * the DMA channel, false otherwise.
+ */
+static inline bool dmaengine_is_pq_aligned(struct dma_chan *chan, size_t off1,
+					   size_t off2, size_t len)
+{
+	return dmaengine_check_align(chan->device->pq_align, off1, off2, len);
+}
+
+/**
+ * dmaengine_is_fill_aligned - test fill alignment
+ * @chan: DMA channel
+ * @off1: first buffer offset
+ * @off2: second buffer offset
+ * @len: transfer length
+ *
+ * Return true if off1, off2 and len satisfy the fill alignment requirement of
+ * the DMA channel, false otherwise.
+ */
+static inline bool dmaengine_is_fill_aligned(struct dma_chan *chan, size_t off1,
+					     size_t off2, size_t len)
+{
+	return dmaengine_check_align(chan->device->fill_align, off1, off2, len);
+}
+
 static inline void
 dma_set_maxpq(struct dma_device *dma, int maxpq, int has_pq_continue)
 {

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v2 05/12] dmaengine: add dmaengine_get_copy_align() and related alignment getter helpers
  2026-09-23 16:19 [PATCH v2 00/12] dmaengine: Add dmaengine API to avoid call DMA Engine callback directly Frank.Li
                   ` (3 preceding siblings ...)
  2026-09-23 16:19 ` [PATCH v2 04/12] dmaengine: add dmaengine_is_*_aligned() helpers for DMA consumers Frank.Li
@ 2026-09-23 16:19 ` Frank.Li
  2026-09-23 16:19 ` [PATCH v2 06/12] dmaengine: add dmaengine_get_cap_mask() and dmaengine_has_cap() helpers Frank.Li
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: Frank.Li @ 2026-09-23 16:19 UTC (permalink / raw)
  To: Vinod Koul, Frank Li, Dan Williams, Herbert Xu, David S. Miller,
	Jon Mason, Dave Jiang, Allen Hubbe
  Cc: dmaengine, linux-kernel, linux-crypto, imx, Frank Li, ntb

From: Frank Li <Frank.Li@nxp.com>

Add dmaengine_get_copy_align(), dmaengine_get_xor_align(),
dmaengine_get_pq_align(), and dmaengine_get_fill_align() inline
helpers to retrieve the alignment requirement of a DMA channel as
a power-of-2 exponent.

These complement the existing dmaengine_is_*_aligned() test helpers
by providing direct access to the alignment value, which is useful
when callers need to propagate or compare alignment constraints.

Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
 include/linux/dmaengine.h | 48 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 48 insertions(+)

diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index 1efb04e137673..615eeb708dcda 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -1537,6 +1537,54 @@ static inline bool is_dma_fill_aligned(struct dma_device *dev, size_t off1,
 	return dmaengine_check_align(dev->fill_align, off1, off2, len);
 }
 
+/**
+ * dmaengine_get_copy_align - get copy alignment requirement of a DMA channel
+ * @chan: DMA channel
+ *
+ * Return the copy alignment requirement of @chan as a power-of-2 exponent.
+ */
+static inline enum dmaengine_alignment
+dmaengine_get_copy_align(struct dma_chan *chan)
+{
+	return chan->device->copy_align;
+}
+
+/**
+ * dmaengine_get_xor_align - get xor alignment requirement of a DMA channel
+ * @chan: DMA channel
+ *
+ * Return the xor alignment requirement of @chan as a power-of-2 exponent.
+ */
+static inline enum dmaengine_alignment
+dmaengine_get_xor_align(struct dma_chan *chan)
+{
+	return chan->device->xor_align;
+}
+
+/**
+ * dmaengine_get_pq_align - get pq alignment requirement of a DMA channel
+ * @chan: DMA channel
+ *
+ * Return the pq alignment requirement of @chan as a power-of-2 exponent.
+ */
+static inline enum dmaengine_alignment
+dmaengine_get_pq_align(struct dma_chan *chan)
+{
+	return chan->device->pq_align;
+}
+
+/**
+ * dmaengine_get_fill_align - get fill alignment requirement of a DMA channel
+ * @chan: DMA channel
+ *
+ * Return the fill alignment requirement of @chan as a power-of-2 exponent.
+ */
+static inline enum dmaengine_alignment
+dmaengine_get_fill_align(struct dma_chan *chan)
+{
+	return chan->device->fill_align;
+}
+
 /**
  * dmaengine_is_copy_aligned - test copy alignment
  * @chan: DMA channel

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v2 06/12] dmaengine: add dmaengine_get_cap_mask() and dmaengine_has_cap() helpers
  2026-09-23 16:19 [PATCH v2 00/12] dmaengine: Add dmaengine API to avoid call DMA Engine callback directly Frank.Li
                   ` (4 preceding siblings ...)
  2026-09-23 16:19 ` [PATCH v2 05/12] dmaengine: add dmaengine_get_copy_align() and related alignment getter helpers Frank.Li
@ 2026-09-23 16:19 ` Frank.Li
  2026-09-23 16:19 ` [PATCH v2 07/12] dmaengine: add dmaengine_get_max_xor() helper Frank.Li
                   ` (6 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: Frank.Li @ 2026-09-23 16:19 UTC (permalink / raw)
  To: Vinod Koul, Frank Li, Dan Williams, Herbert Xu, David S. Miller,
	Jon Mason, Dave Jiang, Allen Hubbe
  Cc: dmaengine, linux-kernel, linux-crypto, imx, Frank Li, ntb

From: Frank Li <Frank.Li@nxp.com>

Add two new inline helpers to query DMA channel capabilities without
directly accessing the internal dma_device pointer:

  dmaengine_get_cap_mask(chan) - returns a const pointer to the
    capability mask of the DMA device backing the channel.

  dmaengine_has_cap(chan, tx_type) - returns true if the channel
    supports the given transaction type.

These complement the existing dma_has_cap() macro which operates on
a dma_cap_mask_t directly.

Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
 include/linux/dmaengine.h | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index 615eeb708dcda..7fce44bd7c049 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -1585,6 +1585,18 @@ dmaengine_get_fill_align(struct dma_chan *chan)
 	return chan->device->fill_align;
 }
 
+/**
+ * dmaengine_get_cap_mask - get capability mask of a DMA channel
+ * @chan: DMA channel
+ *
+ * Return a pointer to the capability mask of the DMA device backing @chan.
+ */
+static inline const dma_cap_mask_t *
+dmaengine_get_cap_mask(struct dma_chan *chan)
+{
+	return &chan->device->cap_mask;
+}
+
 /**
  * dmaengine_is_copy_aligned - test copy alignment
  * @chan: DMA channel
@@ -1810,6 +1822,19 @@ __dma_has_cap(enum dma_transaction_type tx_type, dma_cap_mask_t *srcp)
 	return test_bit(tx_type, srcp->bits);
 }
 
+/**
+ * dmaengine_has_cap - test whether a DMA channel supports a transaction type
+ * @chan: DMA channel
+ * @tx_type: transaction type to test
+ *
+ * Return true if @chan supports @tx_type, false otherwise.
+ */
+static inline bool
+dmaengine_has_cap(struct dma_chan *chan, enum dma_transaction_type tx_type)
+{
+	return dma_has_cap(tx_type, chan->device->cap_mask);
+}
+
 #define for_each_dma_cap_mask(cap, mask) \
 	for_each_set_bit(cap, mask.bits, DMA_TX_TYPE_END)
 

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v2 07/12] dmaengine: add dmaengine_get_max_xor() helper
  2026-09-23 16:19 [PATCH v2 00/12] dmaengine: Add dmaengine API to avoid call DMA Engine callback directly Frank.Li
                   ` (5 preceding siblings ...)
  2026-09-23 16:19 ` [PATCH v2 06/12] dmaengine: add dmaengine_get_cap_mask() and dmaengine_has_cap() helpers Frank.Li
@ 2026-09-23 16:19 ` Frank.Li
  2026-09-23 16:19 ` [PATCH v2 08/12] dmaengine: change dmaengine_get_unmap_data() first arg to dma_chan Frank.Li
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: Frank.Li @ 2026-09-23 16:19 UTC (permalink / raw)
  To: Vinod Koul, Frank Li, Dan Williams, Herbert Xu, David S. Miller,
	Jon Mason, Dave Jiang, Allen Hubbe
  Cc: dmaengine, linux-kernel, linux-crypto, imx, Frank Li, ntb

From: Frank Li <Frank.Li@nxp.com>

Add a new inline helper dmaengine_get_max_xor() that returns the maximum
number of XOR source buffers supported by the DMA channel's device.
Returns 0 if the channel is NULL or does not support XOR operations.

Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
 include/linux/dmaengine.h | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index 7fce44bd7c049..a4c9eef369cb4 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -1232,6 +1232,21 @@ static inline struct dma_async_tx_descriptor *dmaengine_prep_dma_memcpy(
 						    len, flags);
 }
 
+/**
+ * dmaengine_get_max_xor - get the maximum number of XOR sources for a channel
+ * @chan: DMA channel
+ *
+ * Returns the maximum number of source buffers supported by the XOR engine
+ * behind @chan, or 0 if the channel does not support XOR operations.
+ */
+static inline unsigned int dmaengine_get_max_xor(struct dma_chan *chan)
+{
+	if (!chan || !chan->device)
+		return 0;
+
+	return chan->device->max_xor;
+}
+
 /**
  * dmaengine_prep_dma_xor - prepare a DMA XOR operation
  * @chan: the channel to use for this operation

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v2 08/12] dmaengine: change dmaengine_get_unmap_data() first arg to dma_chan
  2026-09-23 16:19 [PATCH v2 00/12] dmaengine: Add dmaengine API to avoid call DMA Engine callback directly Frank.Li
                   ` (6 preceding siblings ...)
  2026-09-23 16:19 ` [PATCH v2 07/12] dmaengine: add dmaengine_get_max_xor() helper Frank.Li
@ 2026-09-23 16:19 ` Frank.Li
  2026-09-23 16:32   ` sashiko-bot
  2026-09-23 16:19 ` [PATCH v2 09/12] dmaengine: replace dma_maxqp() with dmaengine_maxpq() taking struct dma_chan * Frank.Li
                   ` (4 subsequent siblings)
  12 siblings, 1 reply; 17+ messages in thread
From: Frank.Li @ 2026-09-23 16:19 UTC (permalink / raw)
  To: Vinod Koul, Frank Li, Dan Williams, Herbert Xu, David S. Miller,
	Jon Mason, Dave Jiang, Allen Hubbe
  Cc: dmaengine, linux-kernel, linux-crypto, imx, Frank Li, ntb

From: Frank Li <Frank.Li@nxp.com>

Replace the struct device *dev argument with struct dma_chan *chan so
callers do not need to reach into the dma_device internals to obtain
the device pointer.  The implementation now derives the device via
dmaengine_get_dma_device(chan), which correctly handles the per-channel
IOMMU mapping case.

Prepare to make dma_device private and make dmaengine API consistent.

Acked-by: Dave Jiang <dave.jiang@intel.com>
Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
V2 change collect Dave Jiang ack tags
v1 version at
https://lore.kernel.org/imx/b40fa0d7-fbd0-4ee8-b99c-781d08c18838@intel.com/T/#t
---
 crypto/async_tx/async_memcpy.c      | 4 ++--
 crypto/async_tx/async_pq.c          | 8 ++++----
 crypto/async_tx/async_raid6_recov.c | 8 ++++----
 crypto/async_tx/async_xor.c         | 8 ++++----
 drivers/dma/dmaengine.c             | 4 ++--
 drivers/dma/dmatest.c               | 2 +-
 drivers/dma/mv_xor.c                | 4 ++--
 drivers/ntb/ntb_transport.c         | 4 ++--
 drivers/ntb/test/ntb_perf.c         | 2 +-
 include/linux/dmaengine.h           | 4 ++--
 10 files changed, 24 insertions(+), 24 deletions(-)

diff --git a/crypto/async_tx/async_memcpy.c b/crypto/async_tx/async_memcpy.c
index 53277271f063a..49ee66759c7e9 100644
--- a/crypto/async_tx/async_memcpy.c
+++ b/crypto/async_tx/async_memcpy.c
@@ -39,8 +39,8 @@ async_memcpy(struct page *dest, struct page *src, unsigned int dest_offset,
 	struct dma_async_tx_descriptor *tx = NULL;
 	struct dmaengine_unmap_data *unmap = NULL;
 
-	if (device)
-		unmap = dmaengine_get_unmap_data(device->dev, 2, GFP_NOWAIT);
+	if (chan)
+		unmap = dmaengine_get_unmap_data(chan, 2, GFP_NOWAIT);
 
 	if (unmap && is_dma_copy_aligned(device, src_offset, dest_offset, len)) {
 		unsigned long dma_prep_flags = 0;
diff --git a/crypto/async_tx/async_pq.c b/crypto/async_tx/async_pq.c
index 3a7fd90556501..580936eecba1b 100644
--- a/crypto/async_tx/async_pq.c
+++ b/crypto/async_tx/async_pq.c
@@ -187,8 +187,8 @@ async_gen_syndrome(struct page **blocks, unsigned int *offsets, int disks,
 
 	BUG_ON(disks > MAX_DISKS || !(P(blocks, disks) || Q(blocks, disks)));
 
-	if (device)
-		unmap = dmaengine_get_unmap_data(device->dev, disks, GFP_NOWAIT);
+	if (chan)
+		unmap = dmaengine_get_unmap_data(chan, disks, GFP_NOWAIT);
 
 	/* XORing P/Q is only implemented in software */
 	if (unmap && !(submit->flags & ASYNC_TX_PQ_XOR_DST) &&
@@ -310,8 +310,8 @@ async_syndrome_val(struct page **blocks, unsigned int *offsets, int disks,
 
 	BUG_ON(disks < 4 || disks > MAX_DISKS);
 
-	if (device)
-		unmap = dmaengine_get_unmap_data(device->dev, disks, GFP_NOWAIT);
+	if (chan)
+		unmap = dmaengine_get_unmap_data(chan, disks, GFP_NOWAIT);
 
 	if (unmap && disks <= dma_maxpq(device, 0) &&
 	    is_dma_pq_aligned_offs(device, offsets, disks, len)) {
diff --git a/crypto/async_tx/async_raid6_recov.c b/crypto/async_tx/async_raid6_recov.c
index ed5c5eb126990..4f223fa36c706 100644
--- a/crypto/async_tx/async_raid6_recov.c
+++ b/crypto/async_tx/async_raid6_recov.c
@@ -28,8 +28,8 @@ async_sum_product(struct page *dest, unsigned int d_off,
 	u8 ax, bx;
 	u8 *a, *b, *c;
 
-	if (dma)
-		unmap = dmaengine_get_unmap_data(dma->dev, 3, GFP_NOWAIT);
+	if (chan)
+		unmap = dmaengine_get_unmap_data(chan, 3, GFP_NOWAIT);
 
 	if (unmap) {
 		struct device *dev = dmaengine_get_dma_device(chan);
@@ -96,8 +96,8 @@ async_mult(struct page *dest, unsigned int d_off, struct page *src,
 	const u8 *qmul; /* Q multiplier table */
 	u8 *d, *s;
 
-	if (dma)
-		unmap = dmaengine_get_unmap_data(dma->dev, 3, GFP_NOWAIT);
+	if (chan)
+		unmap = dmaengine_get_unmap_data(chan, 3, GFP_NOWAIT);
 
 	if (unmap) {
 		dma_addr_t dma_dest[2];
diff --git a/crypto/async_tx/async_xor.c b/crypto/async_tx/async_xor.c
index 06c48e8cce834..0fb29da2235cd 100644
--- a/crypto/async_tx/async_xor.c
+++ b/crypto/async_tx/async_xor.c
@@ -178,8 +178,8 @@ async_xor_offs(struct page *dest, unsigned int offset,
 
 	BUG_ON(src_cnt <= 1);
 
-	if (device)
-		unmap = dmaengine_get_unmap_data(device->dev, src_cnt+1, GFP_NOWAIT);
+	if (chan)
+		unmap = dmaengine_get_unmap_data(chan, src_cnt + 1, GFP_NOWAIT);
 
 	if (unmap && dma_xor_aligned_offsets(device, offset,
 				src_offs, src_cnt, len)) {
@@ -311,8 +311,8 @@ async_xor_val_offs(struct page *dest, unsigned int offset,
 
 	BUG_ON(src_cnt <= 1);
 
-	if (device)
-		unmap = dmaengine_get_unmap_data(device->dev, src_cnt, GFP_NOWAIT);
+	if (chan)
+		unmap = dmaengine_get_unmap_data(chan, src_cnt, GFP_NOWAIT);
 
 	if (unmap && src_cnt <= device->max_xor &&
 	    dma_xor_aligned_offsets(device, offset, src_offs, src_cnt, len)) {
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
index cc1c0a7c9f33d..4585ebcd2e8cd 100644
--- a/drivers/dma/dmaengine.c
+++ b/drivers/dma/dmaengine.c
@@ -1474,7 +1474,7 @@ static int __init dmaengine_init_unmap_pool(void)
 }
 
 struct dmaengine_unmap_data *
-dmaengine_get_unmap_data(struct device *dev, int nr, gfp_t flags)
+dmaengine_get_unmap_data(struct dma_chan *chan, int nr, gfp_t flags)
 {
 	struct dmaengine_unmap_data *unmap;
 
@@ -1484,7 +1484,7 @@ dmaengine_get_unmap_data(struct device *dev, int nr, gfp_t flags)
 
 	memset(unmap, 0, sizeof(*unmap));
 	kref_init(&unmap->kref);
-	unmap->dev = dev;
+	unmap->dev = dmaengine_get_dma_device(chan);
 	unmap->map_cnt = nr;
 
 	return unmap;
diff --git a/drivers/dma/dmatest.c b/drivers/dma/dmatest.c
index 2ae3469397f37..043bb065dd68a 100644
--- a/drivers/dma/dmatest.c
+++ b/drivers/dma/dmatest.c
@@ -748,7 +748,7 @@ static int dmatest_func(void *data)
 			filltime = ktime_add(filltime, diff);
 		}
 
-		um = dmaengine_get_unmap_data(dma_dev, src->cnt + dst->cnt,
+		um = dmaengine_get_unmap_data(chan, src->cnt + dst->cnt,
 					      GFP_KERNEL);
 		if (!um) {
 			failed_tests++;
diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c
index c4e0dce3ca64e..dec01b6264d7a 100644
--- a/drivers/dma/mv_xor.c
+++ b/drivers/dma/mv_xor.c
@@ -794,7 +794,7 @@ static int mv_chan_memcpy_self_test(struct mv_xor_chan *mv_chan)
 		goto out;
 	}
 
-	unmap = dmaengine_get_unmap_data(dma_chan->device->dev, 2, GFP_KERNEL);
+	unmap = dmaengine_get_unmap_data(dma_chan, 2, GFP_KERNEL);
 	if (!unmap) {
 		err = -ENOMEM;
 		goto free_resources;
@@ -927,7 +927,7 @@ mv_chan_xor_self_test(struct mv_xor_chan *mv_chan)
 		goto out;
 	}
 
-	unmap = dmaengine_get_unmap_data(dma_chan->device->dev, src_count + 1,
+	unmap = dmaengine_get_unmap_data(dma_chan, src_count + 1,
 					 GFP_KERNEL);
 	if (!unmap) {
 		err = -ENOMEM;
diff --git a/drivers/ntb/ntb_transport.c b/drivers/ntb/ntb_transport.c
index f9caa1a653c5b..e1cb55890d72b 100644
--- a/drivers/ntb/ntb_transport.c
+++ b/drivers/ntb/ntb_transport.c
@@ -1532,7 +1532,7 @@ static int ntb_async_rx_submit(struct ntb_queue_entry *entry, void *offset)
 	if (!is_dma_copy_aligned(device, pay_off, buff_off, len))
 		goto err;
 
-	unmap = dmaengine_get_unmap_data(device->dev, 2, GFP_NOWAIT);
+	unmap = dmaengine_get_unmap_data(chan, 2, GFP_NOWAIT);
 	if (!unmap)
 		goto err;
 
@@ -1872,7 +1872,7 @@ static int ntb_async_tx_submit(struct ntb_transport_qp *qp,
 	if (!is_dma_copy_aligned(device, buff_off, dest_off, len))
 		goto err;
 
-	unmap = dmaengine_get_unmap_data(device->dev, 1, GFP_NOWAIT);
+	unmap = dmaengine_get_unmap_data(chan, 1, GFP_NOWAIT);
 	if (!unmap)
 		goto err;
 
diff --git a/drivers/ntb/test/ntb_perf.c b/drivers/ntb/test/ntb_perf.c
index dfd175f79e8f0..5fea36432ba92 100644
--- a/drivers/ntb/test/ntb_perf.c
+++ b/drivers/ntb/test/ntb_perf.c
@@ -809,7 +809,7 @@ static int perf_copy_chunk(struct perf_thread *pthr,
 	dst_vaddr = dst;
 	dst_dma_addr = peer->dma_dst_addr + (dst_vaddr - vbase);
 
-	unmap = dmaengine_get_unmap_data(dma_dev, 1, GFP_NOWAIT);
+	unmap = dmaengine_get_unmap_data(pthr->dma_chan, 1, GFP_NOWAIT);
 	if (!unmap)
 		return -ENOMEM;
 
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index a4c9eef369cb4..63f40b8fd3009 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -656,7 +656,7 @@ static inline void dma_set_unmap(struct dma_async_tx_descriptor *tx,
 }
 
 struct dmaengine_unmap_data *
-dmaengine_get_unmap_data(struct device *dev, int nr, gfp_t flags);
+dmaengine_get_unmap_data(struct dma_chan *chan, int nr, gfp_t flags);
 void dmaengine_unmap_put(struct dmaengine_unmap_data *unmap);
 #else
 static inline void dma_set_unmap(struct dma_async_tx_descriptor *tx,
@@ -664,7 +664,7 @@ static inline void dma_set_unmap(struct dma_async_tx_descriptor *tx,
 {
 }
 static inline struct dmaengine_unmap_data *
-dmaengine_get_unmap_data(struct device *dev, int nr, gfp_t flags)
+dmaengine_get_unmap_data(struct dma_chan *chan, int nr, gfp_t flags)
 {
 	return NULL;
 }

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v2 09/12] dmaengine: replace dma_maxqp() with dmaengine_maxpq() taking struct dma_chan *
  2026-09-23 16:19 [PATCH v2 00/12] dmaengine: Add dmaengine API to avoid call DMA Engine callback directly Frank.Li
                   ` (7 preceding siblings ...)
  2026-09-23 16:19 ` [PATCH v2 08/12] dmaengine: change dmaengine_get_unmap_data() first arg to dma_chan Frank.Li
@ 2026-09-23 16:19 ` Frank.Li
  2026-09-23 16:28   ` sashiko-bot
  2026-09-23 16:19 ` [PATCH v2 10/12] async_tx: use dmaengine_prep_dma_(pq|pq_val|interrupt|xor) instead of direct callback Frank.Li
                   ` (3 subsequent siblings)
  12 siblings, 1 reply; 17+ messages in thread
From: Frank.Li @ 2026-09-23 16:19 UTC (permalink / raw)
  To: Vinod Koul, Frank Li, Dan Williams, Herbert Xu, David S. Miller,
	Jon Mason, Dave Jiang, Allen Hubbe
  Cc: dmaengine, linux-kernel, linux-crypto, imx, Frank Li, ntb

From: Frank Li <Frank.Li@nxp.com>

Replace dma_maxpq() with  dmaengine_maxpq(chan, flags) as a channel-based
API, consistent with the convention of other dmaengine_*() helpers that
take struct dma_chan * rather than struct dma_device *.

Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
 crypto/async_tx/async_pq.c | 8 ++++----
 drivers/dma/dmatest.c      | 2 +-
 include/linux/dmaengine.h  | 6 ++++--
 3 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/crypto/async_tx/async_pq.c b/crypto/async_tx/async_pq.c
index 580936eecba1b..5f62f2edefe58 100644
--- a/crypto/async_tx/async_pq.c
+++ b/crypto/async_tx/async_pq.c
@@ -51,7 +51,7 @@ do_async_gen_syndrome(struct dma_chan *chan,
 
 	while (src_cnt > 0) {
 		submit->flags = flags_orig;
-		pq_src_cnt = min(src_cnt, dma_maxpq(dma, dma_flags));
+		pq_src_cnt = min(src_cnt, dmaengine_maxpq(chan, dma_flags));
 		/* if we are submitting additional pqs, leave the chain open,
 		 * clear the callback parameters, and leave the destination
 		 * buffers mapped
@@ -192,8 +192,8 @@ async_gen_syndrome(struct page **blocks, unsigned int *offsets, int disks,
 
 	/* XORing P/Q is only implemented in software */
 	if (unmap && !(submit->flags & ASYNC_TX_PQ_XOR_DST) &&
-	    (src_cnt <= dma_maxpq(device, 0) ||
-	     dma_maxpq(device, DMA_PREP_CONTINUE) > 0) &&
+	    (src_cnt <= dmaengine_maxpq(chan, 0) ||
+	     dmaengine_maxpq(chan, DMA_PREP_CONTINUE) > 0) &&
 	    is_dma_pq_aligned_offs(device, offsets, disks, len)) {
 		struct dma_async_tx_descriptor *tx;
 		struct device *dma_dev = dmaengine_get_dma_device(chan);
@@ -313,7 +313,7 @@ async_syndrome_val(struct page **blocks, unsigned int *offsets, int disks,
 	if (chan)
 		unmap = dmaengine_get_unmap_data(chan, disks, GFP_NOWAIT);
 
-	if (unmap && disks <= dma_maxpq(device, 0) &&
+	if (unmap && disks <= dmaengine_maxpq(chan, 0) &&
 	    is_dma_pq_aligned_offs(device, offsets, disks, len)) {
 		struct device *dev = dmaengine_get_dma_device(chan);
 		dma_addr_t pq[2];
diff --git a/drivers/dma/dmatest.c b/drivers/dma/dmatest.c
index 043bb065dd68a..01ab33580da81 100644
--- a/drivers/dma/dmatest.c
+++ b/drivers/dma/dmatest.c
@@ -636,7 +636,7 @@ static int dmatest_func(void *data)
 						params->alignment;
 	} else if (thread->type == DMA_PQ) {
 		/* force odd to ensure dst = src */
-		src->cnt = min_odd(params->pq_sources | 1, dma_maxpq(dev, 0));
+		src->cnt = min_odd(params->pq_sources | 1, dmaengine_maxpq(chan, 0));
 		dst->cnt = 2;
 		align = params->alignment < 0 ? dev->pq_align :
 						params->alignment;
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index 63f40b8fd3009..34fd3bb32f86e 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -1706,7 +1706,7 @@ static inline unsigned short dma_dev_to_maxpq(struct dma_device *dma)
 	return dma->max_pq & ~DMA_HAS_PQ_CONTINUE;
 }
 
-/* dma_maxpq - reduce maxpq in the face of continued operations
+/* dmaengine_maxpq - reduce maxpq in the face of continued operations
  * @dma - dma device with PQ capability
  * @flags - to check if DMA_PREP_CONTINUE and DMA_PREP_PQ_DISABLE_P are set
  *
@@ -1719,8 +1719,10 @@ static inline unsigned short dma_dev_to_maxpq(struct dma_device *dma)
  * In the case where P is disabled we only need 1 extra source:
  * 1/ {01} * Q : use Q to continue Q' calculation
  */
-static inline int dma_maxpq(struct dma_device *dma, enum dma_ctrl_flags flags)
+static inline int dmaengine_maxpq(struct dma_chan *chan, enum dma_ctrl_flags flags)
 {
+	struct dma_device *dma = chan->device;
+
 	if (dma_dev_has_pq_continue(dma) || !dmaf_continue(flags))
 		return dma_dev_to_maxpq(dma);
 	if (dmaf_p_disabled_continue(flags))

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v2 10/12] async_tx: use dmaengine_prep_dma_(pq|pq_val|interrupt|xor) instead of direct callback
  2026-09-23 16:19 [PATCH v2 00/12] dmaengine: Add dmaengine API to avoid call DMA Engine callback directly Frank.Li
                   ` (8 preceding siblings ...)
  2026-09-23 16:19 ` [PATCH v2 09/12] dmaengine: replace dma_maxqp() with dmaengine_maxpq() taking struct dma_chan * Frank.Li
@ 2026-09-23 16:19 ` Frank.Li
  2026-09-23 16:19 ` [PATCH v2 11/12] async_tx: convert to dmaengine_is_*_aligned() helpers Frank.Li
                   ` (2 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: Frank.Li @ 2026-09-23 16:19 UTC (permalink / raw)
  To: Vinod Koul, Frank Li, Dan Williams, Herbert Xu, David S. Miller,
	Jon Mason, Dave Jiang, Allen Hubbe
  Cc: dmaengine, linux-kernel, linux-crypto, imx, Frank Li, ntb

From: Frank Li <Frank.Li@nxp.com>

Replace direct device_prep_dma_(pq|pq_val|interrupt|xor) callback
invocations with dmaengine_prep_dma_(pq|pq_val|interrupt|xor) API,
consistent with how other dmaengine operations use their API.

Assisted-by: LLM
Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
 crypto/async_tx/async_pq.c          | 23 +++++++++++------------
 crypto/async_tx/async_raid6_recov.c | 10 ++++------
 crypto/async_tx/async_tx.c          | 13 ++-----------
 crypto/async_tx/async_xor.c         | 19 ++++++++-----------
 4 files changed, 25 insertions(+), 40 deletions(-)

diff --git a/crypto/async_tx/async_pq.c b/crypto/async_tx/async_pq.c
index 5f62f2edefe58..6ccc1073c5ace 100644
--- a/crypto/async_tx/async_pq.c
+++ b/crypto/async_tx/async_pq.c
@@ -40,7 +40,6 @@ do_async_gen_syndrome(struct dma_chan *chan,
 		      struct async_submit_ctl *submit)
 {
 	struct dma_async_tx_descriptor *tx = NULL;
-	struct dma_device *dma = chan->device;
 	enum async_tx_flags flags_orig = submit->flags;
 	dma_async_tx_callback cb_fn_orig = submit->cb_fn;
 	dma_async_tx_callback cb_param_orig = submit->cb_param;
@@ -76,11 +75,11 @@ do_async_gen_syndrome(struct dma_chan *chan,
 		for (;;) {
 			dma_dest[0] = unmap->addr[disks - 2];
 			dma_dest[1] = unmap->addr[disks - 1];
-			tx = dma->device_prep_dma_pq(chan, dma_dest,
-						     &unmap->addr[src_off],
-						     pq_src_cnt,
-						     &scfs[src_off], unmap->len,
-						     dma_flags);
+			tx = dmaengine_prep_dma_pq(chan, dma_dest,
+						   &unmap->addr[src_off],
+						   pq_src_cnt,
+						   &scfs[src_off], unmap->len,
+						   dma_flags);
 			if (likely(tx))
 				break;
 			async_tx_quiesce(&submit->depend_tx);
@@ -358,12 +357,12 @@ async_syndrome_val(struct page **blocks, unsigned int *offsets, int disks,
 		if (submit->flags & ASYNC_TX_FENCE)
 			dma_flags |= DMA_PREP_FENCE;
 		for (;;) {
-			tx = device->device_prep_dma_pq_val(chan, pq,
-							    unmap->addr,
-							    src_cnt,
-							    coefs,
-							    len, pqres,
-							    dma_flags);
+			tx = dmaengine_prep_dma_pq_val(chan, pq,
+						       unmap->addr,
+						       src_cnt,
+						       coefs,
+						       len, pqres,
+						       dma_flags);
 			if (likely(tx))
 				break;
 			async_tx_quiesce(&submit->depend_tx);
diff --git a/crypto/async_tx/async_raid6_recov.c b/crypto/async_tx/async_raid6_recov.c
index 4f223fa36c706..0e3ae945154fc 100644
--- a/crypto/async_tx/async_raid6_recov.c
+++ b/crypto/async_tx/async_raid6_recov.c
@@ -22,7 +22,6 @@ async_sum_product(struct page *dest, unsigned int d_off,
 {
 	struct dma_chan *chan = async_tx_find_channel(submit, DMA_PQ,
 						      &dest, 1, srcs, 2, len);
-	struct dma_device *dma = chan ? chan->device : NULL;
 	struct dmaengine_unmap_data *unmap = NULL;
 	const u8 *amul, *bmul;
 	u8 ax, bx;
@@ -52,8 +51,8 @@ async_sum_product(struct page *dest, unsigned int d_off,
 		pq[1] = unmap->addr[2];
 
 		unmap->len = len;
-		tx = dma->device_prep_dma_pq(chan, pq, unmap->addr, 2, coef,
-					     len, dma_flags);
+		tx = dmaengine_prep_dma_pq(chan, pq, unmap->addr, 2, coef,
+					   len, dma_flags);
 		if (tx) {
 			dma_set_unmap(tx, unmap);
 			async_tx_submit(chan, tx, submit);
@@ -91,7 +90,6 @@ async_mult(struct page *dest, unsigned int d_off, struct page *src,
 {
 	struct dma_chan *chan = async_tx_find_channel(submit, DMA_PQ,
 						      &dest, 1, &src, 1, len);
-	struct dma_device *dma = chan ? chan->device : NULL;
 	struct dmaengine_unmap_data *unmap = NULL;
 	const u8 *qmul; /* Q multiplier table */
 	u8 *d, *s;
@@ -120,8 +118,8 @@ async_mult(struct page *dest, unsigned int d_off, struct page *src,
 		 * dma_dest[1] and ignores dma_dest[0] as a dest
 		 * due to DMA_PREP_PQ_DISABLE_P
 		 */
-		tx = dma->device_prep_dma_pq(chan, dma_dest, unmap->addr,
-					     1, &coef, len, dma_flags);
+		tx = dmaengine_prep_dma_pq(chan, dma_dest, unmap->addr,
+					   1, &coef, len, dma_flags);
 
 		if (tx) {
 			dma_set_unmap(tx, unmap);
diff --git a/crypto/async_tx/async_tx.c b/crypto/async_tx/async_tx.c
index 01ef830675574..7eba152ecb97b 100644
--- a/crypto/async_tx/async_tx.c
+++ b/crypto/async_tx/async_tx.c
@@ -66,7 +66,6 @@ async_tx_channel_switch(struct dma_async_tx_descriptor *depend_tx,
 			struct dma_async_tx_descriptor *tx)
 {
 	struct dma_chan *chan = depend_tx->chan;
-	struct dma_device *device = chan->device;
 	struct dma_async_tx_descriptor *intr_tx = (void *) ~0;
 
 	/* first check to see if we can still append to depend_tx */
@@ -86,10 +85,7 @@ async_tx_channel_switch(struct dma_async_tx_descriptor *depend_tx,
 	/* see if we can schedule an interrupt
 	 * otherwise poll for completion
 	 */
-	if (dma_has_cap(DMA_INTERRUPT, device->cap_mask))
-		intr_tx = device->device_prep_dma_interrupt(chan, 0);
-	else
-		intr_tx = NULL;
+	intr_tx = dmaengine_prep_dma_interrupt(chan, 0);
 
 	if (intr_tx) {
 		intr_tx->callback = NULL;
@@ -221,21 +217,16 @@ struct dma_async_tx_descriptor *
 async_trigger_callback(struct async_submit_ctl *submit)
 {
 	struct dma_chan *chan;
-	struct dma_device *device;
 	struct dma_async_tx_descriptor *tx;
 	struct dma_async_tx_descriptor *depend_tx = submit->depend_tx;
 
 	if (depend_tx) {
 		chan = depend_tx->chan;
-		device = chan->device;
 
 		/* see if we can schedule an interrupt
 		 * otherwise poll for completion
 		 */
-		if (device && !dma_has_cap(DMA_INTERRUPT, device->cap_mask))
-			device = NULL;
-
-		tx = device ? device->device_prep_dma_interrupt(chan, 0) : NULL;
+		tx = dmaengine_prep_dma_interrupt(chan, 0);
 	} else
 		tx = NULL;
 
diff --git a/crypto/async_tx/async_xor.c b/crypto/async_tx/async_xor.c
index 0fb29da2235cd..3cbe08883085b 100644
--- a/crypto/async_tx/async_xor.c
+++ b/crypto/async_tx/async_xor.c
@@ -62,9 +62,8 @@ do_async_xor(struct dma_chan *chan, struct dmaengine_unmap_data *unmap,
 		tmp = src_list[0];
 		if (src_list > unmap->addr)
 			src_list[0] = dma_dest;
-		tx = dma->device_prep_dma_xor(chan, dma_dest, src_list,
-					      xor_src_cnt, unmap->len,
-					      dma_flags);
+		tx = dmaengine_prep_dma_xor(chan, dma_dest, src_list,
+					    xor_src_cnt, unmap->len, dma_flags);
 
 		if (unlikely(!tx))
 			async_tx_quiesce(&submit->depend_tx);
@@ -72,10 +71,9 @@ do_async_xor(struct dma_chan *chan, struct dmaengine_unmap_data *unmap,
 		/* spin wait for the preceding transactions to complete */
 		while (unlikely(!tx)) {
 			dma_async_issue_pending(chan);
-			tx = dma->device_prep_dma_xor(chan, dma_dest,
-						      src_list,
-						      xor_src_cnt, unmap->len,
-						      dma_flags);
+			tx = dmaengine_prep_dma_xor(chan, dma_dest, src_list,
+						    xor_src_cnt, unmap->len,
+						    dma_flags);
 		}
 		src_list[0] = tmp;
 
@@ -335,15 +333,14 @@ async_xor_val_offs(struct page *dest, unsigned int offset,
 		}
 		unmap->len = len;
 
-		tx = device->device_prep_dma_xor_val(chan, unmap->addr, src_cnt,
-						     len, result,
-						     dma_prep_flags);
+		tx = dmaengine_prep_dma_xor_val(chan, unmap->addr, src_cnt,
+						len, result, dma_prep_flags);
 		if (unlikely(!tx)) {
 			async_tx_quiesce(&submit->depend_tx);
 
 			while (!tx) {
 				dma_async_issue_pending(chan);
-				tx = device->device_prep_dma_xor_val(chan,
+				tx = dmaengine_prep_dma_xor_val(chan,
 					unmap->addr, src_cnt, len, result,
 					dma_prep_flags);
 			}

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v2 11/12] async_tx: convert to dmaengine_is_*_aligned() helpers
  2026-09-23 16:19 [PATCH v2 00/12] dmaengine: Add dmaengine API to avoid call DMA Engine callback directly Frank.Li
                   ` (9 preceding siblings ...)
  2026-09-23 16:19 ` [PATCH v2 10/12] async_tx: use dmaengine_prep_dma_(pq|pq_val|interrupt|xor) instead of direct callback Frank.Li
@ 2026-09-23 16:19 ` Frank.Li
  2026-09-23 16:19 ` [PATCH v2 12/12] async_tx: replace open-coded cap_mask accesses with dmaengine_has_cap() Frank.Li
  2026-10-09 10:14 ` [PATCH v2 00/12] dmaengine: Add dmaengine API to avoid call DMA Engine callback directly Vinod Koul
  12 siblings, 0 replies; 17+ messages in thread
From: Frank.Li @ 2026-09-23 16:19 UTC (permalink / raw)
  To: Vinod Koul, Frank Li, Dan Williams, Herbert Xu, David S. Miller,
	Jon Mason, Dave Jiang, Allen Hubbe
  Cc: dmaengine, linux-kernel, linux-crypto, imx, Frank Li, ntb

From: Frank Li <Frank.Li@nxp.com>

Replace is_dma_{copy,xor,pq}_aligned() calls with the new
dmaengine_is_{copy,xor,pq}_aligned() helpers that take a struct
dma_chan * instead of struct dma_device *. Also update the internal
helpers dma_xor_aligned_offsets() and is_dma_pq_aligned_offs() to
take struct dma_chan * accordingly.

Also use dmaengine_get_max_xor() to get max_xor.

Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
 crypto/async_tx/async_memcpy.c |  3 +--
 crypto/async_tx/async_pq.c     | 12 +++++-------
 crypto/async_tx/async_xor.c    | 23 ++++++++++-------------
 3 files changed, 16 insertions(+), 22 deletions(-)

diff --git a/crypto/async_tx/async_memcpy.c b/crypto/async_tx/async_memcpy.c
index 49ee66759c7e9..972670094be0a 100644
--- a/crypto/async_tx/async_memcpy.c
+++ b/crypto/async_tx/async_memcpy.c
@@ -35,14 +35,13 @@ async_memcpy(struct page *dest, struct page *src, unsigned int dest_offset,
 {
 	struct dma_chan *chan = async_tx_find_channel(submit, DMA_MEMCPY,
 						      &dest, 1, &src, 1, len);
-	struct dma_device *device = chan ? chan->device : NULL;
 	struct dma_async_tx_descriptor *tx = NULL;
 	struct dmaengine_unmap_data *unmap = NULL;
 
 	if (chan)
 		unmap = dmaengine_get_unmap_data(chan, 2, GFP_NOWAIT);
 
-	if (unmap && is_dma_copy_aligned(device, src_offset, dest_offset, len)) {
+	if (unmap && dmaengine_is_copy_aligned(chan, src_offset, dest_offset, len)) {
 		unsigned long dma_prep_flags = 0;
 		struct device *dma_dev =  dmaengine_get_dma_device(chan);
 
diff --git a/crypto/async_tx/async_pq.c b/crypto/async_tx/async_pq.c
index 6ccc1073c5ace..30d6ee676dd44 100644
--- a/crypto/async_tx/async_pq.c
+++ b/crypto/async_tx/async_pq.c
@@ -140,13 +140,13 @@ do_sync_gen_syndrome(struct page **blocks, unsigned int *offsets, int disks,
 }
 
 static inline bool
-is_dma_pq_aligned_offs(struct dma_device *dev, unsigned int *offs,
-				     int src_cnt, size_t len)
+is_dma_pq_aligned_offs(struct dma_chan *chan, unsigned int *offs,
+		       int src_cnt, size_t len)
 {
 	int i;
 
 	for (i = 0; i < src_cnt; i++) {
-		if (!is_dma_pq_aligned(dev, offs[i], 0, len))
+		if (!dmaengine_is_pq_aligned(chan, offs[i], 0, len))
 			return false;
 	}
 	return true;
@@ -181,7 +181,6 @@ async_gen_syndrome(struct page **blocks, unsigned int *offsets, int disks,
 	struct dma_chan *chan = async_tx_find_channel(submit, DMA_PQ,
 						      &P(blocks, disks), 2,
 						      blocks, src_cnt, len);
-	struct dma_device *device = chan ? chan->device : NULL;
 	struct dmaengine_unmap_data *unmap = NULL;
 
 	BUG_ON(disks > MAX_DISKS || !(P(blocks, disks) || Q(blocks, disks)));
@@ -193,7 +192,7 @@ async_gen_syndrome(struct page **blocks, unsigned int *offsets, int disks,
 	if (unmap && !(submit->flags & ASYNC_TX_PQ_XOR_DST) &&
 	    (src_cnt <= dmaengine_maxpq(chan, 0) ||
 	     dmaengine_maxpq(chan, DMA_PREP_CONTINUE) > 0) &&
-	    is_dma_pq_aligned_offs(device, offsets, disks, len)) {
+	    is_dma_pq_aligned_offs(chan, offsets, disks, len)) {
 		struct dma_async_tx_descriptor *tx;
 		struct device *dma_dev = dmaengine_get_dma_device(chan);
 		enum dma_ctrl_flags dma_flags = 0;
@@ -301,7 +300,6 @@ async_syndrome_val(struct page **blocks, unsigned int *offsets, int disks,
 		   unsigned int s_off, struct async_submit_ctl *submit)
 {
 	struct dma_chan *chan = pq_val_chan(submit, blocks, disks, len);
-	struct dma_device *device = chan ? chan->device : NULL;
 	struct dma_async_tx_descriptor *tx;
 	unsigned char coefs[MAX_DISKS];
 	enum dma_ctrl_flags dma_flags = submit->cb_fn ? DMA_PREP_INTERRUPT : 0;
@@ -313,7 +311,7 @@ async_syndrome_val(struct page **blocks, unsigned int *offsets, int disks,
 		unmap = dmaengine_get_unmap_data(chan, disks, GFP_NOWAIT);
 
 	if (unmap && disks <= dmaengine_maxpq(chan, 0) &&
-	    is_dma_pq_aligned_offs(device, offsets, disks, len)) {
+	    is_dma_pq_aligned_offs(chan, offsets, disks, len)) {
 		struct device *dev = dmaengine_get_dma_device(chan);
 		dma_addr_t pq[2];
 		int i, j = 0, src_cnt = 0;
diff --git a/crypto/async_tx/async_xor.c b/crypto/async_tx/async_xor.c
index 3cbe08883085b..cf3eedaf2a75b 100644
--- a/crypto/async_tx/async_xor.c
+++ b/crypto/async_tx/async_xor.c
@@ -23,7 +23,6 @@ static __async_inline struct dma_async_tx_descriptor *
 do_async_xor(struct dma_chan *chan, struct dmaengine_unmap_data *unmap,
 	     struct async_submit_ctl *submit)
 {
-	struct dma_device *dma = chan->device;
 	struct dma_async_tx_descriptor *tx = NULL;
 	dma_async_tx_callback cb_fn_orig = submit->cb_fn;
 	void *cb_param_orig = submit->cb_param;
@@ -38,7 +37,7 @@ do_async_xor(struct dma_chan *chan, struct dmaengine_unmap_data *unmap,
 		dma_addr_t tmp;
 
 		submit->flags = flags_orig;
-		xor_src_cnt = min(src_cnt, (int)dma->max_xor);
+		xor_src_cnt = min_t(int, src_cnt, dmaengine_get_max_xor(chan));
 		/* if we are submitting additional xors, leave the chain open
 		 * and clear the callback parameters
 		 */
@@ -124,19 +123,19 @@ do_sync_xor_offs(struct page *dest, unsigned int offset,
 }
 
 static inline bool
-dma_xor_aligned_offsets(struct dma_device *device, unsigned int offset,
-		unsigned int *src_offs, int src_cnt, int len)
+dma_xor_aligned_offsets(struct dma_chan *chan, unsigned int offset,
+			unsigned int *src_offs, int src_cnt, int len)
 {
 	int i;
 
-	if (!is_dma_xor_aligned(device, offset, 0, len))
+	if (!dmaengine_is_xor_aligned(chan, offset, 0, len))
 		return false;
 
 	if (!src_offs)
 		return true;
 
 	for (i = 0; i < src_cnt; i++) {
-		if (!is_dma_xor_aligned(device, src_offs[i], 0, len))
+		if (!dmaengine_is_xor_aligned(chan, src_offs[i], 0, len))
 			return false;
 	}
 	return true;
@@ -171,7 +170,6 @@ async_xor_offs(struct page *dest, unsigned int offset,
 	struct dma_chan *chan = async_tx_find_channel(submit, DMA_XOR,
 						      &dest, 1, src_list,
 						      src_cnt, len);
-	struct dma_device *device = chan ? chan->device : NULL;
 	struct dmaengine_unmap_data *unmap = NULL;
 
 	BUG_ON(src_cnt <= 1);
@@ -179,8 +177,8 @@ async_xor_offs(struct page *dest, unsigned int offset,
 	if (chan)
 		unmap = dmaengine_get_unmap_data(chan, src_cnt + 1, GFP_NOWAIT);
 
-	if (unmap && dma_xor_aligned_offsets(device, offset,
-				src_offs, src_cnt, len)) {
+	if (unmap && dma_xor_aligned_offsets(chan, offset, src_offs,
+					     src_cnt, len)) {
 		struct device *dma_dev = dmaengine_get_dma_device(chan);
 		struct dma_async_tx_descriptor *tx;
 		int i, j;
@@ -303,7 +301,6 @@ async_xor_val_offs(struct page *dest, unsigned int offset,
 		struct async_submit_ctl *submit)
 {
 	struct dma_chan *chan = xor_val_chan(submit, dest, src_list, src_cnt, len);
-	struct dma_device *device = chan ? chan->device : NULL;
 	struct dma_async_tx_descriptor *tx = NULL;
 	struct dmaengine_unmap_data *unmap = NULL;
 
@@ -312,8 +309,8 @@ async_xor_val_offs(struct page *dest, unsigned int offset,
 	if (chan)
 		unmap = dmaengine_get_unmap_data(chan, src_cnt, GFP_NOWAIT);
 
-	if (unmap && src_cnt <= device->max_xor &&
-	    dma_xor_aligned_offsets(device, offset, src_offs, src_cnt, len)) {
+	if (unmap && src_cnt <= dmaengine_get_max_xor(chan) &&
+	    dma_xor_aligned_offsets(chan, offset, src_offs, src_cnt, len)) {
 		unsigned long dma_prep_flags = 0;
 		struct device *dma_dev = dmaengine_get_dma_device(chan);
 		int i;
@@ -351,7 +348,7 @@ async_xor_val_offs(struct page *dest, unsigned int offset,
 		enum async_tx_flags flags_orig = submit->flags;
 
 		pr_debug("%s: (sync) len: %zu\n", __func__, len);
-		WARN_ONCE(device && src_cnt <= device->max_xor,
+		WARN_ONCE(chan && src_cnt <= dmaengine_get_max_xor(chan),
 			  "%s: no space for dma address conversion\n",
 			  __func__);
 

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v2 12/12] async_tx: replace open-coded cap_mask accesses with dmaengine_has_cap()
  2026-09-23 16:19 [PATCH v2 00/12] dmaengine: Add dmaengine API to avoid call DMA Engine callback directly Frank.Li
                   ` (10 preceding siblings ...)
  2026-09-23 16:19 ` [PATCH v2 11/12] async_tx: convert to dmaengine_is_*_aligned() helpers Frank.Li
@ 2026-09-23 16:19 ` Frank.Li
  2026-10-09 10:14 ` [PATCH v2 00/12] dmaengine: Add dmaengine API to avoid call DMA Engine callback directly Vinod Koul
  12 siblings, 0 replies; 17+ messages in thread
From: Frank.Li @ 2026-09-23 16:19 UTC (permalink / raw)
  To: Vinod Koul, Frank Li, Dan Williams, Herbert Xu, David S. Miller,
	Jon Mason, Dave Jiang, Allen Hubbe
  Cc: dmaengine, linux-kernel, linux-crypto, imx, Frank Li, ntb

From: Frank Li <Frank.Li@nxp.com>

Replace remaining direct accesses to chan->device->cap_mask with the
dmaengine_has_cap() helper which already exists in dmaengine.h.

Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
 crypto/async_tx/async_tx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/crypto/async_tx/async_tx.c b/crypto/async_tx/async_tx.c
index 7eba152ecb97b..5637c95be6b3b 100644
--- a/crypto/async_tx/async_tx.c
+++ b/crypto/async_tx/async_tx.c
@@ -47,7 +47,7 @@ __async_tx_find_channel(struct async_submit_ctl *submit,
 
 	/* see if we can keep the chain on one channel */
 	if (depend_tx &&
-	    dma_has_cap(tx_type, depend_tx->chan->device->cap_mask))
+	    dmaengine_has_cap(depend_tx->chan, tx_type))
 		return depend_tx->chan;
 	return async_dma_find_channel(tx_type);
 }

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 03/12] dmaengine: add dmaengine_prep_dma_(pq|pq_val|interrupt|xor)() API
  2026-09-23 16:19 ` [PATCH v2 03/12] dmaengine: add dmaengine_prep_dma_(pq|pq_val|interrupt|xor)() API Frank.Li
@ 2026-09-23 16:26   ` sashiko-bot
  0 siblings, 0 replies; 17+ messages in thread
From: sashiko-bot @ 2026-09-23 16:26 UTC (permalink / raw)
  To: Frank.Li; +Cc: Frank.Li, imx, dmaengine, vkoul, ntb

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] dmaengine: incorrect enum flag names in dmaengine_prep_dma_pq_val() doc
--

commit 8adba4cfb473c162862987f700f7acf2fd3dceaf
Author: Frank Li <Frank.Li@nxp.com>

dmaengine: add dmaengine_prep_dma_(pq|pq_val|interrupt|xor)() API

This commit adds inline wrapper functions for several DMA engine prep callbacks, 
standardizing them with existing helpers like dmaengine_prep_dma_memcpy(). 
It provides a clean public API that hides direct callback access and adds 
proper NULL-checks.

> diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
> index c3a49a33307c6..6a187136f9493 100644
> --- a/include/linux/dmaengine.h
> +++ b/include/linux/dmaengine.h

[ ... ]

> +/**
> + * dmaengine_prep_dma_pq_val - prepare a DMA PQ validation operation
> + * @chan: the channel to use for this operation
> + * @pq: array of two addresses holding existing P and Q parity buffers
> + * @src: array of source buffer addresses
> + * @src_cnt: number of source buffers
> + * @scf: array of scaling coefficients, one per source buffer
> + * @len: length in bytes of each buffer
> + * @pqres: output flags indicating P and/or Q check results (SUM_CHECK_P_VALID,
> + *         SUM_CHECK_Q_VALID)

[Severity: Low]
Are these the correct enum flag names? The codebase uses SUM_CHECK_P_RESULT 
and SUM_CHECK_Q_RESULT, but this documentation block references 
SUM_CHECK_P_VALID and SUM_CHECK_Q_VALID which do not appear to exist. 
Could this comment be updated to match the actual enum values?

> + * @flags: DMA engine flags (e.g. DMA_PREP_INTERRUPT)
> + *
> + * Prepare a PQ validation transaction.  The engine recomputes P and Q from the
> + * source buffers and compares them against the existing parity stored at @pq.
> + * The result of each comparison is reported through @pqres.
> + *
> + * Returns a descriptor on success, or NULL if the channel does not support
> + * this operation or the request could not be queued.
> + */

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260923-dmaengine_prep_dma_pq-v2-0-32ed65b8a9b4@nxp.com?part=3

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 09/12] dmaengine: replace dma_maxqp() with dmaengine_maxpq() taking struct dma_chan *
  2026-09-23 16:19 ` [PATCH v2 09/12] dmaengine: replace dma_maxqp() with dmaengine_maxpq() taking struct dma_chan * Frank.Li
@ 2026-09-23 16:28   ` sashiko-bot
  0 siblings, 0 replies; 17+ messages in thread
From: sashiko-bot @ 2026-09-23 16:28 UTC (permalink / raw)
  To: Frank.Li; +Cc: ntb, imx, dmaengine, vkoul, Frank.Li

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Low] dmaengine: stale kernel-doc parameter for dmaengine_maxpq()
- [Low] dmaengine: stale comment references to dma_maxpq in ioat/prep.c
--

commit cf2513640f8224536d6e477b79237784cd551e0e
Author: Frank Li <Frank.Li@nxp.com>

dmaengine: replace dma_maxqp() with dmaengine_maxpq() taking struct dma_chan *

Replace dma_maxpq() with dmaengine_maxpq(chan, flags) as a channel-based
API, consistent with the convention of other dmaengine_*() helpers that
take struct dma_chan * rather than struct dma_device *.

> diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
> index 63f40b8fd3009..34fd3bb32f86e 100644
> --- a/include/linux/dmaengine.h
> +++ b/include/linux/dmaengine.h
> @@ -1706,7 +1706,7 @@ static inline unsigned short dma_dev_to_maxpq(struct dma_device *dma)
>  	return dma->max_pq & ~DMA_HAS_PQ_CONTINUE;
>  }
>  
> -/* dma_maxpq - reduce maxpq in the face of continued operations
> +/* dmaengine_maxpq - reduce maxpq in the face of continued operations
>   * @dma - dma device with PQ capability

[Severity: Low]
Does this kernel-doc comment need to be updated to document the new 'chan'
parameter instead of the removed 'dma' parameter? The mismatched names will
cause kernel-doc validation tools to emit warnings.

>   * @flags - to check if DMA_PREP_CONTINUE and DMA_PREP_PQ_DISABLE_P are set
>   *

[ ... ]

> @@ -1719,8 +1719,10 @@ static inline unsigned short dma_dev_to_maxpq(struct dma_device *dma)
>   * In the case where P is disabled we only need 1 extra source:
>   * 1/ {01} * Q : use Q to continue Q' calculation
>   */
> -static inline int dma_maxpq(struct dma_device *dma, enum dma_ctrl_flags flags)
> +static inline int dmaengine_maxpq(struct dma_chan *chan, enum dma_ctrl_flags flags)
>  {

[Severity: Low]
Are there plans to update existing comment references to dma_maxpq() in other
drivers as part of this refactoring?

For example, there are stale references in drivers/dma/ioat/prep.c inside
__ioat_prep_pq_lock() and __ioat_prep_pq16_lock() that still refer to the
old dma_maxpq function name.

> +	struct dma_device *dma = chan->device;
> +
>  	if (dma_dev_has_pq_continue(dma) || !dmaf_continue(flags))

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260923-dmaengine_prep_dma_pq-v2-0-32ed65b8a9b4@nxp.com?part=9

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 08/12] dmaengine: change dmaengine_get_unmap_data() first arg to dma_chan
  2026-09-23 16:19 ` [PATCH v2 08/12] dmaengine: change dmaengine_get_unmap_data() first arg to dma_chan Frank.Li
@ 2026-09-23 16:32   ` sashiko-bot
  0 siblings, 0 replies; 17+ messages in thread
From: sashiko-bot @ 2026-09-23 16:32 UTC (permalink / raw)
  To: Frank.Li; +Cc: imx, dmaengine, vkoul, ntb, Frank.Li

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] dmaengine: NULL pointer dereference in mv_xor self-tests due to uninitialized chan_dev
- [High] dmaengine: DMA device mismatch for mapping and unmapping in NTB and mv_xor drivers
--

commit ddb68198d418b187ac31a8ab8dc1644ae5ebab5d
Author: Frank Li <Frank.Li@nxp.com>

dmaengine: change dmaengine_get_unmap_data() first arg to dma_chan

Replace the struct device *dev argument with struct dma_chan *chan so callers
do not need to reach into the dma_device internals to obtain the device
pointer. The implementation now derives the device via
dmaengine_get_dma_device(chan), which correctly handles the per-channel
IOMMU mapping case.

> diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c
> index c4e0dce3ca64e..dec01b6264d7a 100644
> --- a/drivers/dma/mv_xor.c
> +++ b/drivers/dma/mv_xor.c
> @@ -794,7 +794,7 @@ static int mv_chan_memcpy_self_test(struct mv_xor_chan *mv_chan)
>  		goto out;
>  	}
>  
> -	unmap = dmaengine_get_unmap_data(dma_chan->device->dev, 2, GFP_KERNEL);
> +	unmap = dmaengine_get_unmap_data(dma_chan, 2, GFP_KERNEL);

[Severity: High]
Does this cause a NULL pointer dereference on initialization?

The driver mv_xor runs self-tests like mv_chan_memcpy_self_test() during
probe before calling dma_async_device_register().

Because this patch changes dmaengine_get_unmap_data() to call
dmaengine_get_dma_device(chan), it unconditionally dereferences
chan->chan_dev. Since chan->chan_dev is allocated inside
dma_async_device_register(), it is NULL when the self-tests run.

Could this also lead to a device mismatch for DMA mapping?

Later in mv_chan_memcpy_self_test(), dma_map_page() still explicitly uses
dma_chan->device->dev instead of tracking with the new unmap device logic:

drivers/dma/mv_xor.c:mv_chan_memcpy_self_test() {
    ...
	src_dma = dma_map_page(dma_chan->device->dev, virt_to_page(src),
			       offset_in_page(src), PAGE_SIZE,
			       DMA_TO_DEVICE);
    ...
}

Mapping memory using one device pointer and unmapping it via a different one
violates the DMA API contract, which can lead to IOMMU faults and memory
leaks on platforms where the channel uses a separate device.

> @@ -927,7 +927,7 @@ mv_chan_xor_self_test(struct mv_xor_chan *mv_chan)
>  		goto out;
>  	}
>  
> -	unmap = dmaengine_get_unmap_data(dma_chan->device->dev, src_count + 1,
> +	unmap = dmaengine_get_unmap_data(dma_chan, src_count + 1,
>  					 GFP_KERNEL);

[Severity: High]
Will this also trigger the same NULL pointer dereference here since it
runs during probe before registration?

It also has the same mapping mismatch issue where dma_map_page() explicitly
calls out dma_chan->device->dev instead of using the new unmap device logic.

[ ... ]

> diff --git a/drivers/ntb/ntb_transport.c b/drivers/ntb/ntb_transport.c
> index f9caa1a653c5b..e1cb55890d72b 100644
> --- a/drivers/ntb/ntb_transport.c
> +++ b/drivers/ntb/ntb_transport.c
> @@ -1532,7 +1532,7 @@ static int ntb_async_rx_submit(struct ntb_queue_entry *entry, void *offset)
>  	if (!is_dma_copy_aligned(device, pay_off, buff_off, len))
>  		goto err;
>  
> -	unmap = dmaengine_get_unmap_data(device->dev, 2, GFP_NOWAIT);
> +	unmap = dmaengine_get_unmap_data(chan, 2, GFP_NOWAIT);

[Severity: High]
Is there a device mismatch for DMA mapping here as well?

While unmap now uses dmaengine_get_dma_device(chan), ntb_async_rx_submit()
still explicitly maps memory using the parent device:

drivers/ntb/ntb_transport.c:ntb_async_rx_submit() {
    ...
	unmap->addr[0] = dma_map_phys(device->dev, virt_to_phys(offset),
				      len, DMA_TO_DEVICE, 0);
    ...
}

This mismatch between the mapping device and the unmapping device can lead
to IOMMU faults and memory leaks.

> @@ -1872,7 +1872,7 @@ static int ntb_async_tx_submit(struct ntb_transport_qp *qp,
>  	if (!is_dma_copy_aligned(device, buff_off, dest_off, len))
>  		goto err;
>  
> -	unmap = dmaengine_get_unmap_data(device->dev, 1, GFP_NOWAIT);
> +	unmap = dmaengine_get_unmap_data(chan, 1, GFP_NOWAIT);

[Severity: High]
Does this suffer from the same mapping mismatch?

The dma_map_phys() call just below this still maps memory using the
parent device (device->dev).

[ ... ]

> diff --git a/drivers/ntb/test/ntb_perf.c b/drivers/ntb/test/ntb_perf.c
> index dfd175f79e8f0..5fea36432ba92 100644
> --- a/drivers/ntb/test/ntb_perf.c
> +++ b/drivers/ntb/test/ntb_perf.c
> @@ -809,7 +809,7 @@ static int perf_copy_chunk(struct perf_thread *pthr,
>  	dst_vaddr = dst;
>  	dst_dma_addr = peer->dma_dst_addr + (dst_vaddr - vbase);
>  
> -	unmap = dmaengine_get_unmap_data(dma_dev, 1, GFP_NOWAIT);
> +	unmap = dmaengine_get_unmap_data(pthr->dma_chan, 1, GFP_NOWAIT);

[Severity: High]
Might this also create a device mismatch for DMA mapping?

In perf_copy_chunk(), dma_dev is locally initialized to
pthr->dma_chan->device->dev, and used for dma_map_page():

drivers/ntb/test/ntb_perf.c:perf_copy_chunk() {
    ...
	unmap->addr[0] = dma_map_page(dma_dev, virt_to_page(src),
		offset_in_page(src), len, DMA_TO_DEVICE);
    ...
}

This maps memory using the parent device but unmaps it using the new
per-channel unmap device logic.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260923-dmaengine_prep_dma_pq-v2-0-32ed65b8a9b4@nxp.com?part=8

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 00/12] dmaengine: Add dmaengine API to avoid call DMA Engine callback directly
  2026-09-23 16:19 [PATCH v2 00/12] dmaengine: Add dmaengine API to avoid call DMA Engine callback directly Frank.Li
                   ` (11 preceding siblings ...)
  2026-09-23 16:19 ` [PATCH v2 12/12] async_tx: replace open-coded cap_mask accesses with dmaengine_has_cap() Frank.Li
@ 2026-10-09 10:14 ` Vinod Koul
  12 siblings, 0 replies; 17+ messages in thread
From: Vinod Koul @ 2026-10-09 10:14 UTC (permalink / raw)
  To: Frank Li, Dan Williams, Herbert Xu, David S. Miller, Jon Mason,
	Dave Jiang, Allen Hubbe, Frank.Li
  Cc: dmaengine, linux-kernel, linux-crypto, imx, Frank Li, ntb


On Wed, 23 Sep 2026 12:19:29 -0400, Frank.Li@oss.nxp.com wrote:
> Add dmaengine APIs to avoid call DMA Engine callback directly. Prepare to
> make dmaengine provider private.
> 
> Fix all under crypto/async_tx
> 
> Build pass under crypto/async_tx after change dma_device *device to _device.
> to make sure all code use dmaengine APIs.
> 
> [...]

Applied, thanks!

[01/12] async_tx: replace direct ->device_prep*() calls with standard DMA engine API
        (no commit info)
[02/12] async_tx: use dmaengine_get_dma_device() instead of chan->device->dev
        (no commit info)
[03/12] dmaengine: add dmaengine_prep_dma_(pq|pq_val|interrupt|xor)() API
        commit: 4bdb88eb5496cb09902b9778ca7f4628c43b0d77
[04/12] dmaengine: add dmaengine_is_*_aligned() helpers for DMA consumers
        commit: 11e801ccaca78c9d92b1f3a9733772bf9d2c079c
[05/12] dmaengine: add dmaengine_get_copy_align() and related alignment getter helpers
        commit: 072975a8a578a62ea68ec1ceb8d2d7dcfb5dfefa
[06/12] dmaengine: add dmaengine_get_cap_mask() and dmaengine_has_cap() helpers
        commit: bbc109e0e686266d784483df108af206bc52e120
[07/12] dmaengine: add dmaengine_get_max_xor() helper
        commit: bff69558d64a98bc8d03f373d1331223c3428a2c
[08/12] dmaengine: change dmaengine_get_unmap_data() first arg to dma_chan
        (no commit info)
[09/12] dmaengine: replace dma_maxqp() with dmaengine_maxpq() taking struct dma_chan *
        (no commit info)
[10/12] async_tx: use dmaengine_prep_dma_(pq|pq_val|interrupt|xor) instead of direct callback
        (no commit info)
[11/12] async_tx: convert to dmaengine_is_*_aligned() helpers
        (no commit info)
[12/12] async_tx: replace open-coded cap_mask accesses with dmaengine_has_cap()
        (no commit info)

Best regards,
-- 
~Vinod



^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2026-10-09 10:14 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-23 16:19 [PATCH v2 00/12] dmaengine: Add dmaengine API to avoid call DMA Engine callback directly Frank.Li
2026-09-23 16:19 ` [PATCH v2 01/12] async_tx: replace direct ->device_prep*() calls with standard DMA engine API Frank.Li
2026-09-23 16:19 ` [PATCH v2 02/12] async_tx: use dmaengine_get_dma_device() instead of chan->device->dev Frank.Li
2026-09-23 16:19 ` [PATCH v2 03/12] dmaengine: add dmaengine_prep_dma_(pq|pq_val|interrupt|xor)() API Frank.Li
2026-09-23 16:26   ` sashiko-bot
2026-09-23 16:19 ` [PATCH v2 04/12] dmaengine: add dmaengine_is_*_aligned() helpers for DMA consumers Frank.Li
2026-09-23 16:19 ` [PATCH v2 05/12] dmaengine: add dmaengine_get_copy_align() and related alignment getter helpers Frank.Li
2026-09-23 16:19 ` [PATCH v2 06/12] dmaengine: add dmaengine_get_cap_mask() and dmaengine_has_cap() helpers Frank.Li
2026-09-23 16:19 ` [PATCH v2 07/12] dmaengine: add dmaengine_get_max_xor() helper Frank.Li
2026-09-23 16:19 ` [PATCH v2 08/12] dmaengine: change dmaengine_get_unmap_data() first arg to dma_chan Frank.Li
2026-09-23 16:32   ` sashiko-bot
2026-09-23 16:19 ` [PATCH v2 09/12] dmaengine: replace dma_maxqp() with dmaengine_maxpq() taking struct dma_chan * Frank.Li
2026-09-23 16:28   ` sashiko-bot
2026-09-23 16:19 ` [PATCH v2 10/12] async_tx: use dmaengine_prep_dma_(pq|pq_val|interrupt|xor) instead of direct callback Frank.Li
2026-09-23 16:19 ` [PATCH v2 11/12] async_tx: convert to dmaengine_is_*_aligned() helpers Frank.Li
2026-09-23 16:19 ` [PATCH v2 12/12] async_tx: replace open-coded cap_mask accesses with dmaengine_has_cap() Frank.Li
2026-10-09 10:14 ` [PATCH v2 00/12] dmaengine: Add dmaengine API to avoid call DMA Engine callback directly Vinod Koul

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.