From a018524a2ec96da5bb1965053967a20e0069ed9e Mon Sep 17 00:00:00 2001 From: Frank Li Date: Thu, 17 Sep 2026 16:47:06 -0400 Subject: [PATCH] mtd: use dmaengine_get_dma_device() instead of chan->device->dev 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 Signed-off-by: Miquel Raynal --- 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 9d31464046b2..8a14e908d0b5 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 d53b35a8b3cb..88f22fa4704e 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 01cefdaf115d..0a4f5ff11133 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 8490412d5be1..935f66602de9 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 8f6a89d9ba83..4400989df8a0 100644 --- a/drivers/mtd/nand/raw/lpc32xx_mlc.c +++ b/drivers/mtd/nand/raw/lpc32xx_mlc.c @@ -394,6 +394,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; @@ -401,8 +402,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; @@ -430,12 +430,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 10c8080207f4..bdc3957369c2 100644 --- a/drivers/mtd/nand/raw/lpc32xx_slc.c +++ b/drivers/mtd/nand/raw/lpc32xx_slc.c @@ -427,6 +427,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; @@ -448,8 +449,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; @@ -477,13 +477,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 38b7eb5b992c..e5fa5540e80a 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 552f36da79fc..9f7079e36663 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 97f733e481ff..0497801d7059 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;