Skip to content

Commit 1e89375

Browse files
Christoph Hellwigtorvalds
authored andcommitted
dma-mapping: consolidate dma_{alloc,free}_noncoherent
Most architectures do not support non-coherent allocations and either define dma_{alloc,free}_noncoherent to their coherent versions or stub them out. Openrisc uses dma_{alloc,free}_attrs to implement them, and only Mips implements them directly. This patch moves the Openrisc version to common code, and handles the DMA_ATTR_NON_CONSISTENT case in the mips dma_map_ops instance. Note that actual non-coherent allocations require a dma_cache_sync implementation, so if non-coherent allocations didn't work on an architecture before this patch they still won't work after it. [jcmvbkbc@gmail.com: fix xtensa] Signed-off-by: Christoph Hellwig <hch@lst.de> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Russell King <linux@arm.linux.org.uk> Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: Will Deacon <will.deacon@arm.com> Cc: Yoshinori Sato <ysato@users.sourceforge.jp> Cc: Michal Simek <monstr@monstr.eu> Cc: Jonas Bonn <jonas@southpole.se> Cc: Chris Metcalf <cmetcalf@ezchip.com> Cc: Guan Xuetao <gxt@mprc.pku.edu.cn> Cc: Ralf Baechle <ralf@linux-mips.org> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Ingo Molnar <mingo@elte.hu> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: "H. Peter Anvin" <hpa@zytor.com> Cc: Andy Shevchenko <andy.shevchenko@gmail.com> Signed-off-by: Max Filippov <jcmvbkbc@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
1 parent 6894258 commit 1e89375

File tree

19 files changed

+39
-99
lines changed

19 files changed

+39
-99
lines changed

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

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,6 @@ static inline int dma_set_mask(struct device *dev, u64 mask)
2727
return get_dma_ops(dev)->set_dma_mask(dev, mask);
2828
}
2929

30-
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
31-
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
32-
3330
#define dma_cache_sync(dev, va, size, dir) ((void)0)
3431

3532
#endif /* _ALPHA_DMA_MAPPING_H */

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

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,12 @@ static inline void set_dma_ops(struct device *dev, struct dma_map_ops *ops)
3838
dev->archdata.dma_ops = ops;
3939
}
4040

41+
/*
42+
* Note that while the generic code provides dummy dma_{alloc,free}_noncoherent
43+
* implementations, we don't provide a dma_cache_sync function so drivers using
44+
* this API are highlighted with build warnings.
45+
*/
46+
4147
#include <asm-generic/dma-mapping-common.h>
4248

4349
static inline int dma_set_mask(struct device *dev, u64 mask)
@@ -175,21 +181,6 @@ static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
175181
return dma_addr == DMA_ERROR_CODE;
176182
}
177183

178-
/*
179-
* Dummy noncoherent implementation. We don't provide a dma_cache_sync
180-
* function so drivers using this API are highlighted with build warnings.
181-
*/
182-
static inline void *dma_alloc_noncoherent(struct device *dev, size_t size,
183-
dma_addr_t *handle, gfp_t gfp)
184-
{
185-
return NULL;
186-
}
187-
188-
static inline void dma_free_noncoherent(struct device *dev, size_t size,
189-
void *cpu_addr, dma_addr_t handle)
190-
{
191-
}
192-
193184
extern int dma_supported(struct device *dev, u64 mask);
194185

195186
extern int arm_dma_set_mask(struct device *dev, u64 dma_mask);

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

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -118,19 +118,5 @@ static inline void dma_mark_clean(void *addr, size_t size)
118118
{
119119
}
120120

121-
/*
122-
* There is no dma_cache_sync() implementation, so just return NULL here.
123-
*/
124-
static inline void *dma_alloc_noncoherent(struct device *dev, size_t size,
125-
dma_addr_t *handle, gfp_t flags)
126-
{
127-
return NULL;
128-
}
129-
130-
static inline void dma_free_noncoherent(struct device *dev, size_t size,
131-
void *cpu_addr, dma_addr_t handle)
132-
{
133-
}
134-
135121
#endif /* __KERNEL__ */
136122
#endif /* __ASM_DMA_MAPPING_H */

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

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,6 @@ static inline int dma_set_mask(struct device *dev, u64 mask)
2020
return 0;
2121
}
2222

