diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-07-12 18:13:55 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-07-12 18:13:55 -0400 |
| commit | 9e3a25dc992dd9f3170fb643bdd95da5ca9c5576 (patch) | |
| tree | f636ae59fa83c83e837a6668b2693175a6e39f3a /include | |
| parent | 9787aed57dd33ba5c15a713c2c50e78baeb5052d (diff) | |
| parent | 15ffe5e1acf5fe1512e98b20702e46ce9f25e2f7 (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.h | 19 | ||||
| -rw-r--r-- | include/linux/dma-noncoherent.h | 19 | ||||
| -rw-r--r-- | include/linux/genalloc.h | 9 | ||||
| -rw-r--r-- | include/linux/usb/hcd.h | 6 |
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 | ||
| 54 | struct cma; | 55 | struct cma; |
| 55 | struct page; | 56 | struct 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); |
| 112 | bool dma_release_from_contiguous(struct device *dev, struct page *pages, | 113 | bool dma_release_from_contiguous(struct device *dev, struct page *pages, |
| 113 | int count); | 114 | int count); |
| 115 | struct page *dma_alloc_contiguous(struct device *dev, size_t size, gfp_t gfp); | ||
| 116 | void 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 */ | ||
| 160 | static 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 | |||
| 169 | static 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 | */ | ||
| 26 | static __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 | |||
| 23 | void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle, | 39 | void *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); |
| 25 | void arch_dma_free(struct device *dev, size_t size, void *cpu_addr, | 41 | void 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 | ||
| 99 | void *uncached_kernel_address(void *addr); | ||
| 100 | void *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 | ||
| 156 | extern void *gen_pool_dma_alloc(struct gen_pool *pool, size_t size, | 156 | extern void *gen_pool_dma_alloc(struct gen_pool *pool, size_t size, |
| 157 | dma_addr_t *dma); | 157 | dma_addr_t *dma); |
| 158 | extern void *gen_pool_dma_alloc_algo(struct gen_pool *pool, size_t size, | ||
| 159 | dma_addr_t *dma, genpool_algo_t algo, void *data); | ||
| 160 | extern void *gen_pool_dma_alloc_align(struct gen_pool *pool, size_t size, | ||
| 161 | dma_addr_t *dma, int align); | ||
| 162 | extern void *gen_pool_dma_zalloc(struct gen_pool *pool, size_t size, dma_addr_t *dma); | ||
| 163 | extern void *gen_pool_dma_zalloc_algo(struct gen_pool *pool, size_t size, | ||
| 164 | dma_addr_t *dma, genpool_algo_t algo, void *data); | ||
| 165 | extern void *gen_pool_dma_zalloc_align(struct gen_pool *pool, size_t size, | ||
| 166 | dma_addr_t *dma, int align); | ||
| 158 | extern void gen_pool_free_owner(struct gen_pool *pool, unsigned long addr, | 167 | extern void gen_pool_free_owner(struct gen_pool *pool, unsigned long addr, |
| 159 | size_t size, void **owner); | 168 | size_t size, void **owner); |
| 160 | static inline void gen_pool_free(struct gen_pool *pool, unsigned long addr, | 169 | static 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); |
| 462 | extern void usb_remove_hcd(struct usb_hcd *hcd); | 464 | extern void usb_remove_hcd(struct usb_hcd *hcd); |
| 463 | extern int usb_hcd_find_raw_port_number(struct usb_hcd *hcd, int port1); | 465 | extern int usb_hcd_find_raw_port_number(struct usb_hcd *hcd, int port1); |
| 466 | int usb_hcd_setup_local_mem(struct usb_hcd *hcd, phys_addr_t phys_addr, | ||
| 467 | dma_addr_t dma, size_t size); | ||
| 464 | 468 | ||
| 465 | struct platform_device; | 469 | struct platform_device; |
| 466 | extern void usb_hcd_platform_shutdown(struct platform_device *dev); | 470 | extern void usb_hcd_platform_shutdown(struct platform_device *dev); |
