Skip to content

Commit cff2294

Browse files
committed
Merge tag 'dma-mapping-4.20' of git://git.infradead.org/users/hch/dma-mapping
Pull dma mapping updates from Christoph Hellwig: "First batch of dma-mapping changes for 4.20. There will be a second PR as some big changes were only applied just before the end of the merge window, and I want to give them a few more days in linux-next. Summary: - mostly more consolidation of the direct mapping code, including converting over hexagon, and merging the coherent and non-coherent code into a single dma_map_ops instance (me) - cleanups for the dma_configure/dma_unconfigure callchains (me) - better handling of dma_masks in odd setups (me, Alexander Duyck) - better debugging of passing vmalloc address to the DMA API (Stephen Boyd) - CMA command line parsing fix (He Zhe)" * tag 'dma-mapping-4.20' of git://git.infradead.org/users/hch/dma-mapping: (27 commits) dma-direct: respect DMA_ATTR_NO_WARN dma-mapping: translate __GFP_NOFAIL to DMA_ATTR_NO_WARN dma-direct: document the zone selection logic dma-debug: Check for drivers mapping invalid addresses in dma_map_single() dma-direct: fix return value of dma_direct_supported dma-mapping: move dma_default_get_required_mask under ifdef dma-direct: always allow dma mask <= physiscal memory size dma-direct: implement complete bus_dma_mask handling dma-direct: refine dma_direct_alloc zone selection dma-direct: add an explicit dma_direct_get_required_mask dma-mapping: make the get_required_mask method available unconditionally unicore32: remove swiotlb support Revert "dma-mapping: clear dev->dma_ops in arch_teardown_dma_ops" dma-mapping: support non-coherent devices in dma_common_get_sgtable dma-mapping: consolidate the dma mmap implementations dma-mapping: merge direct and noncoherent ops dma-mapping: move the dma_coherent flag to struct device MIPS: don't select DMA_MAYBE_COHERENT from DMA_PERDEV_COHERENT dma-mapping: add the missing ARCH_HAS_SYNC_DMA_FOR_CPU_ALL declaration dma-mapping: fix panic caused by passing empty cma command line argument ...
2 parents 13775da + b9fd042 commit cff2294

66 files changed

Lines changed: 420 additions & 698 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

arch/arc/Kconfig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
config ARC
1010
def_bool y
1111
select ARC_TIMERS
12+
select ARCH_HAS_DMA_COHERENT_TO_PFN
1213
select ARCH_HAS_PTE_SPECIAL
1314
select ARCH_HAS_SYNC_DMA_FOR_CPU
1415
select ARCH_HAS_SYNC_DMA_FOR_DEVICE
@@ -17,8 +18,7 @@ config ARC
1718
select BUILDTIME_EXTABLE_SORT
1819
select CLONE_BACKWARDS
1920
select COMMON_CLK
20-
select DMA_NONCOHERENT_OPS
21-
select DMA_NONCOHERENT_MMAP
21+
select DMA_DIRECT_OPS
2222
select GENERIC_ATOMIC64 if !ISA_ARCV2 || !(ARC_HAS_LL64 && ARC_HAS_LLSC)
2323
select GENERIC_CLOCKEVENTS
2424
select GENERIC_FIND_FIRST_BIT

arch/arc/mm/dma.c

Lines changed: 10 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -84,29 +84,10 @@ void arch_dma_free(struct device *dev, size_t size, void *vaddr,
8484
__free_pages(page, get_order(size));
8585
}
8686

87-
int arch_dma_mmap(struct device *dev, struct vm_area_struct *vma,
88-
void *cpu_addr, dma_addr_t dma_addr, size_t size,
89-
unsigned long attrs)
87+
long arch_dma_coherent_to_pfn(struct device *dev, void *cpu_addr,
88+
dma_addr_t dma_addr)
9089
{
91-
unsigned long user_count = vma_pages(vma);
92-
unsigned long count = PAGE_ALIGN(size) >> PAGE_SHIFT;
93-
unsigned long pfn = __phys_to_pfn(dma_addr);
94-
unsigned long off = vma->vm_pgoff;
95-
int ret = -ENXIO;
96-
97-
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
98-
99-
if (dma_mmap_from_dev_coherent(dev, vma, cpu_addr, size, &ret))
100-
return ret;
101-
102-
if (off < count && user_count <= (count - off)) {
103-
ret = remap_pfn_range(vma, vma->vm_start,
104-
pfn + off,
105-
user_count << PAGE_SHIFT,
106-
vma->vm_page_prot);
107-
}
108-
109-
return ret;
90+
return __phys_to_pfn(dma_addr);
11091
}
11192

