aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-07-12 18:13:55 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2019-07-12 18:13:55 -0400
commit9e3a25dc992dd9f3170fb643bdd95da5ca9c5576 (patch)
treef636ae59fa83c83e837a6668b2693175a6e39f3a /include
parent9787aed57dd33ba5c15a713c2c50e78baeb5052d (diff)
parent15ffe5e1acf5fe1512e98b20702e46ce9f25e2f7 (diff)
Merge tag 'dma-mapping-5.3' of git://git.infradead.org/users/hch/dma-mapping
Pull dma-mapping updates from Christoph Hellwig: - move the USB special case that bounced DMA through a device bar into the USB code instead of handling it in the common DMA code (Laurentiu Tudor and Fredrik Noring) - don't dip into the global CMA pool for single page allocations (Nicolin Chen) - fix a crash when allocating memory for the atomic pool failed during boot (Florian Fainelli) - move support for MIPS-style uncached segments to the common code and use that for MIPS and nios2 (me) - make support for DMA_ATTR_NON_CONSISTENT and DMA_ATTR_NO_KERNEL_MAPPING generic (me) - convert nds32 to the generic remapping allocator (me) * tag 'dma-mapping-5.3' of git://git.infradead.org/users/hch/dma-mapping: (29 commits) dma-mapping: mark dma_alloc_need_uncached as __always_inline MIPS: only select ARCH_HAS_UNCACHED_SEGMENT for non-coherent platforms usb: host: Fix excessive alignment restriction for local memory allocations lib/genalloc.c: Add algorithm, align and zeroed family of DMA allocators nios2: use the generic uncached segment support in dma-direct nds32: use the generic remapping allocator for coherent DMA allocations arc: use the generic remapping allocator for coherent DMA allocations dma-direct: handle DMA_ATTR_NO_KERNEL_MAPPING in common code dma-direct: handle DMA_ATTR_NON_CONSISTENT in common code dma-mapping: add a dma_alloc_need_uncached helper openrisc: remove the partial DMA_ATTR_NON_CONSISTENT support arc: remove the partial DMA_ATTR_NON_CONSISTENT support arm-nommu: remove the partial DMA_ATTR_NON_CONSISTENT support ARM: dma-mapping: allow larger DMA mask than supported dma-mapping: truncate dma masks to what dma_addr_t can hold iommu/dma: Apply dma_{alloc,free}_contiguous functions dma-remap: Avoid de-referencing NULL atomic_pool MIPS: use the generic uncached segment support in dma-direct dma-direct: provide generic support for uncached kernel segments au1100fb: fix DMA API abuse ...
Diffstat (limited to 'include')
-rw-r--r--include/linux/dma-contiguous.h19
-rw-r--r--include/linux/dma-noncoherent.h19
-rw-r--r--include/linux/genalloc.h9
-rw-r--r--include/linux/usb/hcd.h6
4 files changed, 52 insertions, 1 deletions
diff --git a/include/linux/dma-contiguous.h b/include/linux/dma-contiguous.h
index 6665fa03c0d1..c05d4e661489 100644
--- a/include/linux/dma-contiguous.h
+++ b/include/linux/dma-contiguous.h
@@ -50,6 +50,7 @@
50#ifdef __KERNEL__ 50#ifdef __KERNEL__
51 51
52#include <linux/device.h> 52#include <linux/device.h>
53#include <linux/mm.h>
53 54
54struct cma; 55struct cma;
55struct page; 56struct page;
@@ -111,6 +112,8 @@ struct page *dma_alloc_from_contiguous(struct device *dev, size_t count,
111 unsigned int order, bool no_warn); 112 unsigned int order, bool no_warn);
112bool dma_release_from_contiguous(struct device *dev, struct page *pages, 113bool dma_release_from_contiguous(struct device *dev, struct page *pages,
113 int count); 114 int count);
115struct page *dma_alloc_contiguous(struct device *dev, size_t size, gfp_t gfp);
116void dma_free_contiguous(struct device *dev, struct page *page, size_t size);
114 117
115#else 118#else
116 119
@@ -153,6 +156,22 @@ bool dma_release_from_contiguous(struct device *dev, struct page *pages,
153 return false; 156 return false;
154} 157}
155 158
159/* Use fallback alloc() and free() when CONFIG_DMA_CMA=n */
160static inline struct page *dma_alloc_contiguous(struct device *dev, size_t size,
161 gfp_t gfp)
162{
163 int node = dev ? dev_to_node(dev) : NUMA_NO_NODE;
164 size_t align = get_order(PAGE_ALIGN(size));
165
166 return alloc_pages_node(node, gfp, align);
167}
168
169static inline void dma_free_contiguous(struct device *dev, struct page *page,
170 size_t size)
171{
172 __free_pages(page, get_order(size));
173}
174
156#endif 175#endif
157 176
158#endif 177#endif
diff --git a/include/linux/dma-noncoherent.h b/include/linux/dma-noncoherent.h
index 9741767e400f..3813211a9aad 100644
--- a/include/linux/dma-noncoherent.h
+++ b/include/linux/dma-noncoherent.h
@@ -20,6 +20,22 @@ static inline bool dev_is_dma_coherent(struct device *dev)
20} 20}
21#endif /* CONFIG_ARCH_HAS_DMA_COHERENCE_H */ 21#endif /* CONFIG_ARCH_HAS_DMA_COHERENCE_H */
22 22
23/*
24 * Check if an allocation needs to be marked uncached to be coherent.
25 */
26static __always_inline bool dma_alloc_need_uncached(struct device *dev,
27 unsigned long attrs)
28{
29 if (dev_is_dma_coherent(dev))
30 return false;
31 if (attrs & DMA_ATTR_NO_KERNEL_MAPPING)
32 return false;
33 if (IS_ENABLED(CONFIG_DMA_NONCOHERENT_CACHE_SYNC) &&
34 (attrs & DMA_ATTR_NON_CONSISTENT))
35 return false;
36 return true;
37}
38
23void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle, 39void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
24 gfp_t gfp, unsigned long attrs); 40 gfp_t gfp, unsigned long attrs);
25void arch_dma_free(struct device *dev, size_t size, void *cpu_addr, 41void arch_dma_free(struct device *dev, size_t size, void *cpu_addr,
@@ -80,4 +96,7 @@ static inline void arch_dma_prep_coherent(struct page *page, size_t size)
80} 96}
81#endif /* CONFIG_ARCH_HAS_DMA_PREP_COHERENT */ 97#endif /* CONFIG_ARCH_HAS_DMA_PREP_COHERENT */
82 98
99void *uncached_kernel_address(void *addr);
100void *cached_kernel_address(void *addr);
101
83#endif /* _LINUX_DMA_NONCOHERENT_H */ 102#endif /* _LINUX_DMA_NONCOHERENT_H */
diff --git a/include/linux/genalloc.h b/include/linux/genalloc.h
index 205f62b8d291..4bd583bd6934 100644
--- a/include/linux/genalloc.h
+++ b/include/linux/genalloc.h
@@ -155,6 +155,15 @@ static inline unsigned long gen_pool_alloc(struct gen_pool *pool, size_t size)
155 155
156extern void *gen_pool_dma_alloc(struct gen_pool *pool, size_t size, 156extern void *gen_pool_dma_alloc(struct gen_pool *pool, size_t size,
157 dma_addr_t *dma); 157 dma_addr_t *dma);
158extern void *gen_pool_dma_alloc_algo(struct gen_pool *pool, size_t size,
159 dma_addr_t *dma, genpool_algo_t algo, void *data);
160extern void *gen_pool_dma_alloc_align(struct gen_pool *pool, size_t size,
161 dma_addr_t *dma, int align);
162extern void *gen_pool_dma_zalloc(struct gen_pool *pool, size_t size, dma_addr_t *dma);
163extern void *gen_pool_dma_zalloc_algo(struct gen_pool *pool, size_t size,
164 dma_addr_t *dma, genpool_algo_t algo, void *data);
165extern void *gen_pool_dma_zalloc_align(struct gen_pool *pool, size_t size,
166 dma_addr_t *dma, int align);
158extern void gen_pool_free_owner(struct gen_pool *pool, unsigned long addr, 167extern void gen_pool_free_owner(struct gen_pool *pool, unsigned long addr,
159 size_t size, void **owner); 168 size_t size, void **owner);
160static inline void gen_pool_free(struct gen_pool *pool, unsigned long addr, 169static inline void gen_pool_free(struct gen_pool *pool, unsigned long addr,
diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h
index bb57b5af4700..bab27ccc8ff5 100644
--- a/include/linux/usb/hcd.h
+++ b/include/linux/usb/hcd.h
@@ -216,6 +216,9 @@ struct usb_hcd {
216#define HC_IS_RUNNING(state) ((state) & __ACTIVE) 216#define HC_IS_RUNNING(state) ((state) & __ACTIVE)
217#define HC_IS_SUSPENDED(state) ((state) & __SUSPEND) 217#define HC_IS_SUSPENDED(state) ((state) & __SUSPEND)
218 218
219 /* memory pool for HCs having local memory, or %NULL */
220 struct gen_pool *localmem_pool;
221
219 /* more shared queuing code would be good; it should support 222 /* more shared queuing code would be good; it should support
220 * smarter scheduling, handle transaction translators, etc; 223 * smarter scheduling, handle transaction translators, etc;
221 * input size of periodic table to an interrupt scheduler. 224 * input size of periodic table to an interrupt scheduler.
@@ -253,7 +256,6 @@ struct hc_driver {
253 256
254 int flags; 257 int flags;
255#define HCD_MEMORY 0x0001 /* HC regs use memory (else I/O) */ 258#define HCD_MEMORY 0x0001 /* HC regs use memory (else I/O) */
256#define HCD_LOCAL_MEM 0x0002 /* HC needs local memory */
257#define HCD_SHARED 0x0004 /* Two (or more) usb_hcds share HW */ 259#define HCD_SHARED 0x0004 /* Two (or more) usb_hcds share HW */
258#define HCD_USB11 0x0010 /* USB 1.1 */ 260#define HCD_USB11 0x0010 /* USB 1.1 */
259#define HCD_USB2 0x0020 /* USB 2.0 */ 261#define HCD_USB2 0x0020 /* USB 2.0 */
@@ -461,6 +463,8 @@ extern int usb_add_hcd(struct usb_hcd *hcd,
461 unsigned int irqnum, unsigned long irqflags); 463 unsigned int irqnum, unsigned long irqflags);
462extern void usb_remove_hcd(struct usb_hcd *hcd); 464extern void usb_remove_hcd(struct usb_hcd *hcd);
463extern int usb_hcd_find_raw_port_number(struct usb_hcd *hcd, int port1); 465extern int usb_hcd_find_raw_port_number(struct usb_hcd *hcd, int port1);
466int usb_hcd_setup_local_mem(struct usb_hcd *hcd, phys_addr_t phys_addr,
467 dma_addr_t dma, size_t size);
464 468
465struct platform_device; 469struct platform_device;
466extern void usb_hcd_platform_shutdown(struct platform_device *dev); 470extern void usb_hcd_platform_shutdown(struct platform_device *dev);