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

Frank.Li at oss.nxp.com Frank.Li at oss.nxp.com
Thu Sep 17 13:47:06 PDT 2026


From: Frank Li <Frank.Li at 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.

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 at nxp.com>
---
Cc: imx at lists.linux.dev
Cc: vkoul at kernel.org
---
 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




More information about the linux-arm-kernel mailing list