11293
/*
@@ -167,21 +148,19 @@ void arch_sync_dma_for_cpu(struct device *dev, phys_addr_t paddr,
167148
}
168149

169150
/*
170-
* Plug in coherent or noncoherent dma ops
151+
* Plug in direct dma map ops.
171152
*/
172153
void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
173154
const struct iommu_ops *iommu, bool coherent)
174155
{
175156
/*
176157
* IOC hardware snoops all DMA traffic keeping the caches consistent
177158
* with memory - eliding need for any explicit cache maintenance of
178-
* DMA buffers - so we can use dma_direct cache ops.
159+
* DMA buffers.
179160
*/
180-
if (is_isa_arcv2() && ioc_enable && coherent) {
181-
set_dma_ops(dev, &dma_direct_ops);
182-
dev_info(dev, "use dma_direct_ops cache ops\n");
183-
} else {
184-
set_dma_ops(dev, &dma_noncoherent_ops);
185-
dev_info(dev, "use dma_noncoherent_ops cache ops\n");
186-
}
161+
if (is_isa_arcv2() && ioc_enable && coherent)
162+
dev->dma_coherent = true;
163+
164+
dev_info(dev, "use %sncoherent DMA ops\n",
165+
dev->dma_coherent ? "" : "non");
187166
}

arch/arm/include/asm/dma-mapping.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,10 @@ static inline unsigned long dma_max_pfn(struct device *dev)
100100
extern void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
101101
const struct iommu_ops *iommu, bool coherent);
102102

103+
#ifdef CONFIG_MMU
103104
#define arch_teardown_dma_ops arch_teardown_dma_ops
104105
extern void arch_teardown_dma_ops(struct device *dev);
106+
#endif
105107

106108
/* do not use this function in a driver */
107109
static inline bool is_device_dma_coherent(struct device *dev)

