public inbox for linux-arm-kernel@lists.infradead.org 
 help / color / mirror / Atom feed
* [PATCH v2 0/2] dmaengine: add helper macro dmaengine_prep_submit()
@ 2026-05-22 20:13 Frank.Li
  2026-05-22 20:13 ` [PATCH v2 1/2] dmaengine: Add helper dmaengine_prep_submit_slave_single() Frank.Li
  2026-05-22 20:13 ` [PATCH v2 2/2] i2c: imx-lpi2c: use dmaengine_prep_submit() to simple code Frank.Li
  0 siblings, 2 replies; 4+ messages in thread
From: Frank.Li @ 2026-05-22 20:13 UTC (permalink / raw)
  To: Vinod Koul, Dong Aisheng, Andi Shyti, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam
  Cc: dmaengine, linux-kernel, linux-i2c, imx, linux-arm-kernel,
	carlos.song, Frank Li

Add helper macro dmaengine_prep_submit() to combine prep and submit to
one call.

Pervious try to use cleanup
https://lore.kernel.org/dmaengine/20251002-dma_chan_free-v1-0-4dbf116c2b19@nxp.com/

It is not simple enough and easy missing retain_and_null_ptr() at success
path.

struct dma_async_tx_descriptor *rx_cmd_desc __free(dma_async_tx_descriptor) = NULL;
        ...
        cookie = dmaengine_submit(rx_cmd_desc);
        if (dma_submit_error(cookie))
                return dma_submit_error(cookie);
        ...
        retain_and_null_ptr(rx_cmd_desc);
}

So create help macro to combine prep and submit by one call.
patch 2.

 static int lpi2c_dma_rx_cmd_submit(struct lpi2c_imx_struct *lpi2c_imx)
 {
-       struct dma_async_tx_descriptor *rx_cmd_desc;
        struct lpi2c_imx_dma *dma = lpi2c_imx->dma;
        struct dma_chan *txchan = dma->chan_tx;
        dma_cookie_t cookie;
@@ -761,15 +760,10 @@ static int lpi2c_dma_rx_cmd_submit(struct lpi2c_imx_struct *lpi2c_imx)
                return -EINVAL;
        }

