Linux MultiMedia Card development
 help / color / mirror / Atom feed
From: John Garry <john.g.garry@oracle.com>
To: ulfh@kernel.org, florian.fainelli@broadcom.com,
	rjui@broadcom.com, sbranden@broadcom.com
Cc: bcm-kernel-feedback-list@broadcom.com, linux-mmc@vger.kernel.org,
	hch@lst.de, robin.murphy@arm.com, martin.petersen@oracle.com,
	linux-rpi-kernel@lists.infradead.org,
	John Garry <john.g.garry@oracle.com>
Subject: [PATCH] mmc: bcm2835: DMA mapping improvements
Date: Mon,  6 Jul 2026 07:39:13 +0000	[thread overview]
Message-ID: <20260706073913.538598-1-john.g.garry@oracle.com> (raw)

As pointed out by sashiko bot in [0], recent proposed changes to
dma_max_mapping_size() may affect the driver.

While the issue reported may be a false positive, Robin pointed out some
other DMA-related issues in the driver which are addressed here:
- the DMA max mapping size is irrelevant for the programmed IO mode of
  operation
- we should not call dma_max_mapping_size() on the MMC host platform
  device, but rather the DMA engine device

In addition, it's better to use the device returned from
dmaengine_get_dma_device() for dma_umap_sg() and dma_unmap_sg(), and not
reference the DMA channel device directly.

[0] https://lore.kernel.org/linux-scsi/d82926fe-4557-401d-ae58-4302fef5657c@oracle.com/#t

Signed-off-by: John Garry <john.g.garry@oracle.com>
---
Compile tested only. And I doubt that this change needs to be merged
prior to [0], above.

diff --git a/drivers/mmc/host/bcm2835.c b/drivers/mmc/host/bcm2835.c
index ee63835b3ca0a..a13bb39e53066 100644
--- a/drivers/mmc/host/bcm2835.c
+++ b/drivers/mmc/host/bcm2835.c
@@ -188,7 +188,7 @@ struct bcm2835_host {
 	u32			drain_words;
 	struct page		*drain_page;
 	u32			drain_offset;
-	bool			use_dma;
+	struct device		*dma_dev;
 };
 
 static void bcm2835_dumpcmd(struct bcm2835_host *host, struct mmc_command *cmd,
@@ -494,8 +494,7 @@ void bcm2835_prepare_dma(struct bcm2835_host *host, struct mmc_data *data)
 				     &host->dma_cfg_rx :
 				     &host->dma_cfg_tx);
 
-	sg_len = dma_map_sg(dma_chan->device->dev, data->sg, data->sg_len,
-			    dir_data);
+	sg_len = dma_map_sg(host->dma_dev, data->sg, data->sg_len, dir_data);
 	if (!sg_len)
 		return;
 
@@ -503,8 +502,7 @@ void bcm2835_prepare_dma(struct bcm2835_host *host, struct mmc_data *data)
 				       DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
 
 	if (!desc) {
-		dma_unmap_sg(dma_chan->device->dev, data->sg, data->sg_len,
-			     dir_data);
+		dma_unmap_sg(host->dma_dev, data->sg, data->sg_len, dir_data);
 		return;
 	}
 
@@ -1201,7 +1199,7 @@ static void bcm2835_request(struct mmc_host *mmc, struct mmc_request *mrq)
 		return;
 	}
 
-	if (host->use_dma && mrq->data && (mrq->data->blocks > PIO_THRESHOLD))
+	if (host->dma_dev && mrq->data && (mrq->data->blocks > PIO_THRESHOLD))
 		bcm2835_prepare_dma(host, mrq->data);
 
 	host->use_sbc = !!mrq->sbc && host->mrq->data &&
@@ -1281,10 +1279,8 @@ static int bcm2835_add_host(struct bcm2835_host *host)
 
 	if (!host->dma_chan_rxtx) {
 		dev_warn(dev, "unable to initialise DMA channel. Falling back to PIO\n");
-		host->use_dma = false;
+		host->dma_dev = NULL;
 	} else {
-		host->use_dma = true;
-
 		host->dma_cfg_tx.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
 		host->dma_cfg_tx.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
 		host->dma_cfg_tx.direction = DMA_MEM_TO_DEV;
@@ -1300,12 +1296,18 @@ static int bcm2835_add_host(struct bcm2835_host *host)
 		if (dmaengine_slave_config(host->dma_chan_rxtx,
 					   &host->dma_cfg_tx) != 0 ||
 		    dmaengine_slave_config(host->dma_chan_rxtx,
-					   &host->dma_cfg_rx) != 0)
-			host->use_dma = false;
+					   &host->dma_cfg_rx) != 0) {
+			host->dma_dev =
+				dmaengine_get_dma_device(host->dma_chan_rxtx);
+		}
 	}
 
 	mmc->max_segs = 128;
-	mmc->max_req_size = min_t(size_t, 524288, dma_max_mapping_size(dev));
+	mmc->max_req_size = 524288;
+	if (host->dma_dev) {
+		mmc->max_req_size = min_t(size_t, mmc->max_req_size,
+				dma_max_mapping_size(host->dma_dev));
+	}
 	mmc->max_seg_size = mmc->max_req_size;
 	mmc->max_blk_size = 1024;
 	mmc->max_blk_count =  65535;
@@ -1336,10 +1338,10 @@ static int bcm2835_add_host(struct bcm2835_host *host)
 	}
 
 	pio_limit_string[0] = '\0';
-	if (host->use_dma && (PIO_THRESHOLD > 0))
+	if (host->dma_dev && (PIO_THRESHOLD > 0))
 		sprintf(pio_limit_string, " (>%d)", PIO_THRESHOLD);
 	dev_info(dev, "loaded - DMA %s%s\n",
-		 host->use_dma ? "enabled" : "disabled", pio_limit_string);
+		 host->dma_dev ? "enabled" : "disabled", pio_limit_string);
 
 	return 0;
 }
-- 
2.43.7


             reply	other threads:[~2026-07-06  7:40 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-06  7:39 John Garry [this message]
2026-07-13 11:25 ` [PATCH] mmc: bcm2835: DMA mapping improvements Ulf Hansson
2026-07-13 12:19   ` Robin Murphy
2026-07-13 12:37     ` John Garry
2026-07-13 13:07       ` Ulf Hansson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260706073913.538598-1-john.g.garry@oracle.com \
    --to=john.g.garry@oracle.com \
    --cc=bcm-kernel-feedback-list@broadcom.com \
    --cc=florian.fainelli@broadcom.com \
    --cc=hch@lst.de \
    --cc=linux-mmc@vger.kernel.org \
    --cc=linux-rpi-kernel@lists.infradead.org \
    --cc=martin.petersen@oracle.com \
    --cc=rjui@broadcom.com \
    --cc=robin.murphy@arm.com \
    --cc=sbranden@broadcom.com \
    --cc=ulfh@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox