diff mbox series

[v2,1/4] asm: dma-mapping.h: Fix dma mapping functions

Message ID 20200116085348.24031-2-vigneshr@ti.com
State Accepted
Commit c0a5a81f746f18a5d8ed4bf2c062d03e3519ab5e
Headers show
Series dma-mapping: Add cache flush/invalidation to dma_{un}map_single | expand

Commit Message

Vignesh Raghavendra Jan. 16, 2020, 8:53 a.m. UTC
Subsystems such as USB expect dma_map_single() and dma_unmap_single() to
do dcache flush/invalidate operations as required. For example, see
see drivers/usb/gadget/udc/udc-core.c::usb_gadget_map_request().
Currently drivers do this locally, (see drivers/usb/dwc3/ep0.c,
drivers/mtd/nand/raw/denali.c etc..)
Update arch specific dma_map_single() and dma_unmap_single() APIs to do
cache flush/invalidate  operations, so that drivers need not implement
them locally.

Signed-off-by: Vignesh Raghavendra <vigneshr at ti.com>
Reviewed-by: Masahiro Yamada <yamada.masahiro at socionext.com>
Reviewed-by: Rick Chen <rick at andestech.com>
---
 arch/arm/include/asm/dma-mapping.h   | 23 +++++++++++++++++++++--
 arch/nds32/include/asm/dma-mapping.h | 23 +++++++++++++++++++++--
 arch/riscv/include/asm/dma-mapping.h | 23 +++++++++++++++++++++--
 arch/x86/include/asm/dma-mapping.h   | 23 +++++++++++++++++++++--
 4 files changed, 84 insertions(+), 8 deletions(-)

Comments

Tom Rini Jan. 25, 2020, 5:09 p.m. UTC | #1
On Thu, Jan 16, 2020 at 02:23:45PM +0530, Vignesh Raghavendra wrote:

> Subsystems such as USB expect dma_map_single() and dma_unmap_single() to
> do dcache flush/invalidate operations as required. For example, see
> see drivers/usb/gadget/udc/udc-core.c::usb_gadget_map_request().
> Currently drivers do this locally, (see drivers/usb/dwc3/ep0.c,
> drivers/mtd/nand/raw/denali.c etc..)
> Update arch specific dma_map_single() and dma_unmap_single() APIs to do
> cache flush/invalidate  operations, so that drivers need not implement
> them locally.
> 
> Signed-off-by: Vignesh Raghavendra <vigneshr at ti.com>
> Reviewed-by: Masahiro Yamada <yamada.masahiro at socionext.com>
> Reviewed-by: Rick Chen <rick at andestech.com>

Applied to u-boot/master, thanks!
diff mbox series

Patch

diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h
index fc5b8f634d54..d20703739fad 100644
--- a/arch/arm/include/asm/dma-mapping.h
+++ b/arch/arm/include/asm/dma-mapping.h
@@ -7,7 +7,11 @@ 
 #ifndef __ASM_ARM_DMA_MAPPING_H
 #define __ASM_ARM_DMA_MAPPING_H
 
+#include <common.h>
+#include <asm/cache.h>
+#include <cpu_func.h>
 #include <linux/dma-direction.h>
+#include <malloc.h>
 
 #define	dma_mapping_error(x, y)	0
 
@@ -25,12 +29,27 @@  static inline void dma_free_coherent(void *addr)
 static inline unsigned long dma_map_single(volatile void *vaddr, size_t len,
 					   enum dma_data_direction dir)
 {
-	return (unsigned long)vaddr;
+	unsigned long addr = (unsigned long)vaddr;
+
+	len = ALIGN(len, ARCH_DMA_MINALIGN);
+
+	if (dir == DMA_FROM_DEVICE)
+		invalidate_dcache_range(addr, addr + len);
+	else
+		flush_dcache_range(addr, addr + len);
+
+	return addr;
 }
 
 static inline void dma_unmap_single(volatile void *vaddr, size_t len,
-				    unsigned long paddr)
+				    enum dma_data_direction dir)
 {
+	unsigned long addr = (unsigned long)vaddr;
+
+	len = ALIGN(len, ARCH_DMA_MINALIGN);
+
+	if (dir != DMA_TO_DEVICE)
+		invalidate_dcache_range(addr, addr + len);
 }
 
 #endif /* __ASM_ARM_DMA_MAPPING_H */
diff --git a/arch/nds32/include/asm/dma-mapping.h b/arch/nds32/include/asm/dma-mapping.h
index e6808dc84089..c8876ceadda6 100644
--- a/arch/nds32/include/asm/dma-mapping.h
+++ b/arch/nds32/include/asm/dma-mapping.h
@@ -6,7 +6,11 @@ 
 #ifndef __ASM_NDS_DMA_MAPPING_H
 #define __ASM_NDS_DMA_MAPPING_H
 
+#include <common.h>
+#include <asm/cache.h>
+#include <cpu_func.h>
 #include <linux/dma-direction.h>
+#include <malloc.h>
 
 static void *dma_alloc_coherent(size_t len, unsigned long *handle)
 {
@@ -17,12 +21,27 @@  static void *dma_alloc_coherent(size_t len, unsigned long *handle)
 static inline unsigned long dma_map_single(volatile void *vaddr, size_t len,
 					   enum dma_data_direction dir)
 {
-	return (unsigned long)vaddr;
+	unsigned long addr = (unsigned long)vaddr;
+
+	len = ALIGN(len, ARCH_DMA_MINALIGN);
+
+	if (dir == DMA_FROM_DEVICE)
+		invalidate_dcache_range(addr, addr + len);
+	else
+		flush_dcache_range(addr, addr + len);
+
+	return addr;
 }
 
 static inline void dma_unmap_single(volatile void *vaddr, size_t len,
-				    unsigned long paddr)
+				    enum dma_data_direction dir)
 {
+	unsigned long addr = (unsigned long)vaddr;
+
+	len = ALIGN(len, ARCH_DMA_MINALIGN);
+
+	if (dir != DMA_TO_DEVICE)
+		invalidate_dcache_range(addr, addr + len);
 }
 
 #endif /* __ASM_NDS_DMA_MAPPING_H */
diff --git a/arch/riscv/include/asm/dma-mapping.h b/arch/riscv/include/asm/dma-mapping.h
index 3d930c90eceb..6cc39469590a 100644
--- a/arch/riscv/include/asm/dma-mapping.h
+++ b/arch/riscv/include/asm/dma-mapping.h
@@ -9,7 +9,11 @@ 
 #ifndef __ASM_RISCV_DMA_MAPPING_H
 #define __ASM_RISCV_DMA_MAPPING_H
 
+#include <common.h>
+#include <asm/cache.h>
+#include <cpu_func.h>
 #include <linux/dma-direction.h>
+#include <malloc.h>
 
 #define dma_mapping_error(x, y)	0
 
@@ -27,12 +31,27 @@  static inline void dma_free_coherent(void *addr)
 static inline unsigned long dma_map_single(volatile void *vaddr, size_t len,
 					   enum dma_data_direction dir)
 {
-	return (unsigned long)vaddr;
+	unsigned long addr = (unsigned long)vaddr;
+
+	len = ALIGN(len, ARCH_DMA_MINALIGN);
+
+	if (dir == DMA_FROM_DEVICE)
+		invalidate_dcache_range(addr, addr + len);
+	else
+		flush_dcache_range(addr, addr + len);
+
+	return addr;
 }
 
 static inline void dma_unmap_single(volatile void *vaddr, size_t len,
-				    unsigned long paddr)
+				    enum dma_data_direction dir)
 {
+	unsigned long addr = (unsigned long)vaddr;
+
+	len = ALIGN(len, ARCH_DMA_MINALIGN);
+
+	if (dir != DMA_TO_DEVICE)
+		invalidate_dcache_range(addr, addr + len);
 }
 
 #endif /* __ASM_RISCV_DMA_MAPPING_H */
diff --git a/arch/x86/include/asm/dma-mapping.h b/arch/x86/include/asm/dma-mapping.h
index b353ff0bef59..900b99b8a69a 100644
--- a/arch/x86/include/asm/dma-mapping.h
+++ b/arch/x86/include/asm/dma-mapping.h
@@ -7,7 +7,11 @@ 
 #ifndef __ASM_X86_DMA_MAPPING_H
 #define __ASM_X86_DMA_MAPPING_H
 
+#include <common.h>
+#include <asm/cache.h>
+#include <cpu_func.h>
 #include <linux/dma-direction.h>
+#include <malloc.h>
 
 #define	dma_mapping_error(x, y)	0
 
@@ -25,12 +29,27 @@  static inline void dma_free_coherent(void *addr)
 static inline unsigned long dma_map_single(volatile void *vaddr, size_t len,
 					   enum dma_data_direction dir)
 {
-	return (unsigned long)vaddr;
+	unsigned long addr = (unsigned long)vaddr;
+
+	len = ALIGN(len, ARCH_DMA_MINALIGN);
+
+	if (dir == DMA_FROM_DEVICE)
+		invalidate_dcache_range(addr, addr + len);
+	else
+		flush_dcache_range(addr, addr + len);
+
+	return addr;
 }
 
 static inline void dma_unmap_single(volatile void *vaddr, size_t len,
-				    unsigned long paddr)
+				    enum dma_data_direction dir)
 {
+	unsigned long addr = (unsigned long)vaddr;
+
+	len = ALIGN(len, ARCH_DMA_MINALIGN);
+
+	if (dir != DMA_TO_DEVICE)
+		invalidate_dcache_range(addr, addr + len);
 }
 
 #endif /* __ASM_X86_DMA_MAPPING_H */