Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / Atom feed
* remove block layer bounce buffering for MMC v2
@ 2019-02-12  7:25 Christoph Hellwig
  2019-02-12  7:25 ` [PATCH 01/14] scatterlist: add sg_kmap_atomic / sg_kunmap_atomic helpers Christoph Hellwig
                   ` (14 more replies)
  0 siblings, 15 replies; 19+ messages in thread
From: Christoph Hellwig @ 2019-02-12  7:25 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Aaro Koskinen, Nicolas Pitre, linux-mmc, Russell King,
	linux-kernel, iommu, Ben Dooks, linux-omap, linux-arm-kernel

Hi everyone,

this series converts the remaining MMC host drivers to properly kmap the
scatterlist entries it does PIO operations on, and then goes on to
remove the usage of block layer bounce buffering (which I plan to remove
eventually) from the MMC layer.

As a bonus I've converted various drivers to the proper scatterlist
helpers so that at least in theory they are ready for chained
scatterlists.

All the changes are compile tested only as I don't have any of the
hardware, so a careful review would be appreciated.

Changes since v1:
 - fix a missing kunmap_atomic in mvsdio
 - fix a stray whitespace in s3cmci
 - add new sg_kmap_atomic and sg_kunmap_atomic helpers
 - set the DMA and block layer dma boundary
 - use pointer arithmetics to reduce the amount of changes in
   various drivers


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 01/14] scatterlist: add sg_kmap_atomic / sg_kunmap_atomic helpers
  2019-02-12  7:25 remove block layer bounce buffering for MMC v2 Christoph Hellwig
@ 2019-02-12  7:25 ` Christoph Hellwig
  2019-02-12  7:25 ` [PATCH 02/14] mmc: remove the unused use_blk_mq field from struct mmc_host Christoph Hellwig
                   ` (13 subsequent siblings)
  14 siblings, 0 replies; 19+ messages in thread
From: Christoph Hellwig @ 2019-02-12  7:25 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Aaro Koskinen, Nicolas Pitre, linux-mmc, Russell King,
	linux-kernel, iommu, Ben Dooks, linux-omap, linux-arm-kernel

This avoids bug prone open coding of the sg offset handling and
also helps to document the limitations of mapping scatterlist
entries.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 include/linux/scatterlist.h | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h
index b96f0d0b5b8f..524cd8448a48 100644
--- a/include/linux/scatterlist.h
+++ b/include/linux/scatterlist.h
@@ -2,6 +2,7 @@
 #ifndef _LINUX_SCATTERLIST_H
 #define _LINUX_SCATTERLIST_H
 
+#include <linux/highmem.h>
 #include <linux/string.h>
 #include <linux/types.h>
 #include <linux/bug.h>
@@ -239,6 +240,31 @@ static inline void *sg_virt(struct scatterlist *sg)
 	return page_address(sg_page(sg)) + sg->offset;
 }
 
+/**
+ * sg_kmap_atomic - map a S/G list entry to a kernel address
+ * @sg:		scatterlist entry
+ *
+ * Return a kernel address for scatterlist entry by kmapping it.  Note that
+ * this function must only be called on scatterlist entries that do not span
+ * multiple pages.
+ */
+static inline void *sg_kmap_atomic(struct scatterlist *sg)
+{
+	if (WARN_ON_ONCE(sg->offset + sg->length > PAGE_SIZE))
+		return NULL;
+	return kmap_atomic(sg_page(sg)) + sg->offset;
+}
+
+/**
+ * sg_kunmap_atomic - unmap a S/G list entry to a kernel address
+ * @sg:		scatterlist entry
+ * @ptr:	address returned from sg_kmap_atomic
+ */
+static inline void sg_kunmap_atomic(struct scatterlist *sg, void *ptr)
+{
+	kunmap_atomic(ptr - sg->offset);
+}
+
 /**
  * sg_init_marker - Initialize markers in sg table
  * @sgl:	   The SG table
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 02/14] mmc: remove the unused use_blk_mq field from struct mmc_host
  2019-02-12  7:25 remove block layer bounce buffering for MMC v2 Christoph Hellwig
  2019-02-12  7:25 ` [PATCH 01/14] scatterlist: add sg_kmap_atomic / sg_kunmap_atomic helpers Christoph Hellwig
@ 2019-02-12  7:25 ` Christoph Hellwig
  2019-02-12  7:25 ` [PATCH 03/14] mmc: add a need_kmap flag to " Christoph Hellwig
                   ` (12 subsequent siblings)
  14 siblings, 0 replies; 19+ messages in thread
From: Christoph Hellwig @ 2019-02-12  7:25 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Aaro Koskinen, Nicolas Pitre, linux-mmc, Russell King,
	linux-kernel, iommu, Ben Dooks, linux-omap, linux-arm-kernel

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 include/linux/mmc/host.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 4d35ff36ceff..4eadf01b4a93 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -397,7 +397,6 @@ struct mmc_host {
 	unsigned int		doing_retune:1;	/* re-tuning in progress */
 	unsigned int		retune_now:1;	/* do re-tuning at next req */
 	unsigned int		retune_paused:1; /* re-tuning is temporarily disabled */
-	unsigned int		use_blk_mq:1;	/* use blk-mq */
 
 	int			rescan_disable;	/* disable card detection */
 	int			rescan_entered;	/* used with nonremovable devices */
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 03/14] mmc: add a need_kmap flag to struct mmc_host
  2019-02-12  7:25 remove block layer bounce buffering for MMC v2 Christoph Hellwig
  2019-02-12  7:25 ` [PATCH 01/14] scatterlist: add sg_kmap_atomic / sg_kunmap_atomic helpers Christoph Hellwig
  2019-02-12  7:25 ` [PATCH 02/14] mmc: remove the unused use_blk_mq field from struct mmc_host Christoph Hellwig
@ 2019-02-12  7:25 ` " Christoph Hellwig
  2019-02-12  7:25 ` [PATCH 04/14] mmc: davinci: handle highmem pages Christoph Hellwig
                   ` (11 subsequent siblings)
  14 siblings, 0 replies; 19+ messages in thread
From: Christoph Hellwig @ 2019-02-12  7:25 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Aaro Koskinen, Nicolas Pitre, linux-mmc, Russell King,
	linux-kernel, iommu, Ben Dooks, linux-omap, linux-arm-kernel

If we want to get rid of the block layer bounce buffering for highmem we
need to ensure no segment spans multiple pages so that we can kmap it.
Add a flag to struct mmc_host so that we can handle the block and DMA
layer interactions in common code.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 drivers/mmc/core/queue.c | 13 +++++++++++++
 include/linux/mmc/host.h |  1 +
 2 files changed, 14 insertions(+)

diff --git a/drivers/mmc/core/queue.c b/drivers/mmc/core/queue.c
index 35cc138b096d..71cd2411329e 100644
--- a/drivers/mmc/core/queue.c
+++ b/drivers/mmc/core/queue.c
@@ -370,6 +370,19 @@ static void mmc_setup_queue(struct mmc_queue *mq, struct mmc_card *card)
 	blk_queue_max_segments(mq->queue, host->max_segs);
 	blk_queue_max_segment_size(mq->queue, host->max_seg_size);
 
+	/*
+	 * If the host requires kmapping for PIO we need to ensure
+	 * that no segment spans a page boundary.
+	 */
+	if (host->need_kmap) {
+		unsigned int dma_boundary = host->max_seg_size - 1;
+
+		if (dma_boundary >= PAGE_SIZE)
+			dma_boundary = PAGE_SIZE - 1;
+		blk_queue_segment_boundary(mq->queue, dma_boundary);
+		dma_set_seg_boundary(mmc_dev(host), dma_boundary);
+	}
+
 	INIT_WORK(&mq->recovery_work, mmc_mq_recovery_handler);
 	INIT_WORK(&mq->complete_work, mmc_blk_mq_complete_work);
 
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 4eadf01b4a93..87f8a89d2f70 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -397,6 +397,7 @@ struct mmc_host {
 	unsigned int		doing_retune:1;	/* re-tuning in progress */
 	unsigned int		retune_now:1;	/* do re-tuning at next req */
 	unsigned int		retune_paused:1; /* re-tuning is temporarily disabled */
+	unsigned int		need_kmap:1;	/* only allow single page segments */
 
 	int			rescan_disable;	/* disable card detection */
 	int			rescan_entered;	/* used with nonremovable devices */
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 04/14] mmc: davinci: handle highmem pages
  2019-02-12  7:25 remove block layer bounce buffering for MMC v2 Christoph Hellwig
                   ` (2 preceding siblings ...)
  2019-02-12  7:25 ` [PATCH 03/14] mmc: add a need_kmap flag to " Christoph Hellwig
@ 2019-02-12  7:25 ` Christoph Hellwig
  2019-02-12  7:25 ` [PATCH 05/14] mmc: moxart: " Christoph Hellwig
                   ` (10 subsequent siblings)
  14 siblings, 0 replies; 19+ messages in thread
From: Christoph Hellwig @ 2019-02-12  7:25 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Aaro Koskinen, Nicolas Pitre, linux-mmc, Russell King,
	linux-kernel, iommu, Ben Dooks, linux-omap, linux-arm-kernel

Instead of setting up a kernel pointer to track the current PIO address,
track the offset in the current page, and do an atomic kmap for the page
while doing the actual PIO operations.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 drivers/mmc/host/davinci_mmc.c | 22 +++++++++++++---------
 1 file changed, 13 insertions(+), 9 deletions(-)

diff --git a/drivers/mmc/host/davinci_mmc.c b/drivers/mmc/host/davinci_mmc.c
index 9e68c3645e22..6a16d7a1d5bc 100644
--- a/drivers/mmc/host/davinci_mmc.c
+++ b/drivers/mmc/host/davinci_mmc.c
@@ -194,11 +194,12 @@ struct mmc_davinci_host {
 #define DAVINCI_MMC_DATADIR_WRITE	2
 	unsigned char data_dir;
 
-	/* buffer is used during PIO of one scatterlist segment, and
-	 * is updated along with buffer_bytes_left.  bytes_left applies
-	 * to all N blocks of the PIO transfer.
+	/*
+	 * buffer_offset is used during PIO of one scatterlist segment, and is
+	 * updated along with buffer_bytes_left.  bytes_left applies to all N
+	 * blocks of the PIO transfer.
 	 */
-	u8 *buffer;
+	u32 buffer_offset;
 	u32 buffer_bytes_left;
 	u32 bytes_left;
 
@@ -229,8 +230,8 @@ static irqreturn_t mmc_davinci_irq(int irq, void *dev_id);
 /* PIO only */
 static void mmc_davinci_sg_to_buf(struct mmc_davinci_host *host)
 {
+	host->buffer_offset = host->sg->offset;
 	host->buffer_bytes_left = sg_dma_len(host->sg);
-	host->buffer = sg_virt(host->sg);
 	if (host->buffer_bytes_left > host->bytes_left)
 		host->buffer_bytes_left = host->bytes_left;
 }
@@ -238,7 +239,7 @@ static void mmc_davinci_sg_to_buf(struct mmc_davinci_host *host)
 static void davinci_fifo_data_trans(struct mmc_davinci_host *host,
 					unsigned int n)
 {
-	u8 *p;
+	u8 *p, *base;
 	unsigned int i;
 
 	if (host->buffer_bytes_left == 0) {
@@ -246,7 +247,8 @@ static void davinci_fifo_data_trans(struct mmc_davinci_host *host,
 		mmc_davinci_sg_to_buf(host);
 	}
 
-	p = host->buffer;
+	base = sg_kmap_atomic(host->sg);
+	p = base + host->buffer_offset;
 	if (n > host->buffer_bytes_left)
 		n = host->buffer_bytes_left;
 	host->buffer_bytes_left -= n;
@@ -275,7 +277,8 @@ static void davinci_fifo_data_trans(struct mmc_davinci_host *host,
 			p = p + (n & 3);
 		}
 	}
-	host->buffer = p;
+	host->buffer_offset = p - base;
+	sg_kunmap_atomic(host->sg, base);
 }
 
 static void mmc_davinci_start_command(struct mmc_davinci_host *host,
@@ -572,7 +575,7 @@ mmc_davinci_prepare_data(struct mmc_davinci_host *host, struct mmc_request *req)
 			host->base + DAVINCI_MMCFIFOCTL);
 	}
 
-	host->buffer = NULL;
+	host->buffer_offset = 0;
 	host->bytes_left = data->blocks * data->blksz;
 
 	/* For now we try to use DMA whenever we won't need partial FIFO
@@ -1291,6 +1294,7 @@ static int davinci_mmcsd_probe(struct platform_device *pdev)
 
 	mmc->ops = &mmc_davinci_ops;
 	mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
+	mmc->need_kmap = 1;
 
 	/* With no iommu coalescing pages, each phys_seg is a hw_seg.
 	 * Each hw_seg uses one EDMA parameter RAM slot, always one
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 05/14] mmc: moxart: handle highmem pages
  2019-02-12  7:25 remove block layer bounce buffering for MMC v2 Christoph Hellwig
                   ` (3 preceding siblings ...)
  2019-02-12  7:25 ` [PATCH 04/14] mmc: davinci: handle highmem pages Christoph Hellwig
@ 2019-02-12  7:25 ` " Christoph Hellwig
  2019-02-12  7:25 ` [PATCH 06/14] mmc: omap: " Christoph Hellwig
                   ` (9 subsequent siblings)
  14 siblings, 0 replies; 19+ messages in thread
From: Christoph Hellwig @ 2019-02-12  7:25 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Aaro Koskinen, Nicolas Pitre, linux-mmc, Russell King,
	linux-kernel, iommu, Ben Dooks, linux-omap, linux-arm-kernel

Instead of setting up a kernel pointer to track the current PIO address,
track the offset in the current page, and do a kmap for the page while
doing the actual PIO operations.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 drivers/mmc/host/moxart-mmc.c | 20 ++++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/drivers/mmc/host/moxart-mmc.c b/drivers/mmc/host/moxart-mmc.c
index a0670e9cd012..116964e6506d 100644
--- a/drivers/mmc/host/moxart-mmc.c
+++ b/drivers/mmc/host/moxart-mmc.c
@@ -311,7 +311,7 @@ static void moxart_transfer_pio(struct moxart_host *host)
 	if (host->data_len == data->bytes_xfered)
 		return;
 
-	sgp = sg_virt(host->cur_sg);
+	sgp = kmap(sg_page(host->cur_sg)) + host->cur_sg->offset;
 	remain = host->data_remain;
 
 	if (data->flags & MMC_DATA_WRITE) {
@@ -319,8 +319,7 @@ static void moxart_transfer_pio(struct moxart_host *host)
 			if (moxart_wait_for_status(host, FIFO_URUN, &status)
 			     == -ETIMEDOUT) {
 				data->error = -ETIMEDOUT;
-				complete(&host->pio_complete);
-				return;
+				goto done;
 			}
 			for (len = 0; len < remain && len < host->fifo_width;) {
 				iowrite32(*sgp, host->base + REG_DATA_WINDOW);
@@ -335,8 +334,7 @@ static void moxart_transfer_pio(struct moxart_host *host)
 			if (moxart_wait_for_status(host, FIFO_ORUN, &status)
 			    == -ETIMEDOUT) {
 				data->error = -ETIMEDOUT;
-				complete(&host->pio_complete);
-				return;
+				goto done;
 			}
 			for (len = 0; len < remain && len < host->fifo_width;) {
 				/* SCR data must be read in big endian. */
@@ -356,10 +354,15 @@ static void moxart_transfer_pio(struct moxart_host *host)
 	data->bytes_xfered += host->data_remain - remain;
 	host->data_remain = remain;
 
-	if (host->data_len != data->bytes_xfered)
+	if (host->data_len != data->bytes_xfered) {
+		kunmap(sg_page(host->cur_sg));
 		moxart_next_sg(host);
-	else
-		complete(&host->pio_complete);
+		return;
+	}
+
+done:
+	kunmap(sg_page(host->cur_sg));
+	complete(&host->pio_complete);
 }
 
 static void moxart_prepare_data(struct moxart_host *host)
@@ -614,6 +617,7 @@ static int moxart_probe(struct platform_device *pdev)
 	spin_lock_init(&host->lock);
 
 	mmc->ops = &moxart_ops;
+	mmc->need_kmap = 1;
 	mmc->f_max = DIV_ROUND_CLOSEST(host->sysclk, 2);
 	mmc->f_min = DIV_ROUND_CLOSEST(host->sysclk, CLK_DIV_MASK * 2);
 	mmc->ocr_avail = 0xffff00;	/* Support 2.0v - 3.6v power. */
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 06/14] mmc: omap: handle highmem pages
  2019-02-12  7:25 remove block layer bounce buffering for MMC v2 Christoph Hellwig
                   ` (4 preceding siblings ...)
  2019-02-12  7:25 ` [PATCH 05/14] mmc: moxart: " Christoph Hellwig
@ 2019-02-12  7:25 ` " Christoph Hellwig
  2019-02-12 18:39   ` Tony Lindgren
  2019-02-12  7:25 ` [PATCH 07/14] mmc: omap: handle chained sglists Christoph Hellwig
                   ` (8 subsequent siblings)
  14 siblings, 1 reply; 19+ messages in thread
From: Christoph Hellwig @ 2019-02-12  7:25 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Aaro Koskinen, Nicolas Pitre, linux-mmc, Russell King,
	linux-kernel, iommu, Ben Dooks, linux-omap, linux-arm-kernel

Instead of setting up a kernel pointer to track the current PIO address,
track the offset in the current page, and do an atomic kmap for the page
while doing the actual PIO operations.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 drivers/mmc/host/omap.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c
index c60a7625b1fa..6741c95f2281 100644
--- a/drivers/mmc/host/omap.c
+++ b/drivers/mmc/host/omap.c
@@ -148,7 +148,7 @@ struct mmc_omap_host {
 
 	unsigned int		sg_len;
 	int			sg_idx;
-	u16 *			buffer;
+	u32			buffer_offset;
 	u32			buffer_bytes_left;
 	u32			total_bytes_left;
 
@@ -649,7 +649,7 @@ mmc_omap_sg_to_buf(struct mmc_omap_host *host)
 
 	sg = host->data->sg + host->sg_idx;
 	host->buffer_bytes_left = sg->length;
-	host->buffer = sg_virt(sg);
+	host->buffer_offset = sg->offset;
 	if (host->buffer_bytes_left > host->total_bytes_left)
 		host->buffer_bytes_left = host->total_bytes_left;
 }
@@ -666,7 +666,9 @@ mmc_omap_clk_timer(struct timer_list *t)
 static void
 mmc_omap_xfer_data(struct mmc_omap_host *host, int write)
 {
+	struct scatterlist *sg = host->data->sg + host->sg_idx;
 	int n, nwords;
+	void *p;
 
 	if (host->buffer_bytes_left == 0) {
 		host->sg_idx++;
@@ -684,15 +686,17 @@ mmc_omap_xfer_data(struct mmc_omap_host *host, int write)
 	host->total_bytes_left -= n;
 	host->data->bytes_xfered += n;
 
+	p = sg_kmap_atomic(sg);
 	if (write) {
 		__raw_writesw(host->virt_base + OMAP_MMC_REG(host, DATA),
-			      host->buffer, nwords);
+			      p + host->buffer_offset, nwords);
 	} else {
 		__raw_readsw(host->virt_base + OMAP_MMC_REG(host, DATA),
-			     host->buffer, nwords);
+			     p + host->buffer_offset, nwords);
 	}
+	sg_kunmap_atomic(sg, p);
 
-	host->buffer += nwords;
+	host->buffer_offset += nwords;
 }
 
 #ifdef CONFIG_MMC_DEBUG
@@ -1250,6 +1254,7 @@ static int mmc_omap_new_slot(struct mmc_omap_host *host, int id)
 		mmc->caps |= MMC_CAP_4_BIT_DATA | MMC_CAP_ERASE;
 
 	mmc->ops = &mmc_omap_ops;
+	mmc->need_kmap = 1;
 	mmc->f_min = 400000;
 
 	if (mmc_omap2())
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 07/14] mmc: omap: handle chained sglists
  2019-02-12  7:25 remove block layer bounce buffering for MMC v2 Christoph Hellwig
                   ` (5 preceding siblings ...)
  2019-02-12  7:25 ` [PATCH 06/14] mmc: omap: " Christoph Hellwig
@ 2019-02-12  7:25 ` Christoph Hellwig
  2019-02-12  7:25 ` [PATCH 08/14] mmc: s3cmci: handle highmem pages Christoph Hellwig
                   ` (7 subsequent siblings)
  14 siblings, 0 replies; 19+ messages in thread
From: Christoph Hellwig @ 2019-02-12  7:25 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Aaro Koskinen, Nicolas Pitre, linux-mmc, Russell King,
	linux-kernel, iommu, Ben Dooks, linux-omap, linux-arm-kernel

Use the proper sg_next() helper to move to the next scatterlist element
to support chained scatterlists.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 drivers/mmc/host/omap.c | 16 ++++++----------
 1 file changed, 6 insertions(+), 10 deletions(-)

diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c
index 6741c95f2281..8cd39bc087fa 100644
--- a/drivers/mmc/host/omap.c
+++ b/drivers/mmc/host/omap.c
@@ -147,7 +147,7 @@ struct mmc_omap_host {
 	struct mmc_data		*stop_data;
 
 	unsigned int		sg_len;
-	int			sg_idx;
+	struct scatterlist	*cur_sg;
 	u32			buffer_offset;
 	u32			buffer_bytes_left;
 	u32			total_bytes_left;
@@ -645,11 +645,8 @@ mmc_omap_cmd_timer(struct timer_list *t)
 static void
 mmc_omap_sg_to_buf(struct mmc_omap_host *host)
 {
-	struct scatterlist *sg;
-
-	sg = host->data->sg + host->sg_idx;
-	host->buffer_bytes_left = sg->length;
-	host->buffer_offset = sg->offset;
+	host->buffer_bytes_left = host->cur_sg->length;
+	host->buffer_offset = host->cur_sg->offset;
 	if (host->buffer_bytes_left > host->total_bytes_left)
 		host->buffer_bytes_left = host->total_bytes_left;
 }
@@ -666,13 +663,12 @@ mmc_omap_clk_timer(struct timer_list *t)
 static void
 mmc_omap_xfer_data(struct mmc_omap_host *host, int write)
 {
-	struct scatterlist *sg = host->data->sg + host->sg_idx;
+	struct scatterlist *sg = host->cur_sg;
 	int n, nwords;
 	void *p;
 
 	if (host->buffer_bytes_left == 0) {
-		host->sg_idx++;
-		BUG_ON(host->sg_idx == host->sg_len);
+		host->cur_sg = sg_next(host->cur_sg);
 		mmc_omap_sg_to_buf(host);
 	}
 	n = 64;
@@ -984,7 +980,7 @@ mmc_omap_prepare_data(struct mmc_omap_host *host, struct mmc_request *req)
 		}
 	}
 
-	host->sg_idx = 0;
+	host->cur_sg = host->data->sg;
 	if (use_dma) {
 		enum dma_data_direction dma_data_dir;
 		struct dma_async_tx_descriptor *tx;
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 08/14] mmc: s3cmci: handle highmem pages
  2019-02-12  7:25 remove block layer bounce buffering for MMC v2 Christoph Hellwig
                   ` (6 preceding siblings ...)
  2019-02-12  7:25 ` [PATCH 07/14] mmc: omap: handle chained sglists Christoph Hellwig
@ 2019-02-12  7:25 ` Christoph Hellwig
  2019-02-12  7:25 ` [PATCH 09/14] mmc: s3cmci: handle chained sglists Christoph Hellwig
                   ` (6 subsequent siblings)
  14 siblings, 0 replies; 19+ messages in thread
From: Christoph Hellwig @ 2019-02-12  7:25 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Aaro Koskinen, Nicolas Pitre, linux-mmc, Russell King,
	linux-kernel, iommu, Ben Dooks, linux-omap, linux-arm-kernel

Instead of setting up a kernel pointer to track the current PIO address,
track the offset in the current page, and do an atomic kmap for the page
while doing the actual PIO operations.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 drivers/mmc/host/s3cmci.c | 107 +++++++++++++++++++-------------------
 drivers/mmc/host/s3cmci.h |   3 +-
 2 files changed, 55 insertions(+), 55 deletions(-)

diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c
index 10f5219b3b40..989fefea19f1 100644
--- a/drivers/mmc/host/s3cmci.c
+++ b/drivers/mmc/host/s3cmci.c
@@ -317,26 +317,17 @@ static void s3cmci_check_sdio_irq(struct s3cmci_host *host)
 	}
 }
 
-static inline int get_data_buffer(struct s3cmci_host *host,
-				  u32 *bytes, u32 **pointer)
+static inline int get_data_buffer(struct s3cmci_host *host)
 {
-	struct scatterlist *sg;
-
-	if (host->pio_active == XFER_NONE)
-		return -EINVAL;
-
-	if ((!host->mrq) || (!host->mrq->data))
-		return -EINVAL;
-
 	if (host->pio_sgptr >= host->mrq->data->sg_len) {
 		dbg(host, dbg_debug, "no more buffers (%i/%i)\n",
 		      host->pio_sgptr, host->mrq->data->sg_len);
 		return -EBUSY;
 	}
-	sg = &host->mrq->data->sg[host->pio_sgptr];
+	host->cur_sg = &host->mrq->data->sg[host->pio_sgptr];
 
-	*bytes = sg->length;
-	*pointer = sg_virt(sg);
+	host->pio_bytes = host->cur_sg->length;
+	host->pio_offset = host->cur_sg->offset;
 
 	host->pio_sgptr++;
 
@@ -422,11 +413,16 @@ static void s3cmci_disable_irq(struct s3cmci_host *host, bool transfer)
 
 static void do_pio_read(struct s3cmci_host *host)
 {
-	int res;
 	u32 fifo;
 	u32 *ptr;
 	u32 fifo_words;
 	void __iomem *from_ptr;
+	void *buf;
+
+	if (host->pio_active == XFER_NONE)
+		goto done;
+	if (!host->mrq || !host->mrq->data)
+		goto done;
 
 	/* write real prescaler to host, it might be set slow to fix */
 	writel(host->prescaler, host->base + S3C2410_SDIPRE);
@@ -435,20 +431,12 @@ static void do_pio_read(struct s3cmci_host *host)
 
 	while ((fifo = fifo_count(host))) {
 		if (!host->pio_bytes) {
-			res = get_data_buffer(host, &host->pio_bytes,
-					      &host->pio_ptr);
-			if (res) {
-				host->pio_active = XFER_NONE;
-				host->complete_what = COMPLETION_FINALIZE;
-
-				dbg(host, dbg_pio, "pio_read(): "
-				    "complete (no more data).\n");
-				return;
-			}
+			if (get_data_buffer(host) < 0)
+				goto done;
 
 			dbg(host, dbg_pio,
-			    "pio_read(): new target: [%i]@[%p]\n",
-			    host->pio_bytes, host->pio_ptr);
+			    "pio_read(): new target: [%i]@[%zu]\n",
+			    host->pio_bytes, host->pio_offset);
 		}
 
 		dbg(host, dbg_pio,
@@ -470,63 +458,65 @@ static void do_pio_read(struct s3cmci_host *host)
 		host->pio_count += fifo;
 
 		fifo_words = fifo >> 2;
-		ptr = host->pio_ptr;
-		while (fifo_words--)
+
+		buf = (sg_kmap_atomic(host->cur_sg) + host->pio_offset);
+		ptr = buf;
+		while (fifo_words--) {
 			*ptr++ = readl(from_ptr);
-		host->pio_ptr = ptr;
+			host->pio_offset += 4;
+		}
 
 		if (fifo & 3) {
 			u32 n = fifo & 3;
 			u32 data = readl(from_ptr);
-			u8 *p = (u8 *)host->pio_ptr;
+			u8 *p = (u8 *)ptr;
 
 			while (n--) {
 				*p++ = data;
 				data >>= 8;
+				host->pio_offset++;
 			}
 		}
+		sg_kunmap_atomic(host->cur_sg, buf);
 	}
 
 	if (!host->pio_bytes) {
-		res = get_data_buffer(host, &host->pio_bytes, &host->pio_ptr);
-		if (res) {
-			dbg(host, dbg_pio,
-			    "pio_read(): complete (no more buffers).\n");
-			host->pio_active = XFER_NONE;
-			host->complete_what = COMPLETION_FINALIZE;
-
-			return;
-		}
+		if (get_data_buffer(host) < 0)
+			goto done;
 	}
 
 	enable_imask(host,
 		     S3C2410_SDIIMSK_RXFIFOHALF | S3C2410_SDIIMSK_RXFIFOLAST);
+	return;
+
+done:
+	host->pio_active = XFER_NONE;
+	host->complete_what = COMPLETION_FINALIZE;
+	dbg(host, dbg_pio, "pio_read(): complete (no more data).\n");
 }
 
 static void do_pio_write(struct s3cmci_host *host)
 {
 	void __iomem *to_ptr;
-	int res;
+	void *buf;
 	u32 fifo;
 	u32 *ptr;
 
+	if (host->pio_active == XFER_NONE)
+		goto done;
+	if (!host->mrq || !host->mrq->data)
+		goto done;
+
 	to_ptr = host->base + host->sdidata;
 
 	while ((fifo = fifo_free(host)) > 3) {
 		if (!host->pio_bytes) {
-			res = get_data_buffer(host, &host->pio_bytes,
-							&host->pio_ptr);
-			if (res) {
-				dbg(host, dbg_pio,
-				    "pio_write(): complete (no more data).\n");
-				host->pio_active = XFER_NONE;
-
-				return;
-			}
+			if (get_data_buffer(host) < 0)
+				goto done;
 
 			dbg(host, dbg_pio,
-			    "pio_write(): new source: [%i]@[%p]\n",
-			    host->pio_bytes, host->pio_ptr);
+			    "pio_write(): new source: [%i]@[%zd]\n",
+			    host->pio_bytes, host->pio_offset);
 
 		}
 
@@ -543,13 +533,20 @@ static void do_pio_write(struct s3cmci_host *host)
 		host->pio_count += fifo;
 
 		fifo = (fifo + 3) >> 2;
-		ptr = host->pio_ptr;
-		while (fifo--)
+		buf = (sg_kmap_atomic(host->cur_sg) + host->pio_offset);
+		ptr = buf;
+		while (fifo--) {
 			writel(*ptr++, to_ptr);
-		host->pio_ptr = ptr;
+			host->pio_offset += 4;
+		}
+		sg_kunmap_atomic(host->cur_sg, buf);
 	}
 
 	enable_imask(host, S3C2410_SDIIMSK_TXFIFOHALF);
+	return;
+done:
+	dbg(host, dbg_pio, "pio_write(): complete (no more data).\n");
+	host->pio_active = XFER_NONE;
 }
 
 static void pio_tasklet(unsigned long data)
@@ -1055,6 +1052,7 @@ static int s3cmci_prepare_pio(struct s3cmci_host *host, struct mmc_data *data)
 	BUG_ON((data->flags & BOTH_DIR) == BOTH_DIR);
 
 	host->pio_sgptr = 0;
+	host->cur_sg = &host->mrq->data->sg[host->pio_sgptr];
 	host->pio_bytes = 0;
 	host->pio_count = 0;
 	host->pio_active = rw ? XFER_WRITE : XFER_READ;
@@ -1678,6 +1676,7 @@ static int s3cmci_probe(struct platform_device *pdev)
 	host->clk_rate = clk_get_rate(host->clk);
 
 	mmc->ops 	= &s3cmci_ops;
+	mmc->need_kmap	= 1;
 	mmc->ocr_avail	= MMC_VDD_32_33 | MMC_VDD_33_34;
 #ifdef CONFIG_MMC_S3C_HW_SDIO_IRQ
 	mmc->caps	= MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ;
diff --git a/drivers/mmc/host/s3cmci.h b/drivers/mmc/host/s3cmci.h
index 30c2c0dd1bc8..4320f7d832dc 100644
--- a/drivers/mmc/host/s3cmci.h
+++ b/drivers/mmc/host/s3cmci.h
@@ -50,10 +50,11 @@ struct s3cmci_host {
 
 	int			dma_complete;
 
+	struct scatterlist	*cur_sg;
 	u32			pio_sgptr;
 	u32			pio_bytes;
 	u32			pio_count;
-	u32			*pio_ptr;
+	u32			pio_offset;
 #define XFER_NONE 0
 #define XFER_READ 1
 #define XFER_WRITE 2
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 09/14] mmc: s3cmci: handle chained sglists
  2019-02-12  7:25 remove block layer bounce buffering for MMC v2 Christoph Hellwig
                   ` (7 preceding siblings ...)
  2019-02-12  7:25 ` [PATCH 08/14] mmc: s3cmci: handle highmem pages Christoph Hellwig
@ 2019-02-12  7:25 ` Christoph Hellwig
  2019-02-12  7:25 ` [PATCH 10/14] mmc: mvsdio: handle highmem pages Christoph Hellwig
                   ` (5 subsequent siblings)
  14 siblings, 0 replies; 19+ messages in thread
From: Christoph Hellwig @ 2019-02-12  7:25 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Aaro Koskinen, Nicolas Pitre, linux-mmc, Russell King,
	linux-kernel, iommu, Ben Dooks, linux-omap, linux-arm-kernel

Use the proper sg_next() helper to move to the next scatterlist element
to support chained scatterlists.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 drivers/mmc/host/s3cmci.c | 19 +++++++++----------
 drivers/mmc/host/s3cmci.h |  2 +-
 2 files changed, 10 insertions(+), 11 deletions(-)

diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c
index 989fefea19f1..df7c27f78abf 100644
--- a/drivers/mmc/host/s3cmci.c
+++ b/drivers/mmc/host/s3cmci.c
@@ -319,20 +319,19 @@ static void s3cmci_check_sdio_irq(struct s3cmci_host *host)
 
 static inline int get_data_buffer(struct s3cmci_host *host)
 {
-	if (host->pio_sgptr >= host->mrq->data->sg_len) {
-		dbg(host, dbg_debug, "no more buffers (%i/%i)\n",
-		      host->pio_sgptr, host->mrq->data->sg_len);
+	if (!host->next_sg) {
+		dbg(host, dbg_debug, "no more buffers (%i)\n",
+		      host->mrq->data->sg_len);
 		return -EBUSY;
 	}
-	host->cur_sg = &host->mrq->data->sg[host->pio_sgptr];
+	host->cur_sg = host->next_sg;
+	host->next_sg = sg_next(host->next_sg);
 
 	host->pio_bytes = host->cur_sg->length;
 	host->pio_offset = host->cur_sg->offset;
 
-	host->pio_sgptr++;
-
-	dbg(host, dbg_sg, "new buffer (%i/%i)\n",
-	    host->pio_sgptr, host->mrq->data->sg_len);
+	dbg(host, dbg_sg, "new buffer (%i)\n",
+	    host->mrq->data->sg_len);
 
 	return 0;
 }
@@ -1051,8 +1050,8 @@ static int s3cmci_prepare_pio(struct s3cmci_host *host, struct mmc_data *data)
 
 	BUG_ON((data->flags & BOTH_DIR) == BOTH_DIR);
 
-	host->pio_sgptr = 0;
-	host->cur_sg = &host->mrq->data->sg[host->pio_sgptr];
+	host->cur_sg = host->mrq->data->sg;
+	host->next_sg = sg_next(host->cur_sg);
 	host->pio_bytes = 0;
 	host->pio_count = 0;
 	host->pio_active = rw ? XFER_WRITE : XFER_READ;
diff --git a/drivers/mmc/host/s3cmci.h b/drivers/mmc/host/s3cmci.h
index 4320f7d832dc..caf1078d07d1 100644
--- a/drivers/mmc/host/s3cmci.h
+++ b/drivers/mmc/host/s3cmci.h
@@ -51,7 +51,7 @@ struct s3cmci_host {
 	int			dma_complete;
 
 	struct scatterlist	*cur_sg;
-	u32			pio_sgptr;
+	struct scatterlist	*next_sg;
 	u32			pio_bytes;
 	u32			pio_count;
 	u32			pio_offset;
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 10/14] mmc: mvsdio: handle highmem pages
  2019-02-12  7:25 remove block layer bounce buffering for MMC v2 Christoph Hellwig
                   ` (8 preceding siblings ...)
  2019-02-12  7:25 ` [PATCH 09/14] mmc: s3cmci: handle chained sglists Christoph Hellwig
@ 2019-02-12  7:25 ` Christoph Hellwig
  2019-02-12  7:25 ` [PATCH 11/14] mmc: sh_mmcif: " Christoph Hellwig
                   ` (4 subsequent siblings)
  14 siblings, 0 replies; 19+ messages in thread
From: Christoph Hellwig @ 2019-02-12  7:25 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Aaro Koskinen, Nicolas Pitre, linux-mmc, Russell King,
	linux-kernel, iommu, Ben Dooks, linux-omap, linux-arm-kernel

Instead of setting up a kernel pointer to track the current PIO address,
track the offset in the current page, and do an atomic kmap for the page
while doing the actual PIO operations.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 drivers/mmc/host/mvsdio.c | 33 +++++++++++++++++++++------------
 1 file changed, 21 insertions(+), 12 deletions(-)

