linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* use the generic dma-noncoherent code for openrisc
@ 2018-07-19 13:02 Christoph Hellwig
  2018-07-19 13:02 ` [PATCH 1/4] openrisc: remove the sync_single_for_cpu DMA operation Christoph Hellwig
                   ` (4 more replies)
  0 siblings, 5 replies; 7+ messages in thread
From: Christoph Hellwig @ 2018-07-19 13:02 UTC (permalink / raw)
  To: Jonas Bonn, Stefan Kristiansson, Stafford Horne
  Cc: openrisc, iommu, linux-kernel

Hi Openrisc maintainers,

can you review these patches to switch openrisc to use the generic
dma-noncoherent code?  All the requirements are in mainline already
and we've switched various architectures over to it already.

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

* [PATCH 1/4] openrisc: remove the sync_single_for_cpu DMA operation
  2018-07-19 13:02 use the generic dma-noncoherent code for openrisc Christoph Hellwig
@ 2018-07-19 13:02 ` Christoph Hellwig
  2018-07-19 13:02 ` [PATCH 2/4] openrisc: remove the no-op unmap_page and unmap_sg DMA operations Christoph Hellwig
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Christoph Hellwig @ 2018-07-19 13:02 UTC (permalink / raw)
  To: Jonas Bonn, Stefan Kristiansson, Stafford Horne
  Cc: openrisc, iommu, linux-kernel

openrisc does all the required cache maintainance at dma map time, and none
at unmap time.  It thus has to implement sync_single_for_device to match
the map cace for buffer reuse, but there is no point in doing another
invalidation in the sync_single_cpu_case, which in terms of cache
maintainance is equivalent to the unmap case.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 arch/openrisc/kernel/dma.c | 15 ---------------
 1 file changed, 15 deletions(-)

diff --git a/arch/openrisc/kernel/dma.c b/arch/openrisc/kernel/dma.c
index ec7fd45704d2..47601274abf7 100644
--- a/arch/openrisc/kernel/dma.c
+++ b/arch/openrisc/kernel/dma.c
@@ -208,20 +208,6 @@ or1k_unmap_sg(struct device *dev, struct scatterlist *sg,
 	}
 }
 
-static void
-or1k_sync_single_for_cpu(struct device *dev,
-			 dma_addr_t dma_handle, size_t size,
-			 enum dma_data_direction dir)
-{
-	unsigned long cl;
-	dma_addr_t addr = dma_handle;
-	struct cpuinfo_or1k *cpuinfo = &cpuinfo_or1k[smp_processor_id()];
-
-	/* Invalidate the dcache for the requested range */
-	for (cl = addr; cl < addr + size; cl += cpuinfo->dcache_block_size)
-		mtspr(SPR_DCBIR, cl);
-}
-
 static void
 or1k_sync_single_for_device(struct device *dev,
 			    dma_addr_t dma_handle, size_t size,
@@ -243,7 +229,6 @@ const struct dma_map_ops or1k_dma_map_ops = {
 	.unmap_page = or1k_unmap_page,
 	.map_sg = or1k_map_sg,
 	.unmap_sg = or1k_unmap_sg,
-	.sync_single_for_cpu = or1k_sync_single_for_cpu,
 	.sync_single_for_device = or1k_sync_single_for_device,
 };
 EXPORT_SYMBOL(or1k_dma_map_ops);
-- 
2.18.0


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

* [PATCH 2/4] openrisc: remove the no-op unmap_page and unmap_sg DMA operations
  2018-07-19 13:02 use the generic dma-noncoherent code for openrisc Christoph Hellwig
  2018-07-19 13:02 ` [PATCH 1/4] openrisc: remove the sync_single_for_cpu DMA operation Christoph Hellwig
@ 2018-07-19 13:02 ` Christoph Hellwig
  2018-07-19 13:02 ` [PATCH 3/4] openrisc: fix cache maintainance the the sync_single_for_device DMA operation Christoph Hellwig
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Christoph Hellwig @ 2018-07-19 13:02 UTC (permalink / raw)
  To: Jonas Bonn, Stefan Kristiansson, Stafford Horne
  Cc: openrisc, iommu, linux-kernel

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 arch/openrisc/kernel/dma.c | 23 -----------------------
 1 file changed, 23 deletions(-)

diff --git a/arch/openrisc/kernel/dma.c b/arch/openrisc/kernel/dma.c
index 47601274abf7..7cadff93d179 100644
--- a/arch/openrisc/kernel/dma.c
+++ b/arch/openrisc/kernel/dma.c
@@ -171,14 +171,6 @@ or1k_map_page(struct device *dev, struct page *page,
 	return addr;
 }
 
-static void
-or1k_unmap_page(struct device *dev, dma_addr_t dma_handle,
-		size_t size, enum dma_data_direction dir,
-		unsigned long attrs)
-{
-	/* Nothing special to do here... */
-}
-
 static int
 or1k_map_sg(struct device *dev, struct scatterlist *sg,
 	    int nents, enum dma_data_direction dir,
@@ -195,19 +187,6 @@ or1k_map_sg(struct device *dev, struct scatterlist *sg,
 	return nents;
 }
 
-static void
-or1k_unmap_sg(struct device *dev, struct scatterlist *sg,
-	      int nents, enum dma_data_direction dir,
-	      unsigned long attrs)
-{
-	struct scatterlist *s;
-	int i;
-
-	for_each_sg(sg, s, nents, i) {
-		or1k_unmap_page(dev, sg_dma_address(s), sg_dma_len(s), dir, 0);
-	}
-}
-
 static void
 or1k_sync_single_for_device(struct device *dev,
 			    dma_addr_t dma_handle, size_t size,
@@ -226,9 +205,7 @@ const struct dma_map_ops or1k_dma_map_ops = {
 	.alloc = or1k_dma_alloc,
 	.free = or1k_dma_free,
 	.map_page = or1k_map_page,
-	.unmap_page = or1k_unmap_page,
 	.map_sg = or1k_map_sg,
-	.unmap_sg = or1k_unmap_sg,
 	.sync_single_for_device = or1k_sync_single_for_device,
 };
 EXPORT_SYMBOL(or1k_dma_map_ops);
-- 
2.18.0


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

* [PATCH 3/4] openrisc: fix cache maintainance the the sync_single_for_device DMA operation
  2018-07-19 13:02 use the generic dma-noncoherent code for openrisc Christoph Hellwig
  2018-07-19 13:02 ` [PATCH 1/4] openrisc: remove the sync_single_for_cpu DMA operation Christoph Hellwig
  2018-07-19 13:02 ` [PATCH 2/4] openrisc: remove the no-op unmap_page and unmap_sg DMA operations Christoph Hellwig
@ 2018-07-19 13:02 ` Christoph Hellwig
  2018-07-19 13:02 ` [PATCH 4/4] openrisc: use generic dma_noncoherent_ops Christoph Hellwig
  2018-07-21  5:31 ` use the generic dma-noncoherent code for openrisc Stafford Horne
  4 siblings, 0 replies; 7+ messages in thread
From: Christoph Hellwig @ 2018-07-19 13:02 UTC (permalink / raw)
  To: Jonas Bonn, Stefan Kristiansson, Stafford Horne
  Cc: openrisc, iommu, linux-kernel

The cache maintaince in the sync_single_for_device operation should be
equivalent to the map_page operation to facilitate reusing buffers.  Fix the
openrisc implementation by moving the cache maintaince performed in map_page
into the sync_single method, and calling that from map_page.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 arch/openrisc/kernel/dma.c | 42 +++++++++++++++++---------------------
 1 file changed, 19 insertions(+), 23 deletions(-)

diff --git a/arch/openrisc/kernel/dma.c b/arch/openrisc/kernel/dma.c
index 7cadff93d179..d6a0bf1fa713 100644
--- a/arch/openrisc/kernel/dma.c
+++ b/arch/openrisc/kernel/dma.c
@@ -133,19 +133,15 @@ or1k_dma_free(struct device *dev, size_t size, void *vaddr,
 	free_pages_exact(vaddr, size);
 }
 
-static dma_addr_t
-or1k_map_page(struct device *dev, struct page *page,
-	      unsigned long offset, size_t size,
-	      enum dma_data_direction dir,
-	      unsigned long attrs)
+static void
+or1k_sync_single_for_device(struct device *dev,
+			    dma_addr_t dma_handle, size_t size,
+			    enum dma_data_direction dir)
 {
 	unsigned long cl;
-	dma_addr_t addr = page_to_phys(page) + offset;
+	dma_addr_t addr = dma_handle;
 	struct cpuinfo_or1k *cpuinfo = &cpuinfo_or1k[smp_processor_id()];
 
-	if (attrs & DMA_ATTR_SKIP_CPU_SYNC)
-		return addr;
-
 	switch (dir) {
 	case DMA_TO_DEVICE:
 		/* Flush the dcache for the requested range */
@@ -168,6 +164,20 @@ or1k_map_page(struct device *dev, struct page *page,
 		break;
 	}
 
+}
+
+static dma_addr_t
+or1k_map_page(struct device *dev, struct page *page,
+	      unsigned long offset, size_t size,
+	      enum dma_data_direction dir,
+	      unsigned long attrs)
+{
+	unsigned long cl;
+	dma_addr_t addr = page_to_phys(page) + offset;
+	struct cpuinfo_or1k *cpuinfo = &cpuinfo_or1k[smp_processor_id()];
+
+	if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
+		or1k_sync_single_for_device(dev, addr, size, dir);
 	return addr;
 }
 
@@ -187,20 +197,6 @@ or1k_map_sg(struct device *dev, struct scatterlist *sg,
 	return nents;
 }
 
-static void
-or1k_sync_single_for_device(struct device *dev,
-			    dma_addr_t dma_handle, size_t size,
-			    enum dma_data_direction dir)
-{
-	unsigned long cl;
-	dma_addr_t addr = dma_handle;
-	struct cpuinfo_or1k *cpuinfo = &cpuinfo_or1k[smp_processor_id()];
-
-	/* Flush the dcache for the requested range */
-	for (cl = addr; cl < addr + size; cl += cpuinfo->dcache_block_size)
-		mtspr(SPR_DCBFR, cl);
-}
-
 const struct dma_map_ops or1k_dma_map_ops = {
 	.alloc = or1k_dma_alloc,
 	.free = or1k_dma_free,
-- 
2.18.0


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

* [PATCH 4/4] openrisc: use generic dma_noncoherent_ops
  2018-07-19 13:02 use the generic dma-noncoherent code for openrisc Christoph Hellwig
                   ` (2 preceding siblings ...)
  2018-07-19 13:02 ` [PATCH 3/4] openrisc: fix cache maintainance the the sync_single_for_device DMA operation Christoph Hellwig
@ 2018-07-19 13:02 ` Christoph Hellwig
  2018-07-21  5:31 ` use the generic dma-noncoherent code for openrisc Stafford Horne
  4 siblings, 0 replies; 7+ messages in thread
From: Christoph Hellwig @ 2018-07-19 13:02 UTC (permalink / raw)
  To: Jonas Bonn, Stefan Kristiansson, Stafford Horne
  Cc: openrisc, iommu, linux-kernel

Switch to the generic noncoherent direct mapping implementation.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 arch/openrisc/Kconfig                   |  2 +
 arch/openrisc/include/asm/Kbuild        |  1 +
 arch/openrisc/include/asm/dma-mapping.h | 35 -------------
 arch/openrisc/kernel/dma.c              | 65 ++++---------------------
 4 files changed, 12 insertions(+), 91 deletions(-)
 delete mode 100644 arch/openrisc/include/asm/dma-mapping.h

diff --git a/arch/openrisc/Kconfig b/arch/openrisc/Kconfig
index 9ecad05bfc73..65e3c574c9d3 100644
--- a/arch/openrisc/Kconfig
+++ b/arch/openrisc/Kconfig
@@ -6,6 +6,8 @@
 
 config OPENRISC
 	def_bool y
+	select ARCH_HAS_SYNC_DMA_FOR_DEVICE
+	select DMA_NONCOHERENT_OPS
 	select OF
 	select OF_EARLY_FLATTREE
 	select IRQ_DOMAIN
diff --git a/arch/openrisc/include/asm/Kbuild b/arch/openrisc/include/asm/Kbuild
index 65964d390b10..eb87cd8327c8 100644
--- a/arch/openrisc/include/asm/Kbuild
+++ b/arch/openrisc/include/asm/Kbuild
@@ -7,6 +7,7 @@ generic-y += current.h
 generic-y += device.h
 generic-y += div64.h
 generic-y += dma.h
+generic-y += dma-mapping.h
 generic-y += emergency-restart.h
 generic-y += exec.h
 generic-y += extable.h
diff --git a/arch/openrisc/include/asm/dma-mapping.h b/arch/openrisc/include/asm/dma-mapping.h
deleted file mode 100644
index e212a1f0b6d2..000000000000
--- a/arch/openrisc/include/asm/dma-mapping.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * OpenRISC Linux
- *
- * Linux architectural port borrowing liberally from similar works of
- * others.  All original copyrights apply as per the original source
- * declaration.
- *
- * OpenRISC implementation:
- * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#ifndef __ASM_OPENRISC_DMA_MAPPING_H
-#define __ASM_OPENRISC_DMA_MAPPING_H
-
-/*
- * See Documentation/DMA-API-HOWTO.txt and
- * Documentation/DMA-API.txt for documentation.
- */
-
-#include <linux/dma-debug.h>
-#include <linux/dma-mapping.h>
-
-extern const struct dma_map_ops or1k_dma_map_ops;
-
-static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
-{
-	return &or1k_dma_map_ops;
-}
-
-#endif	/* __ASM_OPENRISC_DMA_MAPPING_H */
diff --git a/arch/openrisc/kernel/dma.c b/arch/openrisc/kernel/dma.c
index d6a0bf1fa713..159336adfa2f 100644
--- a/arch/openrisc/kernel/dma.c
+++ b/arch/openrisc/kernel/dma.c
@@ -19,9 +19,7 @@
  * the only thing implemented properly.  The rest need looking into...
  */
 
-#include <linux/dma-mapping.h>
-#include <linux/dma-debug.h>
-#include <linux/export.h>
+#include <linux/dma-noncoherent.h>
 
 #include <asm/cpuinfo.h>
 #include <asm/spr_defs.h>
@@ -80,10 +78,9 @@ page_clear_nocache(pte_t *pte, unsigned long addr,
  * is being ignored for now; uncached but write-combined memory is a
  * missing feature of the OR1K.
  */
-static void *
-or1k_dma_alloc(struct device *dev, size_t size,
-	       dma_addr_t *dma_handle, gfp_t gfp,
-	       unsigned long attrs)
+void *
+arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
+		gfp_t gfp, unsigned long attrs)
 {
 	unsigned long va;
 	void *page;
@@ -115,9 +112,9 @@ or1k_dma_alloc(struct device *dev, size_t size,
 	return (void *)va;
 }
 
-static void
-or1k_dma_free(struct device *dev, size_t size, void *vaddr,
-	      dma_addr_t dma_handle, unsigned long attrs)
+void
+arch_dma_free(struct device *dev, size_t size, void *vaddr,
+		dma_addr_t dma_handle, unsigned long attrs)
 {
 	unsigned long va = (unsigned long)vaddr;
 	struct mm_walk walk = {
@@ -133,13 +130,10 @@ or1k_dma_free(struct device *dev, size_t size, void *vaddr,
 	free_pages_exact(vaddr, size);
 }
 
-static void
-or1k_sync_single_for_device(struct device *dev,
-			    dma_addr_t dma_handle, size_t size,
-			    enum dma_data_direction dir)
+void arch_sync_dma_for_device(struct device *dev, phys_addr_t addr, size_t size,
+		enum dma_data_direction dir)
 {
 	unsigned long cl;
-	dma_addr_t addr = dma_handle;
 	struct cpuinfo_or1k *cpuinfo = &cpuinfo_or1k[smp_processor_id()];
 
 	switch (dir) {
@@ -163,45 +157,4 @@ or1k_sync_single_for_device(struct device *dev,
 		 */
 		break;
 	}
-
-}
-
-static dma_addr_t
-or1k_map_page(struct device *dev, struct page *page,
-	      unsigned long offset, size_t size,
-	      enum dma_data_direction dir,
-	      unsigned long attrs)
-{
-	unsigned long cl;
-	dma_addr_t addr = page_to_phys(page) + offset;
-	struct cpuinfo_or1k *cpuinfo = &cpuinfo_or1k[smp_processor_id()];
-
-	if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
-		or1k_sync_single_for_device(dev, addr, size, dir);
-	return addr;
 }
-
-static int
-or1k_map_sg(struct device *dev, struct scatterlist *sg,
-	    int nents, enum dma_data_direction dir,
-	    unsigned long attrs)
-{
-	struct scatterlist *s;
-	int i;
-
-	for_each_sg(sg, s, nents, i) {
-		s->dma_address = or1k_map_page(dev, sg_page(s), s->offset,
-					       s->length, dir, 0);
-	}
-
-	return nents;
-}
-
-const struct dma_map_ops or1k_dma_map_ops = {
-	.alloc = or1k_dma_alloc,
-	.free = or1k_dma_free,
-	.map_page = or1k_map_page,
-	.map_sg = or1k_map_sg,
-	.sync_single_for_device = or1k_sync_single_for_device,
-};
-EXPORT_SYMBOL(or1k_dma_map_ops);
-- 
2.18.0


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

* Re: use the generic dma-noncoherent code for openrisc
  2018-07-19 13:02 use the generic dma-noncoherent code for openrisc Christoph Hellwig
                   ` (3 preceding siblings ...)
  2018-07-19 13:02 ` [PATCH 4/4] openrisc: use generic dma_noncoherent_ops Christoph Hellwig
@ 2018-07-21  5:31 ` Stafford Horne
  2018-07-21 12:37   ` Christoph Hellwig
  4 siblings, 1 reply; 7+ messages in thread
From: Stafford Horne @ 2018-07-21  5:31 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Jonas Bonn, Stefan Kristiansson, openrisc, iommu, linux-kernel

On Thu, Jul 19, 2018 at 06:02:28AM -0700, Christoph Hellwig wrote:
> Hi Openrisc maintainers,
> 
> can you review these patches to switch openrisc to use the generic
> dma-noncoherent code?  All the requirements are in mainline already
> and we've switched various architectures over to it already.

Hi Christoph,

Thanks for this, these look good to me.  I don't know much about the dma
infrastructure in the kernel to tell the truth, but the patches do maintain the
original cache flushing and invalidation core logic and I don't see any
problems.

I have applied these and ran my regular tests, but I don't really have any DMA
hardware so the testing doesn't mean much.

For upstreaming, do you want me to send these through the openrisc tree, or do
you want to send with the dma tree?

-Stafford

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

* Re: use the generic dma-noncoherent code for openrisc
  2018-07-21  5:31 ` use the generic dma-noncoherent code for openrisc Stafford Horne
@ 2018-07-21 12:37   ` Christoph Hellwig
  0 siblings, 0 replies; 7+ messages in thread
From: Christoph Hellwig @ 2018-07-21 12:37 UTC (permalink / raw)
  To: Stafford Horne
  Cc: Christoph Hellwig, Jonas Bonn, Stefan Kristiansson, openrisc,
	iommu, linux-kernel

On Sat, Jul 21, 2018 at 02:31:42PM +0900, Stafford Horne wrote:
> For upstreaming, do you want me to send these through the openrisc tree, or do
> you want to send with the dma tree?

Feel free to merge them through the openrisc tree.

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

end of thread, other threads:[~2018-07-21 12:34 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-07-19 13:02 use the generic dma-noncoherent code for openrisc Christoph Hellwig
2018-07-19 13:02 ` [PATCH 1/4] openrisc: remove the sync_single_for_cpu DMA operation Christoph Hellwig
2018-07-19 13:02 ` [PATCH 2/4] openrisc: remove the no-op unmap_page and unmap_sg DMA operations Christoph Hellwig
2018-07-19 13:02 ` [PATCH 3/4] openrisc: fix cache maintainance the the sync_single_for_device DMA operation Christoph Hellwig
2018-07-19 13:02 ` [PATCH 4/4] openrisc: use generic dma_noncoherent_ops Christoph Hellwig
2018-07-21  5:31 ` use the generic dma-noncoherent code for openrisc Stafford Horne
2018-07-21 12:37   ` Christoph Hellwig

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).