arch/arm/mm/dma-mapping-nommu.c

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ static void *arm_nommu_dma_alloc(struct device *dev, size_t size,
4747
*/
4848

4949
if (attrs & DMA_ATTR_NON_CONSISTENT)
50-
return dma_direct_alloc(dev, size, dma_handle, gfp, attrs);
50+
return dma_direct_alloc_pages(dev, size, dma_handle, gfp,
51+
attrs);
5152

5253
ret = dma_alloc_from_global_coherent(size, dma_handle);
5354

@@ -70,7 +71,7 @@ static void arm_nommu_dma_free(struct device *dev, size_t size,
7071
unsigned long attrs)
7172
{
7273
if (attrs & DMA_ATTR_NON_CONSISTENT) {
73-
dma_direct_free(dev, size, cpu_addr, dma_addr, attrs);
74+
dma_direct_free_pages(dev, size, cpu_addr, dma_addr, attrs);
7475
} else {
7576
int ret = dma_release_from_global_coherent(get_order(size),
7677
cpu_addr);
@@ -90,7 +91,7 @@ static int arm_nommu_dma_mmap(struct device *dev, struct vm_area_struct *vma,
9091
if (dma_mmap_from_global_coherent(vma, cpu_addr, size, &ret))
9192
return ret;
9293

93-
return dma_common_mmap(dev, vma, cpu_addr, dma_addr, size);
94+
return dma_common_mmap(dev, vma, cpu_addr, dma_addr, size, attrs);
9495
}
9596

9697

@@ -237,7 +238,3 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
237238

238239
set_dma_ops(dev, dma_ops);
239240
}
240-
241-
void arch_teardown_dma_ops(struct device *dev)
242-
{
243-
}

arch/c6x/Kconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ config C6X
99
select ARCH_HAS_SYNC_DMA_FOR_CPU
1010
select ARCH_HAS_SYNC_DMA_FOR_DEVICE
1111
select CLKDEV_LOOKUP
12-
select DMA_NONCOHERENT_OPS
12+
select DMA_DIRECT_OPS
1313
select GENERIC_ATOMIC64
1414
select GENERIC_IRQ_SHOW
1515
select HAVE_ARCH_TRACEHOOK

arch/hexagon/Kconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ comment "Linux Kernel Configuration for Hexagon"
44

55
config HEXAGON
66
def_bool y
7+
select ARCH_HAS_SYNC_DMA_FOR_DEVICE
78
select ARCH_NO_PREEMPT
89
select HAVE_OPROFILE
910
# Other pending projects/to-do items.
@@ -29,6 +30,7 @@ config HEXAGON
2930
select GENERIC_CLOCKEVENTS_BROADCAST
3031
select MODULES_USE_ELF_RELA
3132
select GENERIC_CPU_DEVICES
33+
select DMA_DIRECT_OPS
3234
---help---
3335
Qualcomm Hexagon is a processor architecture designed for high
3436
performance and low power across a wide variety of applications.

arch/hexagon/include/asm/Kbuild

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ generic-y += compat.h
66
generic-y += current.h
77
generic-y += device.h
88
generic-y += div64.h
9+
generic-y += dma-mapping.h
910
generic-y += emergency-restart.h
1011
generic-y += extable.h
1112
generic-y += fb.h

arch/hexagon/include/asm/dma-mapping.h

Lines changed: 0 additions & 40 deletions
This file was deleted.

arch/hexagon/kernel/dma.c

Lines changed: 8 additions & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -18,32 +18,19 @@
1818
* 02110-1301, USA.
1919
*/
2020

21-
#include <linux/dma-mapping.h>
22-
#include <linux/dma-direct.h>
21+
#include <linux/dma-noncoherent.h>
2322
#include <linux/bootmem.h>
2423
#include <linux/genalloc.h>
25-
#include <asm/dma-mapping.h>
2624
#include <linux/module.h>
2725
#include <asm/page.h>
2826

29-
#define HEXAGON_MAPPING_ERROR 0
30-
31-
const struct dma_map_ops *dma_ops;
32-
EXPORT_SYMBOL(dma_ops);
33-
34-
static inline void *dma_addr_to_virt(dma_addr_t dma_addr)
35-
{
36-
return phys_to_virt((unsigned long) dma_addr);
37-
}
38-
3927
static struct gen_pool *coherent_pool;
4028

4129

4230
/* Allocates from a pool of uncached memory that was reserved at boot time */
4331

44-
static void *hexagon_dma_alloc_coherent(struct device *dev, size_t size,
45-
dma_addr_t *dma_addr, gfp_t flag,
46-
unsigned long attrs)
32+
void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_addr,
33+
gfp_t flag, unsigned long attrs)
4734
{
4835
void *ret;
4936

@@ -75,58 +62,17 @@ static void *hexagon_dma_alloc_coherent(struct device *dev, size_t size,
7562
return ret;
7663
}
7764

78-
static void hexagon_free_coherent(struct device *dev, size_t size, void *vaddr,
79-
dma_addr_t dma_addr, unsigned long attrs)
65+
void arch_dma_free(struct device *dev, size_t size, void *vaddr,
66+
dma_addr_t dma_addr, unsigned long attrs)
8067
{
8168
gen_pool_free(coherent_pool, (unsigned long) vaddr, size);
8269
}
8370

84-
static int check_addr(const char *name, struct device *hwdev,
85-
dma_addr_t bus, size_t size)
86-
{
87-
if (hwdev && hwdev->dma_mask && !dma_capable(hwdev, bus, size)) {
88-
if (*hwdev->dma_mask >= DMA_BIT_MASK(32))
89-
printk(KERN_ERR
90-
"%s: overflow %Lx+%zu of device mask %Lx\n",
91-
name, (long long)bus, size,
92-
(long long)*hwdev->dma_mask);
93-
return 0;
94-
}
95-
return 1;
96-
}
97-
98-
static int hexagon_map_sg(struct device *hwdev, struct scatterlist *sg,
99-
int nents, enum dma_data_direction dir,
100-
unsigned long attrs)
71+
void arch_sync_dma_for_device(struct device *dev, phys_addr_t paddr,
72+
size_t size, enum dma_data_direction dir)
10173
{
102-
struct scatterlist *s;
103-
int i;
104-
105-
WARN_ON(nents == 0 || sg[0].length == 0);
106-
107-
for_each_sg(sg, s, nents, i) {
108-
s->dma_address = sg_phys(s);
109-
if (!check_addr("map_sg", hwdev, s->dma_address, s->length))
110-
return 0;
111-
112-
s->dma_length = s->length;
74+
void *addr = phys_to_virt(paddr);
11375

114-
if (attrs & DMA_ATTR_SKIP_CPU_SYNC)
115-
continue;
116-
117-
flush_dcache_range(dma_addr_to_virt(s->dma_address),
118-
dma_addr_to_virt(s->dma_address + s->length));
119-
}
120-
121-
return nents;
122-
}
123-
124-
/*
125-
* address is virtual
126-
*/
127-
static inline void dma_sync(void *addr, size_t size,
128-
enum dma_data_direction dir)
129-
{
13076
switch (dir) {
13177
case DMA_TO_DEVICE:
13278
hexagon_clean_dcache_range((unsigned long) addr,
@@ -144,76 +90,3 @@ static inline void dma_sync(void *addr, size_t size,
14490
BUG();
14591
}
14692
}
147-
148-
/**
149-
* hexagon_map_page() - maps an address for device DMA
150-
* @dev: pointer to DMA device
151-
* @page: pointer to page struct of DMA memory
152-
* @offset: offset within page
153-
* @size: size of memory to map
154-
* @dir: transfer direction
155-
* @attrs: pointer to DMA attrs (not used)
156-
*
157-
* Called to map a memory address to a DMA address prior
158-
* to accesses to/from device.
159-
*
160-
* We don't particularly have many hoops to jump through
161-
* so far. Straight translation between phys and virtual.
162-
*
163-
* DMA is not cache coherent so sync is necessary; this
164-
* seems to be a convenient place to do it.
165-
*
166-
*/
167-
static dma_addr_t hexagon_map_page(struct device *dev, struct page *page,
168-
unsigned long offset, size_t size,
169-
enum dma_data_direction dir,
170-
unsigned long attrs)
171-
{
172-
dma_addr_t bus = page_to_phys(page) + offset;
173-
WARN_ON(size == 0);
174-
175-
if (!check_addr("map_single", dev, bus, size))
176-
return HEXAGON_MAPPING_ERROR;
177-
178-
if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
179-
dma_sync(dma_addr_to_virt(bus), size, dir);
180-
181-
return bus;
182-
}
183-
184-
static void hexagon_sync_single_for_cpu(struct device *dev,
185-
dma_addr_t dma_handle, size_t size,
186-
enum dma_data_direction dir)
187-
{
188-
dma_sync(dma_addr_to_virt(dma_handle), size, dir);
189-
}
190-
191-
static void hexagon_sync_single_for_device(struct device *dev,
192-
dma_addr_t dma_handle, size_t size,
193-
enum dma_data_direction dir)
194-
{
195-
dma_sync(dma_addr_to_virt(dma_handle), size, dir);
196-
}
197-
198-
static int hexagon_mapping_error(struct device *dev, dma_addr_t dma_addr)
199-
{
200-
return dma_addr == HEXAGON_MAPPING_ERROR;
201-
}
202-
203-
const struct dma_map_ops hexagon_dma_ops = {
204-
.alloc = hexagon_dma_alloc_coherent,
205-
.free = hexagon_free_coherent,
206-
.map_sg = hexagon_map_sg,
207-
.map_page = hexagon_map_page,
208-
.sync_single_for_cpu = hexagon_sync_single_for_cpu,
209-
.sync_single_for_device = hexagon_sync_single_for_device,
210-
.mapping_error = hexagon_mapping_error,
211-
};
212-
213-
void __init hexagon_dma_init(void)
214-
{
215-
if (dma_ops)
216-
return;
217-
218-
dma_ops = &hexagon_dma_ops;
219-
}

arch/ia64/include/asm/dma-mapping.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010
#include <linux/scatterlist.h>
1111
#include <linux/dma-debug.h>
1212

13-
#define ARCH_HAS_DMA_GET_REQUIRED_MASK
14-
1513
extern const struct dma_map_ops *dma_ops;
1614
extern struct ia64_machine_vector ia64_mv;
1715
extern void set_iommu_machvec(void);

0 commit comments

Comments
 (0)