-       rx_cmd_desc = dmaengine_prep_slave_single(txchan, dma->dma_tx_addr,
-                                                 dma->rx_cmd_buf_len, DMA_MEM_TO_DEV,
-                                                 DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
-       if (!rx_cmd_desc) {
-               dev_err(&lpi2c_imx->adapter.dev, "DMA prep slave sg failed, use pio\n");
-               goto desc_prepare_err_exit;
-       }
-
-       cookie = dmaengine_submit(rx_cmd_desc);
+       cookie = dmaengine_prep_submit(txchan, NULL, NULL, slave_single,
+                                      dma->dma_tx_addr,
+                                      dma->rx_cmd_buf_len, DMA_MEM_TO_DEV,
+                                      DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
        if (dma_submit_error(cookie)) {
                dev_err(&lpi2c_imx->adapter.dev, "submitting DMA failed, use pio\n");
                goto submit_err_exit;
@@ -779,15 +773,9 @@ static int lpi2c_dma_rx_cmd_submit(struct lpi2c_imx_struct *lpi2c_imx)

        return 0;

-desc_prepare_err_exit:
-       dma_unmap_single(txchan->device->dev, dma->dma_tx_addr,
-                        dma->rx_cmd_buf_len, DMA_TO_DEVICE);
-       return -EINVAL;
-
 submit_err_exit:
        dma_unmap_single(txchan->device->dev, dma->dma_tx_addr,
                         dma->rx_cmd_buf_len, DMA_TO_DEVICE);
-       dmaengine_desc_free(rx_cmd_desc);
        return -EINVAL;
 }

Signed-off-by: Frank Li <Frank.Li@nxp•com>
---
Changes in v2:
- use API dmaengine_prep_submit_slave_single()
- Link to v1: https://lore.kernel.org/r/20260130-dma_prep_submit-v1-0-2198f9e848fa@nxp.com

---
Frank Li (2):
      dmaengine: Add helper dmaengine_prep_submit_slave_single()
      i2c: imx-lpi2c: use dmaengine_prep_submit() to simple code

 drivers/dma/dmaengine.c            | 28 ++++++++++++++++++++++++++++
 drivers/i2c/busses/i2c-imx-lpi2c.c | 21 +++++----------------
 include/linux/dmaengine.h          | 17 +++++++++++++++++
 3 files changed, 50 insertions(+), 16 deletions(-)
---
base-commit: 8f0b4cce4481fb22653697cced8d0d04027cb1e8
change-id: 20260130-dma_prep_submit-cbeac742de48

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



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

* [PATCH v2 1/2] dmaengine: Add helper dmaengine_prep_submit_slave_single()
  2026-05-22 20:13 [PATCH v2 0/2] dmaengine: add helper macro dmaengine_prep_submit() Frank.Li
@ 2026-05-22 20:13 ` Frank.Li
  2026-05-22 20:13 ` [PATCH v2 2/2] i2c: imx-lpi2c: use dmaengine_prep_submit() to simple code Frank.Li
  1 sibling, 0 replies; 4+ messages in thread
From: Frank.Li @ 2026-05-22 20:13 UTC (permalink / raw)
  To: Vinod Koul, Dong Aisheng, Andi Shyti, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam
  Cc: dmaengine, linux-kernel, linux-i2c, imx, linux-arm-kernel,
	carlos.song, Frank Li

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

Previously, DMA users had to call dmaengine_prep_slave_single() followed by
dmaengine_submit(). Many DMA consumers missed call dmaengine_desc_free()
when dmaengine_submit() returned an error.

Introduce dmaengine_prep_submit_slave_single() to combine preparation and
submission into a single step and ensure the descriptor is freed on
submission failure.

Signed-off-by: Frank Li <Frank.Li@nxp•com>
---
change in v2
- use api function dmaengine_prep_submit_slave_single()
---
 drivers/dma/dmaengine.c   | 28 ++++++++++++++++++++++++++++
 include/linux/dmaengine.h | 17 +++++++++++++++++
 2 files changed, 45 insertions(+)

diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
index ca13cd39330ba..1e25be78a22a5 100644
--- a/drivers/dma/dmaengine.c
+++ b/drivers/dma/dmaengine.c
@@ -1619,6 +1619,34 @@ void dma_run_dependencies(struct dma_async_tx_descriptor *tx)
 }
 EXPORT_SYMBOL_GPL(dma_run_dependencies);
 
+#define dmaengine_prep_submit(chan, cb, cb_param, func, ...)	\
+({	struct dma_async_tx_descriptor *tx =			\
+		dmaengine_prep_##func(chan, __VA_ARGS__);	\
+		dma_cookie_t cookie = -ENOMEM;			\
+								\
+	if (tx) {						\
+		tx->callback = cb;				\
+		tx->callback_param = cb_param;			\
+		cookie = dmaengine_submit(tx);			\
+								\
+		if (dma_submit_error(cookie))			\
+			dmaengine_desc_free(tx);		\
+	}							\
+	cookie;							\
+})
+
+dma_cookie_t
+dmaengine_prep_submit_slave_single(struct dma_chan *chan,
+				   dma_async_tx_callback cb, void *cb_param,
+				   dma_addr_t buf, size_t len,
+				   enum dma_transfer_direction dir,
+				   unsigned long flags)
+{
+	return dmaengine_prep_submit(chan, cb, cb_param, slave_single,
+				     buf, len, dir, flags);
+}
+EXPORT_SYMBOL_GPL(dmaengine_prep_submit_slave_single);
+
 static int __init dma_bus_init(void)
 {
 	int err = dmaengine_init_unmap_pool();
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index 99efe2b9b4ea9..0f789fac7e91a 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -990,6 +990,13 @@ static inline struct dma_async_tx_descriptor *dmaengine_prep_slave_single(
 						  dir, flags, NULL);
 }
 
+dma_cookie_t
+dmaengine_prep_submit_slave_single(struct dma_chan *chan,
+				   dma_async_tx_callback cb, void *cb_param,
+				   dma_addr_t buf, size_t len,
+				   enum dma_transfer_direction dir,
+				   unsigned long flags);
+
 /**
  * dmaengine_prep_peripheral_dma_vec() - Prepare a DMA scatter-gather descriptor
  * @chan: The channel to be used for this descriptor
@@ -1575,6 +1582,16 @@ static inline int dma_get_slave_caps(struct dma_chan *chan,
 {
 	return -ENXIO;
 }
+
+static inline dma_cookie_t
+dmaengine_prep_submit_slave_single(struct dma_chan *chan,
+				   dma_async_tx_callback cb, void *cb_param;
+				   dma_addr_t buf, size_t len,
+				   enum dma_transfer_direction dir,
+				   unsigned long flags);
+{
+	return -ENODEV;
+}
 #endif
 
 static inline int dmaengine_desc_set_reuse(struct dma_async_tx_descriptor *tx)

-- 
2.43.0



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

* [PATCH v2 2/2] i2c: imx-lpi2c: use dmaengine_prep_submit() to simple code
  2026-05-22 20:13 [PATCH v2 0/2] dmaengine: add helper macro dmaengine_prep_submit() Frank.Li
  2026-05-22 20:13 ` [PATCH v2 1/2] dmaengine: Add helper dmaengine_prep_submit_slave_single() Frank.Li
@ 2026-05-22 20:13 ` Frank.Li
  2026-05-26 22:22   ` kernel test robot
  1 sibling, 1 reply; 4+ messages in thread
From: Frank.Li @ 2026-05-22 20:13 UTC (permalink / raw)
  To: Vinod Koul, Dong Aisheng, Andi Shyti, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam
  Cc: dmaengine, linux-kernel, linux-i2c, imx, linux-arm-kernel,
	carlos.song, Frank Li

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

Use dmaengine_prep_submit() to simple code. No functional change.

Signed-off-by: Frank Li <Frank.Li@nxp•com>
---
 drivers/i2c/busses/i2c-imx-lpi2c.c | 21 +++++----------------
 1 file changed, 5 insertions(+), 16 deletions(-)

diff --git a/drivers/i2c/busses/i2c-imx-lpi2c.c b/drivers/i2c/busses/i2c-imx-lpi2c.c
index 2a0962a0b4417..c90f72eec8498 100644
--- a/drivers/i2c/busses/i2c-imx-lpi2c.c
+++ b/drivers/i2c/busses/i2c-imx-lpi2c.c
@@ -720,7 +720,6 @@ static void lpi2c_dma_callback(void *data)
 
 static int lpi2c_dma_rx_cmd_submit(struct lpi2c_imx_struct *lpi2c_imx)
 {
-	struct dma_async_tx_descriptor *rx_cmd_desc;
 	struct lpi2c_imx_dma *dma = lpi2c_imx->dma;
 	struct dma_chan *txchan = dma->chan_tx;
 	dma_cookie_t cookie;
@@ -733,15 +732,11 @@ static int lpi2c_dma_rx_cmd_submit(struct lpi2c_imx_struct *lpi2c_imx)
 		return -EINVAL;
 	}
 
-	rx_cmd_desc = dmaengine_prep_slave_single(txchan, dma->dma_tx_addr,
-						  dma->rx_cmd_buf_len, DMA_MEM_TO_DEV,
-						  DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
-	if (!rx_cmd_desc) {
-		dev_err(&lpi2c_imx->adapter.dev, "DMA prep slave sg failed, use pio\n");
-		goto desc_prepare_err_exit;
-	}
-
-	cookie = dmaengine_submit(rx_cmd_desc);
+	cookie = dmaengine_prep_submit_slave_single(txchan, NULL, NULL,
+						    dma->dma_tx_addr,
+						    dma->rx_cmd_buf_len,
+						    DMA_MEM_TO_DEV,
+						    DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
 	if (dma_submit_error(cookie)) {
 		dev_err(&lpi2c_imx->adapter.dev, "submitting DMA failed, use pio\n");
 		goto submit_err_exit;
@@ -751,15 +746,9 @@ static int lpi2c_dma_rx_cmd_submit(struct lpi2c_imx_struct *lpi2c_imx)
 
 	return 0;
 
-desc_prepare_err_exit:
-	dma_unmap_single(txchan->device->dev, dma->dma_tx_addr,
-			 dma->rx_cmd_buf_len, DMA_TO_DEVICE);
-	return -EINVAL;
-
 submit_err_exit:
 	dma_unmap_single(txchan->device->dev, dma->dma_tx_addr,
 			 dma->rx_cmd_buf_len, DMA_TO_DEVICE);
-	dmaengine_desc_free(rx_cmd_desc);
 	return -EINVAL;
 }
 

-- 
2.43.0



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

* Re: [PATCH v2 2/2] i2c: imx-lpi2c: use dmaengine_prep_submit() to simple code
  2026-05-22 20:13 ` [PATCH v2 2/2] i2c: imx-lpi2c: use dmaengine_prep_submit() to simple code Frank.Li
@ 2026-05-26 22:22   ` kernel test robot
  0 siblings, 0 replies; 4+ messages in thread
From: kernel test robot @ 2026-05-26 22:22 UTC (permalink / raw)
  To: Frank.Li, Vinod Koul, Dong Aisheng, Andi Shyti, Shawn Guo,
	Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam
  Cc: llvm, oe-kbuild-all, dmaengine, linux-kernel, linux-i2c, imx,
	linux-arm-kernel, carlos.song, Frank Li

Hi Frank,

kernel test robot noticed the following build errors:

[auto build test ERROR on 8f0b4cce4481fb22653697cced8d0d04027cb1e8]

url:    https://github.com/intel-lab-lkp/linux/commits/Frank-Li-oss-nxp-com/dmaengine-Add-helper-dmaengine_prep_submit_slave_single/20260523-041812
base:   8f0b4cce4481fb22653697cced8d0d04027cb1e8
patch link:    https://lore.kernel.org/r/20260522-dma_prep_submit-v2-2-7a87a5a29525%40nxp.com
patch subject: [PATCH v2 2/2] i2c: imx-lpi2c: use dmaengine_prep_submit() to simple code
config: x86_64-kexec (https://download.01.org/0day-ci/archive/20260527/202605270007.xFkhAWbC-lkp@intel.com/config)
compiler: clang version 20.1.8 (https://github.com/llvm/llvm-project 87f0227cb60147a26a1eeb4fb06e3b505e9c7261)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260527/202605270007.xFkhAWbC-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel•com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202605270007.xFkhAWbC-lkp@intel.com/

All errors (new ones prefixed by >>):

   In file included from net/core/dev.c:124:
>> include/linux/dmaengine.h:1588:48: error: expected ')'
    1588 |                                    dma_async_tx_callback cb, void *cb_param;
         |                                                                            ^
   include/linux/dmaengine.h:1587:35: note: to match this '('
    1587 | dmaengine_prep_submit_slave_single(struct dma_chan *chan,
         |                                   ^
>> include/linux/dmaengine.h:1587:1: error: conflicting types for 'dmaengine_prep_submit_slave_single'
    1587 | dmaengine_prep_submit_slave_single(struct dma_chan *chan,
         | ^
   include/linux/dmaengine.h:994:1: note: previous declaration is here
     994 | dmaengine_prep_submit_slave_single(struct dma_chan *chan,
         | ^
>> include/linux/dmaengine.h:1589:24: error: redefinition of 'size_t' as different kind of symbol
    1589 |                                    dma_addr_t buf, size_t len,
         |                                                    ^
   include/linux/types.h:62:26: note: previous definition is here
      62 | typedef __kernel_size_t         size_t;
         |                                 ^
   In file included from net/core/dev.c:124:
>> include/linux/dmaengine.h:1589:30: error: expected ';' after top level declarator
    1589 |                                    dma_addr_t buf, size_t len,
         |                                                          ^
         |                                                          ;
>> include/linux/dmaengine.h:1592:1: error: expected identifier or '('
    1592 | {
         | ^
   5 errors generated.


vim +1588 include/linux/dmaengine.h

  1585	
  1586	static inline dma_cookie_t
> 1587	dmaengine_prep_submit_slave_single(struct dma_chan *chan,
> 1588					   dma_async_tx_callback cb, void *cb_param;
> 1589					   dma_addr_t buf, size_t len,
  1590					   enum dma_transfer_direction dir,
  1591					   unsigned long flags);
> 1592	{
  1593		return -ENODEV;
  1594	}
  1595	#endif
  1596	

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


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

end of thread, other threads:[~2026-05-26 22:23 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-22 20:13 [PATCH v2 0/2] dmaengine: add helper macro dmaengine_prep_submit() Frank.Li
2026-05-22 20:13 ` [PATCH v2 1/2] dmaengine: Add helper dmaengine_prep_submit_slave_single() Frank.Li
2026-05-22 20:13 ` [PATCH v2 2/2] i2c: imx-lpi2c: use dmaengine_prep_submit() to simple code Frank.Li
2026-05-26 22:22   ` kernel test robot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox