aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2018-05-11 02:36:53 -0400
committerChristoph Hellwig <hch@lst.de>2018-08-02 07:54:20 -0400
commit6fa1d28e38cfa0c90f8d64c0cab37769e5337b85 (patch)
treee86521d0770694a10588bc70fd31624113da6484
parent46bcde94cd02283535cb719666399f1c4cfb8f22 (diff)
sh: use generic dma_noncoherent_ops
Switch to the generic noncoherent direct mapping implementation. Signed-off-by: Christoph Hellwig <hch@lst.de> Acked-by: Yoshinori Sato <ysato@users.sourceforge.jp>
-rw-r--r--arch/sh/Kconfig3
-rw-r--r--arch/sh/include/asm/Kbuild1
-rw-r--r--arch/sh/include/asm/dma-mapping.h26
-rw-r--r--arch/sh/kernel/Makefile2
-rw-r--r--arch/sh/kernel/dma-coherent.c23
-rw-r--r--arch/sh/kernel/dma-nommu.c78
6 files changed, 15 insertions, 118 deletions
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index c9993a0cdc7e..da4db4b5359f 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -51,7 +51,6 @@ config SUPERH
51 select HAVE_ARCH_AUDITSYSCALL 51 select HAVE_ARCH_AUDITSYSCALL
52 select HAVE_FUTEX_CMPXCHG if FUTEX 52 select HAVE_FUTEX_CMPXCHG if FUTEX
53 select HAVE_NMI 53 select HAVE_NMI
54 select NEED_DMA_MAP_STATE
55 select NEED_SG_DMA_LENGTH 54 select NEED_SG_DMA_LENGTH
56 55
57 help 56 help
@@ -164,6 +163,8 @@ config DMA_COHERENT
164 163
165config DMA_NONCOHERENT 164config DMA_NONCOHERENT
166 def_bool !DMA_COHERENT 165 def_bool !DMA_COHERENT
166 select ARCH_HAS_SYNC_DMA_FOR_DEVICE
167 select DMA_NONCOHERENT_OPS
167 168
168config PGTABLE_LEVELS 169config PGTABLE_LEVELS
169 default 3 if X2TLB 170 default 3 if X2TLB
diff --git a/arch/sh/include/asm/Kbuild b/arch/sh/include/asm/Kbuild
index 46dd82ab2c29..6a5609a55965 100644
--- a/arch/sh/include/asm/Kbuild
+++ b/arch/sh/include/asm/Kbuild
@@ -2,6 +2,7 @@ generic-y += compat.h
2generic-y += current.h 2generic-y += current.h
3generic-y += delay.h 3generic-y += delay.h
4generic-y += div64.h 4generic-y += div64.h
5generic-y += dma-mapping.h
5generic-y += emergency-restart.h 6generic-y += emergency-restart.h
6generic-y += exec.h 7generic-y += exec.h
7generic-y += irq_regs.h 8generic-y += irq_regs.h
diff --git a/arch/sh/include/asm/dma-mapping.h b/arch/sh/include/asm/dma-mapping.h
deleted file mode 100644
index 1ebc6a4eb1c5..000000000000
--- a/arch/sh/include/asm/dma-mapping.h
+++ /dev/null
@@ -1,26 +0,0 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef __ASM_SH_DMA_MAPPING_H
3#define __ASM_SH_DMA_MAPPING_H
4
5extern const struct dma_map_ops nommu_dma_ops;
6
7static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
8{
9#ifdef CONFIG_DMA_NONCOHERENT
10 return &nommu_dma_ops;
11#else
12 return &dma_direct_ops;
13#endif
14}
15
16extern void *dma_generic_alloc_coherent(struct device *dev, size_t size,
17 dma_addr_t *dma_addr, gfp_t flag,
18 unsigned long attrs);
19extern void dma_generic_free_coherent(struct device *dev, size_t size,
20 void *vaddr, dma_addr_t dma_handle,
21 unsigned long attrs);
22
23void sh_sync_dma_for_device(void *vaddr, size_t size,
24 enum dma_data_direction dir);
25
26#endif /* __ASM_SH_DMA_MAPPING_H */
diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile
index d5ddb64bfffe..59673f8a3379 100644
--- a/arch/sh/kernel/Makefile
+++ b/arch/sh/kernel/Makefile
@@ -45,7 +45,7 @@ obj-$(CONFIG_DUMP_CODE) += disassemble.o
45obj-$(CONFIG_HIBERNATION) += swsusp.o 45obj-$(CONFIG_HIBERNATION) += swsusp.o
46obj-$(CONFIG_DWARF_UNWINDER) += dwarf.o 46obj-$(CONFIG_DWARF_UNWINDER) += dwarf.o
47obj-$(CONFIG_PERF_EVENTS) += perf_event.o perf_callchain.o 47obj-$(CONFIG_PERF_EVENTS) += perf_event.o perf_callchain.o
48obj-$(CONFIG_DMA_NONCOHERENT) += dma-nommu.o dma-coherent.o 48obj-$(CONFIG_DMA_NONCOHERENT) += dma-coherent.o
49obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o 49obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
50 50
51ccflags-y := -Werror 51ccflags-y := -Werror
diff --git a/arch/sh/kernel/dma-coherent.c b/arch/sh/kernel/dma-coherent.c
index 2518065d5d27..a0021eef956b 100644
--- a/arch/sh/kernel/dma-coherent.c
+++ b/arch/sh/kernel/dma-coherent.c
@@ -7,14 +7,13 @@
7 */ 7 */
8#include <linux/mm.h> 8#include <linux/mm.h>
9#include <linux/init.h> 9#include <linux/init.h>
10#include <linux/dma-mapping.h> 10#include <linux/dma-noncoherent.h>
11#include <linux/module.h> 11#include <linux/module.h>
12#include <asm/cacheflush.h> 12#include <asm/cacheflush.h>
13#include <asm/addrspace.h> 13#include <asm/addrspace.h>
14 14
15void *dma_generic_alloc_coherent(struct device *dev, size_t size, 15void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
16 dma_addr_t *dma_handle, gfp_t gfp, 16 gfp_t gfp, unsigned long attrs)
17 unsigned long attrs)
18{ 17{
19 void *ret, *ret_nocache; 18 void *ret, *ret_nocache;
20 int order = get_order(size); 19 int order = get_order(size);
@@ -29,7 +28,8 @@ void *dma_generic_alloc_coherent(struct device *dev, size_t size,
29 * Pages from the page allocator may have data present in 28 * Pages from the page allocator may have data present in
30 * cache. So flush the cache before using uncached memory. 29 * cache. So flush the cache before using uncached memory.
31 */ 30 */
32 sh_sync_dma_for_device(ret, size, DMA_BIDIRECTIONAL); 31 arch_sync_dma_for_device(dev, virt_to_phys(ret), size,
32 DMA_BIDIRECTIONAL);
33 33
34 ret_nocache = (void __force *)ioremap_nocache(virt_to_phys(ret), size); 34 ret_nocache = (void __force *)ioremap_nocache(virt_to_phys(ret), size);
35 if (!ret_nocache) { 35 if (!ret_nocache) {
@@ -46,9 +46,8 @@ void *dma_generic_alloc_coherent(struct device *dev, size_t size,
46 return ret_nocache; 46 return ret_nocache;
47} 47}
48 48
49void dma_generic_free_coherent(struct device *dev, size_t size, 49void arch_dma_free(struct device *dev, size_t size, void *vaddr,
50 void *vaddr, dma_addr_t dma_handle, 50 dma_addr_t dma_handle, unsigned long attrs)
51 unsigned long attrs)
52{ 51{
53 int order = get_order(size); 52 int order = get_order(size);
54 unsigned long pfn = (dma_handle >> PAGE_SHIFT); 53 unsigned long pfn = (dma_handle >> PAGE_SHIFT);
@@ -63,12 +62,12 @@ void dma_generic_free_coherent(struct device *dev, size_t size,
63 iounmap(vaddr); 62 iounmap(vaddr);
64} 63}
65 64
66void sh_sync_dma_for_device(void *vaddr, size_t size, 65void arch_sync_dma_for_device(struct device *dev, phys_addr_t paddr,
67 enum dma_data_direction direction) 66 size_t size, enum dma_data_direction dir)
68{ 67{
69 void *addr = sh_cacheop_vaddr(vaddr); 68 void *addr = sh_cacheop_vaddr(phys_to_virt(paddr));
70 69
71 switch (direction) { 70 switch (dir) {
72 case DMA_FROM_DEVICE: /* invalidate only */ 71 case DMA_FROM_DEVICE: /* invalidate only */
73 __flush_invalidate_region(addr, size); 72 __flush_invalidate_region(addr, size);
74 break; 73 break;
diff --git a/arch/sh/kernel/dma-nommu.c b/arch/sh/kernel/dma-nommu.c
deleted file mode 100644
index d8689b1cb743..000000000000
--- a/arch/sh/kernel/dma-nommu.c
+++ /dev/null
@@ -1,78 +0,0 @@
1/*
2 * DMA mapping support for platforms lacking IOMMUs.
3 *
4 * Copyright (C) 2009 Paul Mundt
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 */
10#include <linux/dma-mapping.h>
11#include <linux/io.h>
12#include <asm/cacheflush.h>
13
14static dma_addr_t nommu_map_page(struct device *dev, struct page *page,
15 unsigned long offset, size_t size,
16 enum dma_data_direction dir,
17 unsigned long attrs)
18{
19 dma_addr_t addr = page_to_phys(page) + offset
20 - PFN_PHYS(dev->dma_pfn_offset);
21
22 WARN_ON(size == 0);
23
24 if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
25 sh_sync_dma_for_device(page_address(page) + offset, size, dir);
26
27 return addr;
28}
29
30static int nommu_map_sg(struct device *dev, struct scatterlist *sg,
31 int nents, enum dma_data_direction dir,
32 unsigned long attrs)
33{
34 struct scatterlist *s;
35 int i;
36
37 WARN_ON(nents == 0 || sg[0].length == 0);
38
39 for_each_sg(sg, s, nents, i) {
40 dma_addr_t offset = PFN_PHYS(dev->dma_pfn_offset);
41
42 BUG_ON(!sg_page(s));
43
44 if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
45 sh_sync_dma_for_device(sg_virt(s), s->length, dir);
46
47 s->dma_address = sg_phys(s) - offset;
48 s->dma_length = s->length;
49 }
50
51 return nents;
52}
53
54static void nommu_sync_single_for_device(struct device *dev, dma_addr_t addr,