* [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