diff --git a/drivers/mmc/host/mvsdio.c b/drivers/mmc/host/mvsdio.c
index e22bbff89c8d..d04c78125a4d 100644
--- a/drivers/mmc/host/mvsdio.c
+++ b/drivers/mmc/host/mvsdio.c
@@ -42,7 +42,8 @@ struct mvsd_host {
 	unsigned int intr_en;
 	unsigned int ctrl;
 	unsigned int pio_size;
-	void *pio_ptr;
+	struct scatterlist *pio_sg;
+	unsigned int pio_offset; /* offset in words into the segment */
 	unsigned int sg_frags;
 	unsigned int ns_per_clk;
 	unsigned int clock;
@@ -96,9 +97,9 @@ static int mvsd_setup_data(struct mvsd_host *host, struct mmc_data *data)
 	if (tmout_index > MVSD_HOST_CTRL_TMOUT_MAX)
 		tmout_index = MVSD_HOST_CTRL_TMOUT_MAX;
 
-	dev_dbg(host->dev, "data %s at 0x%08x: blocks=%d blksz=%d tmout=%u (%d)\n",
+	dev_dbg(host->dev, "data %s at 0x%08llx: blocks=%d blksz=%d tmout=%u (%d)\n",
 		(data->flags & MMC_DATA_READ) ? "read" : "write",
-		(u32)sg_virt(data->sg), data->blocks, data->blksz,
+		(u64)sg_phys(data->sg), data->blocks, data->blksz,
 		tmout, tmout_index);
 
 	host->ctrl &= ~MVSD_HOST_CTRL_TMOUT_MASK;
@@ -118,10 +119,11 @@ static int mvsd_setup_data(struct mvsd_host *host, struct mmc_data *data)
 		 * boundary.
 		 */
 		host->pio_size = data->blocks * data->blksz;
-		host->pio_ptr = sg_virt(data->sg);
+		host->pio_sg = data->sg;
+		host->pio_offset = data->sg->offset / 2;
 		if (!nodma)
-			dev_dbg(host->dev, "fallback to PIO for data at 0x%p size %d\n",
-				host->pio_ptr, host->pio_size);
+			dev_dbg(host->dev, "fallback to PIO for data at 0x%x size %d\n",
+				host->pio_offset, host->pio_size);
 		return 1;
 	} else {
 		dma_addr_t phys_addr;
@@ -291,8 +293,9 @@ static u32 mvsd_finish_data(struct mvsd_host *host, struct mmc_data *data,
 {
 	void __iomem *iobase = host->base;
 
-	if (host->pio_ptr) {
-		host->pio_ptr = NULL;
+	if (host->pio_sg) {
+		host->pio_sg = NULL;
+		host->pio_offset = 0;
 		host->pio_size = 0;
 	} else {
 		dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->sg_frags,
@@ -376,8 +379,10 @@ static irqreturn_t mvsd_irq(int irq, void *dev)
 	if (host->pio_size &&
 	    (intr_status & host->intr_en &
 	     (MVSD_NOR_RX_READY | MVSD_NOR_RX_FIFO_8W))) {
-		u16 *p = host->pio_ptr;
+		u16 *base = sg_kmap_atomic(host->pio_sg);
+		u16 *p = base + host->pio_offset;
 		int s = host->pio_size;
+
 		while (s >= 32 && (intr_status & MVSD_NOR_RX_FIFO_8W)) {
 			readsw(iobase + MVSD_FIFO, p, 16);
 			p += 16;
@@ -416,13 +421,15 @@ static irqreturn_t mvsd_irq(int irq, void *dev)
 		}
 		dev_dbg(host->dev, "pio %d intr 0x%04x hw_state 0x%04x\n",
 			s, intr_status, mvsd_read(MVSD_HW_STATE));
-		host->pio_ptr = p;
+		host->pio_offset = p - base;
 		host->pio_size = s;
+		sg_kunmap_atomic(host->pio_sg, base);
 		irq_handled = 1;
 	} else if (host->pio_size &&
 		   (intr_status & host->intr_en &
 		    (MVSD_NOR_TX_AVAIL | MVSD_NOR_TX_FIFO_8W))) {
-		u16 *p = host->pio_ptr;
+		u16 *base = sg_kmap_atomic(host->pio_sg);
+		u16 *p = base + host->pio_offset;
 		int s = host->pio_size;
 		/*
 		 * The TX_FIFO_8W bit is unreliable. When set, bursting
@@ -453,8 +460,9 @@ static irqreturn_t mvsd_irq(int irq, void *dev)
 		}
 		dev_dbg(host->dev, "pio %d intr 0x%04x hw_state 0x%04x\n",
 			s, intr_status, mvsd_read(MVSD_HW_STATE));
-		host->pio_ptr = p;
+		host->pio_offset = p - base;
 		host->pio_size = s;
+		sg_kunmap_atomic(host->pio_sg, base);
 		irq_handled = 1;
 	}
 
@@ -737,6 +745,7 @@ static int mvsd_probe(struct platform_device *pdev)
 	clk_prepare_enable(host->clk);
 
 	mmc->ops = &mvsd_ops;
+	mmc->need_kmap = 1;
 
 	mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
 
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 11/14] mmc: sh_mmcif: handle highmem pages
  2019-02-12  7:25 remove block layer bounce buffering for MMC v2 Christoph Hellwig
                   ` (9 preceding siblings ...)
  2019-02-12  7:25 ` [PATCH 10/14] mmc: mvsdio: handle highmem pages Christoph Hellwig
@ 2019-02-12  7:25 ` " Christoph Hellwig
  2019-02-12  7:25 ` [PATCH 12/14] mmc: sh_mmcif: handle chained sglists Christoph Hellwig
                   ` (3 subsequent siblings)
  14 siblings, 0 replies; 19+ messages in thread
From: Christoph Hellwig @ 2019-02-12  7:25 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Aaro Koskinen, Nicolas Pitre, linux-mmc, Russell King,
	linux-kernel, iommu, Ben Dooks, linux-omap, linux-arm-kernel

Instead of setting up a kernel pointer to track the current PIO address,
track the offset in the current page, and do an atomic kmap for the page
while doing the actual PIO operations.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 drivers/mmc/host/sh_mmcif.c | 59 +++++++++++++++++++++++--------------
 1 file changed, 37 insertions(+), 22 deletions(-)

diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
index 81bd9afb0980..24c3f13bafdb 100644
--- a/drivers/mmc/host/sh_mmcif.c
+++ b/drivers/mmc/host/sh_mmcif.c
@@ -228,7 +228,7 @@ struct sh_mmcif_host {
 	bool dying;
 	long timeout;
 	void __iomem *addr;
-	u32 *pio_ptr;
+	u32 pio_offset;
 	spinlock_t lock;		/* protect sh_mmcif_host::state */
 	enum sh_mmcif_state state;
 	enum sh_mmcif_wait_for wait_for;
@@ -595,7 +595,7 @@ static int sh_mmcif_error_manage(struct sh_mmcif_host *host)
 	return ret;
 }
 
-static bool sh_mmcif_next_block(struct sh_mmcif_host *host, u32 *p)
+static bool sh_mmcif_next_block(struct sh_mmcif_host *host)
 {
 	struct mmc_data *data = host->mrq->data;
 
@@ -606,10 +606,10 @@ static bool sh_mmcif_next_block(struct sh_mmcif_host *host, u32 *p)
 
 	if (host->sg_blkidx == data->sg->length) {
 		host->sg_blkidx = 0;
-		if (++host->sg_idx < data->sg_len)
-			host->pio_ptr = sg_virt(++data->sg);
-	} else {
-		host->pio_ptr = p;
+		if (++host->sg_idx < data->sg_len) {
+			data->sg++;
+			host->pio_offset = data->sg->offset / 4;
+		}
 	}
 
 	return host->sg_idx != data->sg_len;
@@ -631,8 +631,8 @@ static bool sh_mmcif_read_block(struct sh_mmcif_host *host)
 {
 	struct device *dev = sh_mmcif_host_to_dev(host);
 	struct mmc_data *data = host->mrq->data;
-	u32 *p = sg_virt(data->sg);
-	int i;
+	u32 *p;
+	int off, i;
 
 	if (host->sd_error) {
 		data->error = sh_mmcif_error_manage(host);
@@ -640,8 +640,11 @@ static bool sh_mmcif_read_block(struct sh_mmcif_host *host)
 		return false;
 	}
 
+	p = sg_kmap_atomic(data->sg);
+	off = data->sg->offset / 4;
 	for (i = 0; i < host->blocksize / 4; i++)
-		*p++ = sh_mmcif_readl(host->addr, MMCIF_CE_DATA);
+		p[off++] = sh_mmcif_readl(host->addr, MMCIF_CE_DATA);
+	sg_kunmap_atomic(data->sg, p);
 
 	/* buffer read end */
 	sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFRE);
@@ -664,7 +667,7 @@ static void sh_mmcif_multi_read(struct sh_mmcif_host *host,
 	host->wait_for = MMCIF_WAIT_FOR_MREAD;
 	host->sg_idx = 0;
 	host->sg_blkidx = 0;
-	host->pio_ptr = sg_virt(data->sg);
+	host->pio_offset = data->sg->offset / 4;
 
 	sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFREN);
 }
@@ -673,7 +676,7 @@ static bool sh_mmcif_mread_block(struct sh_mmcif_host *host)
 {
 	struct device *dev = sh_mmcif_host_to_dev(host);
 	struct mmc_data *data = host->mrq->data;
-	u32 *p = host->pio_ptr;
+	u32 *p;
 	int i;
 
 	if (host->sd_error) {
@@ -684,10 +687,14 @@ static bool sh_mmcif_mread_block(struct sh_mmcif_host *host)
 
 	BUG_ON(!data->sg->length);
 
-	for (i = 0; i < host->blocksize / 4; i++)
-		*p++ = sh_mmcif_readl(host->addr, MMCIF_CE_DATA);
+	p = sg_kmap_atomic(data->sg);
+	for (i = 0; i < host->blocksize / 4; i++) {
+		p[host->pio_offset++] =
+			sh_mmcif_readl(host->addr, MMCIF_CE_DATA);
+	}
+	sg_kunmap_atomic(data->sg, p);
 
-	if (!sh_mmcif_next_block(host, p))
+	if (!sh_mmcif_next_block(host))
 		return false;
 
 	sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFREN);
@@ -711,8 +718,8 @@ static bool sh_mmcif_write_block(struct sh_mmcif_host *host)
 {
 	struct device *dev = sh_mmcif_host_to_dev(host);
 	struct mmc_data *data = host->mrq->data;
-	u32 *p = sg_virt(data->sg);
-	int i;
+	u32 *p;
+	int off, i;
 
 	if (host->sd_error) {
 		data->error = sh_mmcif_error_manage(host);
@@ -720,8 +727,11 @@ static bool sh_mmcif_write_block(struct sh_mmcif_host *host)
 		return false;
 	}
 
+	p = sg_kmap_atomic(data->sg);
+	off = data->sg->offset / 4;
 	for (i = 0; i < host->blocksize / 4; i++)
-		sh_mmcif_writel(host->addr, MMCIF_CE_DATA, *p++);
+		sh_mmcif_writel(host->addr, MMCIF_CE_DATA, p[off++]);
+	sg_kunmap_atomic(data->sg, p);
 
 	/* buffer write end */
 	sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MDTRANE);
@@ -744,7 +754,7 @@ static void sh_mmcif_multi_write(struct sh_mmcif_host *host,
 	host->wait_for = MMCIF_WAIT_FOR_MWRITE;
 	host->sg_idx = 0;
 	host->sg_blkidx = 0;
-	host->pio_ptr = sg_virt(data->sg);
+	host->pio_offset = data->sg->offset / 4;
 
 	sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN);
 }
@@ -753,7 +763,7 @@ static bool sh_mmcif_mwrite_block(struct sh_mmcif_host *host)
 {
 	struct device *dev = sh_mmcif_host_to_dev(host);
 	struct mmc_data *data = host->mrq->data;
-	u32 *p = host->pio_ptr;
+	u32 *p;
 	int i;
 
 	if (host->sd_error) {
@@ -764,10 +774,14 @@ static bool sh_mmcif_mwrite_block(struct sh_mmcif_host *host)
 
 	BUG_ON(!data->sg->length);
 
-	for (i = 0; i < host->blocksize / 4; i++)
-		sh_mmcif_writel(host->addr, MMCIF_CE_DATA, *p++);
+	p = sg_kmap_atomic(data->sg);
+	for (i = 0; i < host->blocksize / 4; i++) {
+		sh_mmcif_writel(host->addr, MMCIF_CE_DATA,
+				p[host->pio_offset++]);
+	}
+	sg_kunmap_atomic(data->sg, p);
 
-	if (!sh_mmcif_next_block(host, p))
+	if (!sh_mmcif_next_block(host))
 		return false;
 
 	sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN);
@@ -1424,6 +1438,7 @@ static int sh_mmcif_probe(struct platform_device *pdev)
 	spin_lock_init(&host->lock);
 
 	mmc->ops = &sh_mmcif_ops;
+	mmc->need_kmap = 1;
 	sh_mmcif_init_ocr(host);
 
 	mmc->caps |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_WAIT_WHILE_BUSY;
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 12/14] mmc: sh_mmcif: handle chained sglists
  2019-02-12  7:25 remove block layer bounce buffering for MMC v2 Christoph Hellwig
                   ` (10 preceding siblings ...)
  2019-02-12  7:25 ` [PATCH 11/14] mmc: sh_mmcif: " Christoph Hellwig
@ 2019-02-12  7:25 ` Christoph Hellwig
  2019-02-12  7:25 ` [PATCH 13/14] mmc: core: don't use block layer bounce buffers Christoph Hellwig
                   ` (2 subsequent siblings)
  14 siblings, 0 replies; 19+ messages in thread
From: Christoph Hellwig @ 2019-02-12  7:25 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Aaro Koskinen, Nicolas Pitre, linux-mmc, Russell King,
	linux-kernel, iommu, Ben Dooks, linux-omap, linux-arm-kernel

Use the proper sg_next() helper to move to the next scatterlist element
to support chained scatterlists.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 drivers/mmc/host/sh_mmcif.c | 13 +++++--------
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
index 24c3f13bafdb..9e59dbe6ef30 100644
--- a/drivers/mmc/host/sh_mmcif.c
+++ b/drivers/mmc/host/sh_mmcif.c
@@ -234,7 +234,6 @@ struct sh_mmcif_host {
 	enum sh_mmcif_wait_for wait_for;
 	struct delayed_work timeout_work;
 	size_t blocksize;
-	int sg_idx;
 	int sg_blkidx;
 	bool power;
 	bool ccs_enable;		/* Command Completion Signal support */
@@ -606,13 +605,13 @@ static bool sh_mmcif_next_block(struct sh_mmcif_host *host)
 
 	if (host->sg_blkidx == data->sg->length) {
 		host->sg_blkidx = 0;
-		if (++host->sg_idx < data->sg_len) {
-			data->sg++;
-			host->pio_offset = data->sg->offset / 4;
-		}
+		data->sg = sg_next(data->sg);
+		if (!data->sg)
+			return false;
+		host->pio_offset = data->sg->offset / 4;
 	}
 
-	return host->sg_idx != data->sg_len;
+	return true;
 }
 
 static void sh_mmcif_single_read(struct sh_mmcif_host *host,
@@ -665,7 +664,6 @@ static void sh_mmcif_multi_read(struct sh_mmcif_host *host,
 		BLOCK_SIZE_MASK;
 
 	host->wait_for = MMCIF_WAIT_FOR_MREAD;
-	host->sg_idx = 0;
 	host->sg_blkidx = 0;
 	host->pio_offset = data->sg->offset / 4;
 
@@ -752,7 +750,6 @@ static void sh_mmcif_multi_write(struct sh_mmcif_host *host,
 		BLOCK_SIZE_MASK;
 
 	host->wait_for = MMCIF_WAIT_FOR_MWRITE;
-	host->sg_idx = 0;
 	host->sg_blkidx = 0;
 	host->pio_offset = data->sg->offset / 4;
 
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 13/14] mmc: core: don't use block layer bounce buffers
  2019-02-12  7:25 remove block layer bounce buffering for MMC v2 Christoph Hellwig
                   ` (11 preceding siblings ...)
  2019-02-12  7:25 ` [PATCH 12/14] mmc: sh_mmcif: handle chained sglists Christoph Hellwig
@ 2019-02-12  7:25 ` Christoph Hellwig
  2019-02-12  7:25 ` [PATCH 14/14] dma-mapping: remove dma_max_pfn Christoph Hellwig
  2019-02-25 13:54 ` remove block layer bounce buffering for MMC v2 Ulf Hansson
  14 siblings, 0 replies; 19+ messages in thread
From: Christoph Hellwig @ 2019-02-12  7:25 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Aaro Koskinen, Nicolas Pitre, linux-mmc, Russell King,
	linux-kernel, iommu, Ben Dooks, linux-omap, linux-arm-kernel

All MMC and SD host drivers are highmem safe now, and bounce buffering
for addressing limitations is handled in the DMA layer now.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 drivers/mmc/core/queue.c | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/drivers/mmc/core/queue.c b/drivers/mmc/core/queue.c
index 71cd2411329e..1c92a2a4d641 100644
--- a/drivers/mmc/core/queue.c
+++ b/drivers/mmc/core/queue.c
@@ -354,17 +354,12 @@ static const struct blk_mq_ops mmc_mq_ops = {
 static void mmc_setup_queue(struct mmc_queue *mq, struct mmc_card *card)
 {
 	struct mmc_host *host = card->host;
-	u64 limit = BLK_BOUNCE_HIGH;
-
-	if (mmc_dev(host)->dma_mask && *mmc_dev(host)->dma_mask)
-		limit = (u64)dma_max_pfn(mmc_dev(host)) << PAGE_SHIFT;
 
 	blk_queue_flag_set(QUEUE_FLAG_NONROT, mq->queue);
 	blk_queue_flag_clear(QUEUE_FLAG_ADD_RANDOM, mq->queue);
 	if (mmc_can_erase(card))
 		mmc_queue_setup_discard(mq->queue, card);
 
-	blk_queue_bounce_limit(mq->queue, limit);
 	blk_queue_max_hw_sectors(mq->queue,
 		min(host->max_blk_count, host->max_req_size / 512));
 	blk_queue_max_segments(mq->queue, host->max_segs);
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 14/14] dma-mapping: remove dma_max_pfn
  2019-02-12  7:25 remove block layer bounce buffering for MMC v2 Christoph Hellwig
                   ` (12 preceding siblings ...)
  2019-02-12  7:25 ` [PATCH 13/14] mmc: core: don't use block layer bounce buffers Christoph Hellwig
@ 2019-02-12  7:25 ` Christoph Hellwig
  2019-02-25 13:54 ` remove block layer bounce buffering for MMC v2 Ulf Hansson
  14 siblings, 0 replies; 19+ messages in thread
From: Christoph Hellwig @ 2019-02-12  7:25 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Aaro Koskinen, Nicolas Pitre, linux-mmc, Russell King,
	linux-kernel, iommu, Ben Dooks, linux-omap, linux-arm-kernel

These days the DMA mapping code must bounce buffer for any not supported
address, and if they driver needs to optimize for natively supported
ranged it should use dma_get_required_mask.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 arch/arm/include/asm/dma-mapping.h | 7 -------
 include/linux/dma-mapping.h        | 7 -------
 2 files changed, 14 deletions(-)

diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h
index 31d3b96f0f4b..496b36b9a7ff 100644
--- a/arch/arm/include/asm/dma-mapping.h
+++ b/arch/arm/include/asm/dma-mapping.h
@@ -89,13 +89,6 @@ static inline dma_addr_t virt_to_dma(struct device *dev, void *addr)
 }
 #endif
 
-/* The ARM override for dma_max_pfn() */
-static inline unsigned long dma_max_pfn(struct device *dev)
-{
-	return dma_to_pfn(dev, *dev->dma_mask);
-}
-#define dma_max_pfn(dev) dma_max_pfn(dev)
-
 #define arch_setup_dma_ops arch_setup_dma_ops
 extern void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
 			       const struct iommu_ops *iommu, bool coherent);
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
index f6ded992c183..c6dbc287e466 100644
--- a/include/linux/dma-mapping.h
+++ b/include/linux/dma-mapping.h
@@ -710,13 +710,6 @@ static inline int dma_set_seg_boundary(struct device *dev, unsigned long mask)
 	return -EIO;
 }
 
-#ifndef dma_max_pfn
-static inline unsigned long dma_max_pfn(struct device *dev)
-{
-	return (*dev->dma_mask >> PAGE_SHIFT) + dev->dma_pfn_offset;
-}
-#endif
-
 static inline int dma_get_cache_alignment(void)
 {
 #ifdef ARCH_DMA_MINALIGN
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 06/14] mmc: omap: handle highmem pages
  2019-02-12  7:25 ` [PATCH 06/14] mmc: omap: " Christoph Hellwig
@ 2019-02-12 18:39   ` Tony Lindgren
  0 siblings, 0 replies; 19+ messages in thread
From: Tony Lindgren @ 2019-02-12 18:39 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Ulf Hansson, Aaro Koskinen, Nicolas Pitre, linux-mmc,
	Russell King, linux-kernel, iommu, Ben Dooks, linux-omap,
	linux-arm-kernel

* Christoph Hellwig <hch@lst.de> [190212 07:27]:
> Instead of setting up a kernel pointer to track the current PIO address,
> track the offset in the current page, and do an atomic kmap for the page
> while doing the actual PIO operations.

I'm currently having issues booting my test devices (770 and n8x0)
with this MMC controller so I can't test these patches currently.
Aaro, can you please test when you have a chance?

Regards,

Tony

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: remove block layer bounce buffering for MMC v2
  2019-02-12  7:25 remove block layer bounce buffering for MMC v2 Christoph Hellwig
                   ` (13 preceding siblings ...)
  2019-02-12  7:25 ` [PATCH 14/14] dma-mapping: remove dma_max_pfn Christoph Hellwig
@ 2019-02-25 13:54 ` Ulf Hansson
  2019-03-08  9:18   ` Christoph Hellwig
  14 siblings, 1 reply; 19+ messages in thread
From: Ulf Hansson @ 2019-02-25 13:54 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Aaro Koskinen, Nicolas Pitre, linux-mmc, Russell King,
	Linux Kernel Mailing List, list@263.net:IOMMU DRIVERS,
	Joerg Roedel, iommu, Ben Dooks, linux-omap, Linux ARM

On Tue, 12 Feb 2019 at 08:25, Christoph Hellwig <hch@lst.de> wrote:
>
> Hi everyone,
>
> this series converts the remaining MMC host drivers to properly kmap the
> scatterlist entries it does PIO operations on, and then goes on to
> remove the usage of block layer bounce buffering (which I plan to remove
> eventually) from the MMC layer.
>
> As a bonus I've converted various drivers to the proper scatterlist
> helpers so that at least in theory they are ready for chained
> scatterlists.
>
> All the changes are compile tested only as I don't have any of the
> hardware, so a careful review would be appreciated.
>
> Changes since v1:
>  - fix a missing kunmap_atomic in mvsdio
>  - fix a stray whitespace in s3cmci
>  - add new sg_kmap_atomic and sg_kunmap_atomic helpers
>  - set the DMA and block layer dma boundary
>  - use pointer arithmetics to reduce the amount of changes in
>    various drivers
>

This looks good to me, however the lack of feedback/tests worries me a
bit. So, unless you think it's a bad idea, I intend to apply this when
v5.1 rc1 is out, which allows a lengthy test period in linux-next.

Make sense?

Kind regards
Uffe

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: remove block layer bounce buffering for MMC v2
  2019-02-25 13:54 ` remove block layer bounce buffering for MMC v2 Ulf Hansson
@ 2019-03-08  9:18   ` Christoph Hellwig
  2019-03-08  9:43     ` Ulf Hansson
  0 siblings, 1 reply; 19+ messages in thread
From: Christoph Hellwig @ 2019-03-08  9:18 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Aaro Koskinen, Nicolas Pitre, linux-mmc, Russell King,
	Linux Kernel Mailing List, list@263.net:IOMMU DRIVERS,
	Joerg Roedel, iommu, Ben Dooks, linux-omap, Christoph Hellwig,
	Linux ARM

On Mon, Feb 25, 2019 at 02:54:13PM +0100, Ulf Hansson wrote:
> This looks good to me, however the lack of feedback/tests worries me a
> bit. So, unless you think it's a bad idea, I intend to apply this when
> v5.1 rc1 is out, which allows a lengthy test period in linux-next.

Please don't rush to merge this.  Based on a talk to some folks I
have an idea for a sg iterator that can hide the kmapping from
the drivers, which should allow for some less scary driver code and
clean this up a bit further.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: remove block layer bounce buffering for MMC v2
  2019-03-08  9:18   ` Christoph Hellwig
@ 2019-03-08  9:43     ` Ulf Hansson
  0 siblings, 0 replies; 19+ messages in thread
From: Ulf Hansson @ 2019-03-08  9:43 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Aaro Koskinen, Nicolas Pitre, linux-mmc, Russell King,
	Linux Kernel Mailing List, list@263.net:IOMMU DRIVERS,
	Joerg Roedel, iommu, Ben Dooks, linux-omap, Linux ARM

On Fri, 8 Mar 2019 at 10:18, Christoph Hellwig <hch@lst.de> wrote:
>
> On Mon, Feb 25, 2019 at 02:54:13PM +0100, Ulf Hansson wrote:
> > This looks good to me, however the lack of feedback/tests worries me a
> > bit. So, unless you think it's a bad idea, I intend to apply this when
> > v5.1 rc1 is out, which allows a lengthy test period in linux-next.
>
> Please don't rush to merge this.  Based on a talk to some folks I
> have an idea for a sg iterator that can hide the kmapping from
> the drivers, which should allow for some less scary driver code and
> clean this up a bit further.

Okay, I see. Thanks for letting me know!

Kind regards
Uffe

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, back to index

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-02-12  7:25 remove block layer bounce buffering for MMC v2 Christoph Hellwig
2019-02-12  7:25 ` [PATCH 01/14] scatterlist: add sg_kmap_atomic / sg_kunmap_atomic helpers Christoph Hellwig
2019-02-12  7:25 ` [PATCH 02/14] mmc: remove the unused use_blk_mq field from struct mmc_host Christoph Hellwig
2019-02-12  7:25 ` [PATCH 03/14] mmc: add a need_kmap flag to " Christoph Hellwig
2019-02-12  7:25 ` [PATCH 04/14] mmc: davinci: handle highmem pages Christoph Hellwig
2019-02-12  7:25 ` [PATCH 05/14] mmc: moxart: " Christoph Hellwig
2019-02-12  7:25 ` [PATCH 06/14] mmc: omap: " Christoph Hellwig
2019-02-12 18:39   ` Tony Lindgren
2019-02-12  7:25 ` [PATCH 07/14] mmc: omap: handle chained sglists Christoph Hellwig
2019-02-12  7:25 ` [PATCH 08/14] mmc: s3cmci: handle highmem pages Christoph Hellwig
2019-02-12  7:25 ` [PATCH 09/14] mmc: s3cmci: handle chained sglists Christoph Hellwig
2019-02-12  7:25 ` [PATCH 10/14] mmc: mvsdio: handle highmem pages Christoph Hellwig
2019-02-12  7:25 ` [PATCH 11/14] mmc: sh_mmcif: " Christoph Hellwig
2019-02-12  7:25 ` [PATCH 12/14] mmc: sh_mmcif: handle chained sglists Christoph Hellwig
2019-02-12  7:25 ` [PATCH 13/14] mmc: core: don't use block layer bounce buffers Christoph Hellwig
2019-02-12  7:25 ` [PATCH 14/14] dma-mapping: remove dma_max_pfn Christoph Hellwig
2019-02-25 13:54 ` remove block layer bounce buffering for MMC v2 Ulf Hansson
2019-03-08  9:18   ` Christoph Hellwig
2019-03-08  9:43     ` Ulf Hansson

Linux-ARM-Kernel Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-arm-kernel/0 linux-arm-kernel/git/0.git
	git clone --mirror https://lore.kernel.org/linux-arm-kernel/1 linux-arm-kernel/git/1.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-arm-kernel linux-arm-kernel/ https://lore.kernel.org/linux-arm-kernel \
		linux-arm-kernel@lists.infradead.org infradead-linux-arm-kernel@archiver.kernel.org
	public-inbox-index linux-arm-kernel


Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.infradead.lists.linux-arm-kernel


AGPL code for this site: git clone https://public-inbox.org/ public-inbox