[PATCH 1/1] mtd: use dmaengine_get_dma_device() instead of chan->device->dev

From: Frank . Li

Date: Thu Sep 17 2026 - 17:10:52 EST


From: Frank Li <Frank.Li@xxxxxxx>

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.

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

Assisted-by: LLM
Signed-off-by: Frank Li <Frank.Li@xxxxxxx>
---
Cc: imx@xxxxxxxxxxxxxxx
Cc: vkoul@xxxxxxxxxx
---
drivers/mtd/hyperbus/hbmc-am654.c | 7 ++++---
drivers/mtd/nand/raw/cadence-nand-controller.c | 2 +-
drivers/mtd/nand/raw/intel-nand-controller.c | 6 ++++--
drivers/mtd/nand/raw/loongson-nand-controller.c | 4 ++--
drivers/mtd/nand/raw/lpc32xx_mlc.c | 10 ++++------
drivers/mtd/nand/raw/lpc32xx_slc.c | 10 ++++------
drivers/mtd/nand/raw/marvell_nand.c | 7 ++++---
drivers/mtd/nand/raw/omap2.c | 10 +++++-----
drivers/mtd/nand/raw/sh_flctl.c | 8 +++++---
9 files changed, 33 insertions(+), 31 deletions(-)

diff --git a/drivers/mtd/hyperbus/hbmc-am654.c b/drivers/mtd/hyperbus/hbmc-am654.c
index 9d31464046b22..8a14e908d0b53 100644
--- a/drivers/mtd/hyperbus/hbmc-am654.c
+++ b/drivers/mtd/hyperbus/hbmc-am654.c
@@ -78,14 +78,15 @@ static int am654_hbmc_dma_read(struct am654_hbmc_device_priv *priv, void *to,
struct dma_chan *rx_chan = priv->rx_chan;
struct dma_async_tx_descriptor *tx;
dma_addr_t dma_dst, dma_src;
+ struct device *rx_dev = dmaengine_get_dma_device(rx_chan);
dma_cookie_t cookie;
int ret;

if (!priv->rx_chan || !virt_addr_valid(to) || object_is_on_stack(to))
return -EINVAL;

- dma_dst = dma_map_single(rx_chan->device->dev, to, len, DMA_FROM_DEVICE);
- if (dma_mapping_error(rx_chan->device->dev, dma_dst)) {
+ dma_dst = dma_map_single(rx_dev, to, len, DMA_FROM_DEVICE);
+ if (dma_mapping_error(rx_dev, dma_dst)) {
dev_dbg(priv->ctlr->dev, "DMA mapping failed\n");
return -EIO;
}
@@ -117,7 +118,7 @@ static int am654_hbmc_dma_read(struct am654_hbmc_device_priv *priv, void *to,
}

unmap_dma:
- dma_unmap_single(rx_chan->device->dev, dma_dst, len, DMA_FROM_DEVICE);
+ dma_unmap_single(rx_dev, dma_dst, len, DMA_FROM_DEVICE);
return ret;
}

diff --git a/drivers/mtd/nand/raw/cadence-nand-controller.c b/drivers/mtd/nand/raw/cadence-nand-controller.c
index 2085632631c02..4f5e6d2b128c7 100644
--- a/drivers/mtd/nand/raw/cadence-nand-controller.c
+++ b/drivers/mtd/nand/raw/cadence-nand-controller.c
@@ -3229,7 +3229,7 @@ static void cadence_nand_remove(struct cdns_nand_ctrl *cdns_ctrl)
{
cadence_nand_chips_cleanup(cdns_ctrl);
if (cdns_ctrl->dmac)
- dma_unmap_resource(cdns_ctrl->dmac->device->dev,
+ dma_unmap_resource(dmaengine_get_dma_device(cdns_ctrl->dmac),
cdns_ctrl->io.iova_dma, cdns_ctrl->io.size,
DMA_BIDIRECTIONAL, 0);
cadence_nand_irq_cleanup(cdns_ctrl->irq, cdns_ctrl);
diff --git a/drivers/mtd/nand/raw/intel-nand-controller.c b/drivers/mtd/nand/raw/intel-nand-controller.c
index 01cefdaf115d1..0a4f5ff111334 100644
--- a/drivers/mtd/nand/raw/intel-nand-controller.c
+++ b/drivers/mtd/nand/raw/intel-nand-controller.c
@@ -290,6 +290,7 @@ static int ebu_dma_start(struct ebu_nand_controller *ebu_host, u32 dir,
struct dma_async_tx_descriptor *tx;
struct completion *dma_completion;
dma_async_tx_callback callback;
+ struct device *dma_dev;
struct dma_chan *chan;
dma_cookie_t cookie;
unsigned long flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT;
@@ -307,8 +308,9 @@ static int ebu_dma_start(struct ebu_nand_controller *ebu_host, u32 dir,
callback = ebu_dma_tx_callback;
}

- buf_dma = dma_map_single(chan->device->dev, (void *)buf, len, dir);
- if (dma_mapping_error(chan->device->dev, buf_dma)) {
+ dma_dev = dmaengine_get_dma_device(chan);
+ buf_dma = dma_map_single(dma_dev, (void *)buf, len, dir);
+ if (dma_mapping_error(dma_dev, buf_dma)) {
dev_err(ebu_host->dev, "Failed to map DMA buffer\n");
ret = -EIO;
goto err_unmap;
diff --git a/drivers/mtd/nand/raw/loongson-nand-controller.c b/drivers/mtd/nand/raw/loongson-nand-controller.c
index 8490412d5be19..935f66602de97 100644
--- a/drivers/mtd/nand/raw/loongson-nand-controller.c
+++ b/drivers/mtd/nand/raw/loongson-nand-controller.c
@@ -391,7 +391,7 @@ static void loongson_nand_dma_callback(void *data)
{
struct loongson_nand_host *host = (struct loongson_nand_host *)data;
struct dma_chan *chan = host->dma_chan;
- struct device *dev = chan->device->dev;
+ struct device *dev = dmaengine_get_dma_device(chan);
enum dma_status status;

status = dmaengine_tx_status(chan, host->dma_cookie, NULL);
@@ -407,7 +407,7 @@ static int loongson_nand_dma_transfer(struct loongson_nand_host *host, struct lo
{
struct nand_chip *chip = &host->chip;
struct dma_chan *chan = host->dma_chan;
- struct device *dev = chan->device->dev;
+ struct device *dev = dmaengine_get_dma_device(chan);
struct dma_async_tx_descriptor *desc;
enum dma_data_direction data_dir = op->is_write ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
enum dma_transfer_direction xfer_dir = op->is_write ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM;
diff --git a/drivers/mtd/nand/raw/lpc32xx_mlc.c b/drivers/mtd/nand/raw/lpc32xx_mlc.c
index 8436015edcb4f..d03486dc41150 100644
--- a/drivers/mtd/nand/raw/lpc32xx_mlc.c
+++ b/drivers/mtd/nand/raw/lpc32xx_mlc.c
@@ -392,6 +392,7 @@ static int lpc32xx_xmit_dma(struct mtd_info *mtd, void *mem, int len,
{
struct nand_chip *chip = mtd_to_nand(mtd);
struct lpc32xx_nand_host *host = nand_get_controller_data(chip);
+ struct device *dma_dev = dmaengine_get_dma_device(host->dma_chan);
struct dma_async_tx_descriptor *desc;
int flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT;
unsigned long time_left;
@@ -399,8 +400,7 @@ static int lpc32xx_xmit_dma(struct mtd_info *mtd, void *mem, int len,

sg_init_one(&host->sgl, mem, len);

- res = dma_map_sg(host->dma_chan->device->dev, &host->sgl, 1,
- DMA_BIDIRECTIONAL);
+ res = dma_map_sg(dma_dev, &host->sgl, 1, DMA_BIDIRECTIONAL);
if (res != 1) {
dev_err(mtd->dev.parent, "Failed to map sg list\n");
return -ENXIO;
@@ -428,12 +428,10 @@ static int lpc32xx_xmit_dma(struct mtd_info *mtd, void *mem, int len,
goto out1;
}

- dma_unmap_sg(host->dma_chan->device->dev, &host->sgl, 1,
- DMA_BIDIRECTIONAL);
+ dma_unmap_sg(dma_dev, &host->sgl, 1, DMA_BIDIRECTIONAL);
return 0;
out1:
- dma_unmap_sg(host->dma_chan->device->dev, &host->sgl, 1,
- DMA_BIDIRECTIONAL);
+ dma_unmap_sg(dma_dev, &host->sgl, 1, DMA_BIDIRECTIONAL);
return res;
}

diff --git a/drivers/mtd/nand/raw/lpc32xx_slc.c b/drivers/mtd/nand/raw/lpc32xx_slc.c
index b4d90afa92677..638267d44360d 100644
--- a/drivers/mtd/nand/raw/lpc32xx_slc.c
+++ b/drivers/mtd/nand/raw/lpc32xx_slc.c
@@ -425,6 +425,7 @@ static int lpc32xx_xmit_dma(struct mtd_info *mtd, dma_addr_t dma,
{
struct nand_chip *chip = mtd_to_nand(mtd);
struct lpc32xx_nand_host *host = nand_get_controller_data(chip);
+ struct device *dma_dev = dmaengine_get_dma_device(host->dma_chan);
struct dma_async_tx_descriptor *desc;
int flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT;
int res;
@@ -446,8 +447,7 @@ static int lpc32xx_xmit_dma(struct mtd_info *mtd, dma_addr_t dma,

sg_init_one(&host->sgl, mem, len);

- res = dma_map_sg(host->dma_chan->device->dev, &host->sgl, 1,
- DMA_BIDIRECTIONAL);
+ res = dma_map_sg(dma_dev, &host->sgl, 1, DMA_BIDIRECTIONAL);
if (res != 1) {
dev_err(mtd->dev.parent, "Failed to map sg list\n");
return -ENXIO;
@@ -475,13 +475,11 @@ static int lpc32xx_xmit_dma(struct mtd_info *mtd, dma_addr_t dma,
res = 0;
}

- dma_unmap_sg(host->dma_chan->device->dev, &host->sgl, 1,
- DMA_BIDIRECTIONAL);
+ dma_unmap_sg(dma_dev, &host->sgl, 1, DMA_BIDIRECTIONAL);

return res;
out1:
- dma_unmap_sg(host->dma_chan->device->dev, &host->sgl, 1,
- DMA_BIDIRECTIONAL);
+ dma_unmap_sg(dma_dev, &host->sgl, 1, DMA_BIDIRECTIONAL);
return -ENXIO;
}

diff --git a/drivers/mtd/nand/raw/marvell_nand.c b/drivers/mtd/nand/raw/marvell_nand.c
index 38b7eb5b992c8..e5fa5540e80a0 100644
--- a/drivers/mtd/nand/raw/marvell_nand.c
+++ b/drivers/mtd/nand/raw/marvell_nand.c
@@ -868,6 +868,7 @@ static int marvell_nfc_xfer_data_dma(struct marvell_nfc *nfc,
unsigned int len)
{
unsigned int dma_len = min_t(int, ALIGN(len, 32), MAX_CHUNK_SIZE);
+ struct device *dma_dev = dmaengine_get_dma_device(nfc->dma_chan);
struct dma_async_tx_descriptor *tx;
struct scatterlist sg;
dma_cookie_t cookie;
@@ -876,7 +877,7 @@ static int marvell_nfc_xfer_data_dma(struct marvell_nfc *nfc,
marvell_nfc_enable_dma(nfc);
/* Prepare the DMA transfer */
sg_init_one(&sg, nfc->dma_buf, dma_len);
- ret = dma_map_sg(nfc->dma_chan->device->dev, &sg, 1, direction);
+ ret = dma_map_sg(dma_dev, &sg, 1, direction);
if (!ret) {
dev_err(nfc->dev, "Could not map DMA S/G list\n");
return -ENXIO;
@@ -888,7 +889,7 @@ static int marvell_nfc_xfer_data_dma(struct marvell_nfc *nfc,
DMA_PREP_INTERRUPT);
if (!tx) {
dev_err(nfc->dev, "Could not prepare DMA S/G list\n");
- dma_unmap_sg(nfc->dma_chan->device->dev, &sg, 1, direction);
+ dma_unmap_sg(dma_dev, &sg, 1, direction);
return -ENXIO;
}

@@ -900,7 +901,7 @@ static int marvell_nfc_xfer_data_dma(struct marvell_nfc *nfc,

dma_async_issue_pending(nfc->dma_chan);
ret = marvell_nfc_wait_cmdd(nfc->selected_chip);
- dma_unmap_sg(nfc->dma_chan->device->dev, &sg, 1, direction);
+ dma_unmap_sg(dma_dev, &sg, 1, direction);
marvell_nfc_disable_dma(nfc);
if (ret) {
dev_err(nfc->dev, "Timeout waiting for DMA (status: %d)\n",
diff --git a/drivers/mtd/nand/raw/omap2.c b/drivers/mtd/nand/raw/omap2.c
index 4909e62dc11e9..4fa89aee934eb 100644
--- a/drivers/mtd/nand/raw/omap2.c
+++ b/drivers/mtd/nand/raw/omap2.c
@@ -380,8 +380,8 @@ static inline int omap_nand_dma_transfer(struct nand_chip *chip,
{
struct omap_nand_info *info = mtd_to_omap(nand_to_mtd(chip));
struct dma_async_tx_descriptor *tx;
- enum dma_data_direction dir = is_write ? DMA_TO_DEVICE :
- DMA_FROM_DEVICE;
+ enum dma_data_direction dir = is_write ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
+ struct device *dma_dev = dmaengine_get_dma_device(info->dma);
struct scatterlist sg;
unsigned long tim, limit;
unsigned n;
@@ -392,7 +392,7 @@ static inline int omap_nand_dma_transfer(struct nand_chip *chip,
goto out_copy;

sg_init_one(&sg, addr, len);
- n = dma_map_sg(info->dma->device->dev, &sg, 1, dir);
+ n = dma_map_sg(dma_dev, &sg, 1, dir);
if (n == 0) {
dev_err(&info->pdev->dev,
"Couldn't DMA map a %d byte buffer\n", len);
@@ -434,11 +434,11 @@ static inline int omap_nand_dma_transfer(struct nand_chip *chip,
/* disable and stop the PFPW engine */
omap_prefetch_reset(info->gpmc_cs, info);

- dma_unmap_sg(info->dma->device->dev, &sg, 1, dir);
+ dma_unmap_sg(dma_dev, &sg, 1, dir);
return 0;

out_copy_unmap:
- dma_unmap_sg(info->dma->device->dev, &sg, 1, dir);
+ dma_unmap_sg(dma_dev, &sg, 1, dir);
out_copy:
is_write == 0 ? omap_nand_data_in(chip, (void *)addr, len, false)
: omap_nand_data_out(chip, addr, len, false);
diff --git a/drivers/mtd/nand/raw/sh_flctl.c b/drivers/mtd/nand/raw/sh_flctl.c
index 97f733e481ffc..0497801d7059f 100644
--- a/drivers/mtd/nand/raw/sh_flctl.c
+++ b/drivers/mtd/nand/raw/sh_flctl.c
@@ -378,6 +378,7 @@ static int flctl_dma_fifo0_transfer(struct sh_flctl *flctl, unsigned long *buf,
int len, enum dma_data_direction dir)
{
struct dma_async_tx_descriptor *desc = NULL;
+ struct device *dma_dev;
struct dma_chan *chan;
enum dma_transfer_direction tr_dir;
dma_addr_t dma_addr;
@@ -394,9 +395,10 @@ static int flctl_dma_fifo0_transfer(struct sh_flctl *flctl, unsigned long *buf,
tr_dir = DMA_MEM_TO_DEV;
}

- dma_addr = dma_map_single(chan->device->dev, buf, len, dir);
+ dma_dev = dmaengine_get_dma_device(chan);
+ dma_addr = dma_map_single(dma_dev, buf, len, dir);

- if (!dma_mapping_error(chan->device->dev, dma_addr))
+ if (!dma_mapping_error(dma_dev, dma_addr))
desc = dmaengine_prep_slave_single(chan, dma_addr, len,
tr_dir, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);

@@ -440,7 +442,7 @@ static int flctl_dma_fifo0_transfer(struct sh_flctl *flctl, unsigned long *buf,
reg &= ~DREQ0EN;
writel(reg, FLINTDMACR(flctl));

- dma_unmap_single(chan->device->dev, dma_addr, len, dir);
+ dma_unmap_single(dma_dev, dma_addr, len, dir);

/* ret == 0 is success */
return ret;
--
2.43.0