23-
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
24-
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
25-
2623
static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
2724
{
2825
return 0;

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

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,6 @@ extern int bad_dma_address;
3434

3535
extern struct dma_map_ops *dma_ops;
3636

37-
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
38-
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
39-
4037
static inline struct dma_map_ops *get_dma_ops(struct device *dev)
4138
{
4239
if (unlikely(dev == NULL))

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

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,6 @@ extern void machvec_dma_sync_single(struct device *, dma_addr_t, size_t,
2323
extern void machvec_dma_sync_sg(struct device *, struct scatterlist *, int,
2424
enum dma_data_direction);
2525

26-
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
27-
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
28-
2926
#define get_dma_ops(dev) platform_dma_get_ops(dev)
3027

3128
#include <asm-generic/dma-mapping-common.h>

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

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,6 @@ static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
9898
return (dma_addr == DMA_ERROR_CODE);
9999
}
100100

101-
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
102-
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
103-
104101
static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
105102
enum dma_data_direction direction)
106103
{

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

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,4 @@ dma_set_mask(struct device *dev, u64 mask)
6464
extern void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
6565
enum dma_data_direction direction);
6666

67-
void *dma_alloc_noncoherent(struct device *dev, size_t size,
68-
dma_addr_t *dma_handle, gfp_t flag);
69-
70-
void dma_free_noncoherent(struct device *dev, size_t size,
71-
void *vaddr, dma_addr_t dma_handle);
72-
7367
#endif /* _ASM_DMA_MAPPING_H */

arch/mips/mm/dma-default.c

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ static gfp_t massage_gfp_flags(const struct device *dev, gfp_t gfp)
112112
return gfp | dma_flag;
113113
}
114114

115-
void *dma_alloc_noncoherent(struct device *dev, size_t size,
115+
static void *mips_dma_alloc_noncoherent(struct device *dev, size_t size,
116116
dma_addr_t * dma_handle, gfp_t gfp)
117117
{
118118
void *ret;
@@ -128,7 +128,6 @@ void *dma_alloc_noncoherent(struct device *dev, size_t size,
128128

129129
return ret;
130130
}
131-
EXPORT_SYMBOL(dma_alloc_noncoherent);
132131

133132
static void *mips_dma_alloc_coherent(struct device *dev, size_t size,
134133
dma_addr_t * dma_handle, gfp_t gfp, struct dma_attrs *attrs)
@@ -137,6 +136,13 @@ static void *mips_dma_alloc_coherent(struct device *dev, size_t size,
137136
struct page *page = NULL;
138137
unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT;
139138

139+
/*
140+
* XXX: seems like the coherent and non-coherent implementations could
141+
* be consolidated.
142+
*/
143+
if (dma_get_attr(DMA_ATTR_NON_CONSISTENT, attrs))
144+
return mips_dma_alloc_noncoherent(dev, size, dma_handle, gfp);
145+
140146
gfp = massage_gfp_flags(dev, gfp);
141147

142148
if (IS_ENABLED(CONFIG_DMA_CMA) && !(gfp & GFP_ATOMIC))
@@ -161,13 +167,12 @@ static void *mips_dma_alloc_coherent(struct device *dev, size_t size,
161167
}
162168

163169

164-
void dma_free_noncoherent(struct device *dev, size_t size, void *vaddr,
165-
dma_addr_t dma_handle)
170+
static void mips_dma_free_noncoherent(struct device *dev, size_t size,
171+
void *vaddr, dma_addr_t dma_handle)
166172
{
167173
plat_unmap_dma_mem(dev, dma_handle, size, DMA_BIDIRECTIONAL);
168174
free_pages((unsigned long) vaddr, get_order(size));
169175
}
170-
EXPORT_SYMBOL(dma_free_noncoherent);
171176

172177
static void mips_dma_free_coherent(struct device *dev, size_t size, void *vaddr,
173178
dma_addr_t dma_handle, struct dma_attrs *attrs)
@@ -176,6 +181,11 @@ static void mips_dma_free_coherent(struct device *dev, size_t size, void *vaddr,
176181
unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT;
177182
struct page *page = NULL;
178183

184+
if (dma_get_attr(DMA_ATTR_NON_CONSISTENT, attrs)) {
185+
mips_dma_free_noncoherent(dev, size, vaddr, dma_handle);
186+
return;
187+
}
188+
179189
plat_unmap_dma_mem(dev, dma_handle, size, DMA_BIDIRECTIONAL);
180190

181191
if (!plat_device_is_coherent(dev) && !hw_coherentio)

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

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -37,26 +37,6 @@ static inline struct dma_map_ops *get_dma_ops(struct device *dev)
3737

3838
#include <asm-generic/dma-mapping-common.h>
3939

40-
static inline void *dma_alloc_noncoherent(struct device *dev, size_t size,
41-
dma_addr_t *dma_handle, gfp_t gfp)
42-
{
43-
struct dma_attrs attrs;
44-
45-
dma_set_attr(DMA_ATTR_NON_CONSISTENT, &attrs);
46-
47-
return dma_alloc_attrs(dev, size, dma_handle, gfp, &attrs);
48-
}
49-
50-
static inline void dma_free_noncoherent(struct device *dev, size_t size,
51-
void *cpu_addr, dma_addr_t dma_handle)
52-
{
53-
struct dma_attrs attrs;
54-
55-
dma_set_attr(DMA_ATTR_NON_CONSISTENT, &attrs);
56-
57-
dma_free_attrs(dev, size, cpu_addr, dma_handle, &attrs);
58-
}
59-
6040
static inline int dma_supported(struct device *dev, u64 dma_mask)
6141
{
6242
/* Support 32 bit DMA mask exclusively */

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

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -177,9 +177,6 @@ static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr)
177177
return daddr - get_dma_offset(dev);
178178
}
179179

180-
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
181-
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
182-
183180
#define ARCH_HAS_DMA_MMAP_COHERENT
184181

185182
static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size,

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

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,6 @@ static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
2525
{
2626
}
2727

28-
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
29-
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
30-
3128
#include <asm-generic/dma-mapping-common.h>
3229

3330
static inline int dma_supported(struct device *dev, u64 mask)

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

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,6 @@ static inline int dma_set_mask(struct device *dev, u64 mask)
3838
void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
3939
enum dma_data_direction dir);
4040

41-
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
42-
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
43-
4441
static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
4542
{
4643
struct dma_map_ops *ops = get_dma_ops(dev);

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

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,6 @@
99

1010
int dma_supported(struct device *dev, u64 mask);
1111

12-
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
13-
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
14-
1512
static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
1613
enum dma_data_direction dir)
1714
{

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

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,6 @@ dma_set_mask(struct device *dev, u64 mask)
116116
return 0;
117117
}
118118

119-
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_attrs(d, s, h, f, NULL)
120-
#define dma_free_noncoherent(d, s, v, h) dma_free_attrs(d, s, v, h, NULL)
121-
122119
/*
123120
* dma_alloc_noncoherent() is #defined to return coherent memory,
124121
* so there's no need to do any flushing here.

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

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,6 @@ static inline int dma_set_mask(struct device *dev, u64 dma_mask)
8080
return 0;
8181
}
8282

83-
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
84-
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
85-
8683
static inline void dma_cache_sync(struct device *dev, void *vaddr,
8784
size_t size, enum dma_data_direction direction)
8885
{

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

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,6 @@ static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
5656
return (dma_addr == DMA_ERROR_CODE);
5757
}
5858

59-
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
60-
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
61-
6259
extern int dma_supported(struct device *hwdev, u64 mask);
6360
extern int dma_set_mask(struct device *dev, u64 mask);
6461

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

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,6 @@ static inline struct dma_map_ops *get_dma_ops(struct device *dev)
3232

3333
#include <asm-generic/dma-mapping-common.h>
3434

35-
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_attrs(d, s, h, f, NULL)
36-
#define dma_free_noncoherent(d, s, v, h) dma_free_attrs(d, s, v, h, NULL)
37-
3835
static inline int
3936
dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
4037
{

include/asm-generic/dma-mapping-common.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,4 +295,22 @@ static inline void dma_free_coherent(struct device *dev, size_t size,
295295
return dma_free_attrs(dev, size, cpu_addr, dma_handle, NULL);
296296
}
297297

298+
static inline void *dma_alloc_noncoherent(struct device *dev, size_t size,
299+
dma_addr_t *dma_handle, gfp_t gfp)
300+
{
301+
DEFINE_DMA_ATTRS(attrs);
302+
303+
dma_set_attr(DMA_ATTR_NON_CONSISTENT, &attrs);
304+
return dma_alloc_attrs(dev, size, dma_handle, gfp, &attrs);
305+
}
306+
307+
static inline void dma_free_noncoherent(struct device *dev, size_t size,
308+
void *cpu_addr, dma_addr_t dma_handle)
309+
{
310+
DEFINE_DMA_ATTRS(attrs);
311+
312+
dma_set_attr(DMA_ATTR_NON_CONSISTENT, &attrs);
313+
dma_free_attrs(dev, size, cpu_addr, dma_handle, &attrs);
314+
}
315+
298316
#endif

0 commit comments

Comments
 (0)