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 | |
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
...
41 files changed, 515 insertions, 654 deletions
diff --git a/arch/Kconfig b/arch/Kconfig index c47b328eada0..e8d19c3cb91f 100644 --- a/arch/Kconfig +++ b/arch/Kconfig | |||
@@ -260,6 +260,14 @@ config ARCH_HAS_SET_MEMORY | |||
260 | config ARCH_HAS_SET_DIRECT_MAP | 260 | config ARCH_HAS_SET_DIRECT_MAP |
261 | bool | 261 | bool |
262 | 262 | ||
263 | # | ||
264 | # Select if arch has an uncached kernel segment and provides the | ||
265 | # uncached_kernel_address / cached_kernel_address symbols to use it | ||
266 | # | ||
267 | config ARCH_HAS_UNCACHED_SEGMENT | ||
268 | select ARCH_HAS_DMA_PREP_COHERENT | ||
269 | bool | ||
270 | |||
263 | # Select if arch init_task must go in the __init_task_data section | 271 | # Select if arch init_task must go in the __init_task_data section |
264 | config ARCH_TASK_STRUCT_ON_STACK | 272 | config ARCH_TASK_STRUCT_ON_STACK |
265 | bool | 273 | bool |
diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig index 1c8137e7247b..8383155c8c82 100644 --- a/arch/arc/Kconfig +++ b/arch/arc/Kconfig | |||
@@ -7,6 +7,7 @@ config ARC | |||
7 | def_bool y | 7 | def_bool y |
8 | select ARC_TIMERS | 8 | select ARC_TIMERS |
9 | select ARCH_HAS_DMA_COHERENT_TO_PFN | 9 | select ARCH_HAS_DMA_COHERENT_TO_PFN |
10 | select ARCH_HAS_DMA_PREP_COHERENT | ||
10 | select ARCH_HAS_PTE_SPECIAL | 11 | select ARCH_HAS_PTE_SPECIAL |
11 | select ARCH_HAS_SETUP_DMA_OPS | 12 | select ARCH_HAS_SETUP_DMA_OPS |
12 | select ARCH_HAS_SYNC_DMA_FOR_CPU | 13 | select ARCH_HAS_SYNC_DMA_FOR_CPU |
@@ -16,6 +17,7 @@ config ARC | |||
16 | select BUILDTIME_EXTABLE_SORT | 17 | select BUILDTIME_EXTABLE_SORT |
17 | select CLONE_BACKWARDS | 18 | select CLONE_BACKWARDS |
18 | select COMMON_CLK | 19 | select COMMON_CLK |
20 | select DMA_DIRECT_REMAP | ||
19 | select GENERIC_ATOMIC64 if !ISA_ARCV2 || !(ARC_HAS_LL64 && ARC_HAS_LLSC) | 21 | select GENERIC_ATOMIC64 if !ISA_ARCV2 || !(ARC_HAS_LL64 && ARC_HAS_LLSC) |
20 | select GENERIC_CLOCKEVENTS | 22 | select GENERIC_CLOCKEVENTS |
21 | select GENERIC_FIND_FIRST_BIT | 23 | select GENERIC_FIND_FIRST_BIT |
diff --git a/arch/arc/mm/dma.c b/arch/arc/mm/dma.c index 0bf1468c35a3..62c210e7ee4c 100644 --- a/arch/arc/mm/dma.c +++ b/arch/arc/mm/dma.c | |||
@@ -8,51 +8,15 @@ | |||
8 | #include <asm/cacheflush.h> | 8 | #include <asm/cacheflush.h> |
9 | 9 | ||
10 | /* | 10 | /* |
11 | * ARCH specific callbacks for generic noncoherent DMA ops (dma/noncoherent.c) | 11 | * ARCH specific callbacks for generic noncoherent DMA ops |
12 | * - hardware IOC not available (or "dma-coherent" not set for device in DT) | 12 | * - hardware IOC not available (or "dma-coherent" not set for device in DT) |
13 | * - But still handle both coherent and non-coherent requests from caller | 13 | * - But still handle both coherent and non-coherent requests from caller |
14 | * | 14 | * |
15 | * For DMA coherent hardware (IOC) generic code suffices | 15 | * For DMA coherent hardware (IOC) generic code suffices |
16 | */ | 16 | */ |
17 | void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle, | ||
18 | gfp_t gfp, unsigned long attrs) | ||
19 | { | ||
20 | unsigned long order = get_order(size); | ||
21 | struct page *page; | ||
22 | phys_addr_t paddr; | ||
23 | void *kvaddr; | ||
24 | bool need_coh = !(attrs & DMA_ATTR_NON_CONSISTENT); | ||
25 | |||
26 | /* | ||
27 | * __GFP_HIGHMEM flag is cleared by upper layer functions | ||
28 | * (in include/linux/dma-mapping.h) so we should never get a | ||
29 | * __GFP_HIGHMEM here. | ||
30 | */ | ||
31 | BUG_ON(gfp & __GFP_HIGHMEM); | ||
32 | |||
33 | page = alloc_pages(gfp | __GFP_ZERO, order); | ||
34 | if (!page) | ||
35 | return NULL; | ||
36 | |||
37 | /* This is linear addr (0x8000_0000 based) */ | ||
38 | paddr = page_to_phys(page); | ||
39 | |||
40 | *dma_handle = paddr; | ||
41 | |||
42 | /* | ||
43 | * A coherent buffer needs MMU mapping to enforce non-cachability. | ||
44 | * kvaddr is kernel Virtual address (0x7000_0000 based). | ||
45 | */ | ||
46 | if (need_coh) { | ||
47 | kvaddr = ioremap_nocache(paddr, size); | ||
48 | if (kvaddr == NULL) { | ||
49 | __free_pages(page, order); | ||
50 | return NULL; | ||
51 | } | ||
52 | } else { | ||
53 | kvaddr = (void *)(u32)paddr; | ||
54 | } | ||
55 | 17 | ||
18 | void arch_dma_prep_coherent(struct page *page, size_t size) | ||
19 | { | ||
56 | /* | 20 | /* |
57 | * Evict any existing L1 and/or L2 lines for the backing page | 21 | * Evict any existing L1 and/or L2 lines for the backing page |
58 | * in case it was used earlier as a normal "cached" page. | 22 | * in case it was used earlier as a normal "cached" page. |
@@ -63,28 +27,7 @@ void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle, | |||
63 | * Currently flush_cache_vmap nukes the L1 cache completely which | 27 | * Currently flush_cache_vmap nukes the L1 cache completely which |
64 | * will be optimized as a separate commit | 28 | * will be optimized as a separate commit |
65 | */ | 29 | */ |
66 | if (need_coh) | 30 | dma_cache_wback_inv(page_to_phys(page), size); |
67 | dma_cache_wback_inv(paddr, size); | ||
68 | |||
69 | return kvaddr; | ||
70 | } | ||
71 | |||
72 | void arch_dma_free(struct device *dev, size_t size, void *vaddr, | ||
73 | dma_addr_t dma_handle, unsigned long attrs) | ||
74 | { | ||
75 | phys_addr_t paddr = dma_handle; | ||
76 | struct page *page = virt_to_page(paddr); | ||
77 | |||
78 | if (!(attrs & DMA_ATTR_NON_CONSISTENT)) | ||
79 | iounmap((void __force __iomem *)vaddr); | ||
80 | |||
81 | __free_pages(page, get_order(size)); | ||
82 | } | ||
83 | |||
84 | long arch_dma_coherent_to_pfn(struct device *dev, void *cpu_addr, | ||
85 | dma_addr_t dma_addr) | ||
86 | { | ||
87 | return __phys_to_pfn(dma_addr); | ||
88 | } | 31 | } |
89 | 32 | ||
90 | /* | 33 | /* |
@@ -161,3 +104,9 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size, | |||
161 | dev_info(dev, "use %sncoherent DMA ops\n", | 104 | dev_info(dev, "use %sncoherent DMA ops\n", |
162 | dev->dma_coherent ? "" : "non"); | 105 | dev->dma_coherent ? "" : "non"); |
163 | } | 106 | } |
107 | |||
108 | static int __init atomic_pool_init(void) | ||
109 | { | ||
110 | return dma_atomic_pool_init(GFP_KERNEL, pgprot_noncached(PAGE_KERNEL)); | ||
111 | } | ||
112 | postcore_initcall(atomic_pool_init); | ||
diff --git a/arch/arm/mm/dma-mapping-nommu.c b/arch/arm/mm/dma-mapping-nommu.c index 1aea01ba1262..52b82559d99b 100644 --- a/arch/arm/mm/dma-mapping-nommu.c +++ b/arch/arm/mm/dma-mapping-nommu.c | |||
@@ -35,18 +35,7 @@ static void *arm_nommu_dma_alloc(struct device *dev, size_t size, | |||
35 | unsigned long attrs) | 35 | unsigned long attrs) |
36 | 36 | ||
37 | { | 37 | { |
38 | void *ret; | 38 | void *ret = dma_alloc_from_global_coherent(size, dma_handle); |
39 | |||
40 | /* | ||
41 | * Try generic allocator first if we are advertised that | ||
42 | * consistency is not required. | ||
43 | */ | ||
44 | |||
45 | if (attrs & DMA_ATTR_NON_CONSISTENT) | ||
46 | return dma_direct_alloc_pages(dev, size, dma_handle, gfp, | ||
47 | attrs); | ||
48 | |||
49 | ret = dma_alloc_from_global_coherent(size, dma_handle); | ||
50 | 39 | ||
51 | /* | 40 | /* |
52 | * dma_alloc_from_global_coherent() may fail because: | 41 | * dma_alloc_from_global_coherent() may fail because: |
@@ -66,16 +55,9 @@ static void arm_nommu_dma_free(struct device *dev, size_t size, | |||
66 | void *cpu_addr, dma_addr_t dma_addr, | 55 | void *cpu_addr, dma_addr_t dma_addr, |
67 | unsigned long attrs) | 56 | unsigned long attrs) |
68 | { | 57 | { |
69 | if (attrs & DMA_ATTR_NON_CONSISTENT) { | 58 | int ret = dma_release_from_global_coherent(get_order(size), cpu_addr); |
70 | dma_direct_free_pages(dev, size, cpu_addr, dma_addr, attrs); | ||
71 | } else { | ||
72 | int ret = dma_release_from_global_coherent(get_order(size), | ||
73 | cpu_addr); | ||
74 | |||
75 | WARN_ON_ONCE(ret == 0); | ||
76 | } | ||
77 | 59 | ||
78 | return; | 60 | WARN_ON_ONCE(ret == 0); |
79 | } | 61 | } |
80 | 62 | ||
81 | static int arm_nommu_dma_mmap(struct device *dev, struct vm_area_struct *vma, | 63 | static int arm_nommu_dma_mmap(struct device *dev, struct vm_area_struct *vma, |
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index 1fb5c0ca1ed8..4789c60a86e3 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c | |||
@@ -216,25 +216,7 @@ EXPORT_SYMBOL(arm_coherent_dma_ops); | |||
216 | 216 | ||
217 | static int __dma_supported(struct device *dev, u64 mask, bool warn) | 217 | static int __dma_supported(struct device *dev, u64 mask, bool warn) |
218 | { | 218 | { |
219 | unsigned long max_dma_pfn; | 219 | unsigned long max_dma_pfn = min(max_pfn, arm_dma_pfn_limit); |
220 | |||
221 | /* | ||
222 | * If the mask allows for more memory than we can address, | ||
223 | * and we actually have that much memory, then we must | ||
224 | * indicate that DMA to this device is not supported. | ||
225 | */ | ||
226 | if (sizeof(mask) != sizeof(dma_addr_t) && | ||
227 | mask > (dma_addr_t)~0 && | ||
228 | dma_to_pfn(dev, ~0) < max_pfn - 1) { | ||
229 | if (warn) { | ||
230 | dev_warn(dev, "Coherent DMA mask %#llx is larger than dma_addr_t allows\n", | ||
231 | mask); | ||
232 | dev_warn(dev, "Driver did not use or check the return value from dma_set_coherent_mask()?\n"); | ||
233 | } | ||
234 | return 0; | ||
235 | } | ||
236 | |||
237 | max_dma_pfn = min(max_pfn, arm_dma_pfn_limit); | ||
238 | 220 | ||
239 | /* | 221 | /* |
240 | * Translate the device's DMA mask to a PFN limit. This | 222 | * Translate the device's DMA mask to a PFN limit. This |
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 7957d3457156..d50fafd7bf3a 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig | |||
@@ -1121,6 +1121,7 @@ config DMA_NONCOHERENT | |||
1121 | bool | 1121 | bool |
1122 | select ARCH_HAS_DMA_MMAP_PGPROT | 1122 | select ARCH_HAS_DMA_MMAP_PGPROT |
1123 | select ARCH_HAS_SYNC_DMA_FOR_DEVICE | 1123 | select ARCH_HAS_SYNC_DMA_FOR_DEVICE |
1124 | select ARCH_HAS_UNCACHED_SEGMENT | ||
1124 | select NEED_DMA_MAP_STATE | 1125 | select NEED_DMA_MAP_STATE |
1125 | select ARCH_HAS_DMA_COHERENT_TO_PFN | 1126 | select ARCH_HAS_DMA_COHERENT_TO_PFN |
1126 | select DMA_NONCOHERENT_CACHE_SYNC | 1127 | select DMA_NONCOHERENT_CACHE_SYNC |
diff --git a/arch/mips/include/asm/page.h b/arch/mips/include/asm/page.h index a25643d258cb..0ba4ce6e2bf3 100644 --- a/arch/mips/include/asm/page.h +++ b/arch/mips/include/asm/page.h | |||
@@ -258,9 +258,6 @@ extern bool __virt_addr_valid(const volatile void *kaddr); | |||
258 | ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) | \ | 258 | ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) | \ |
259 | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) | 259 | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) |
260 | 260 | ||
261 | #define UNCAC_ADDR(addr) (UNCAC_BASE + __pa(addr)) | ||
262 | #define CAC_ADDR(addr) ((unsigned long)__va((addr) - UNCAC_BASE)) | ||
263 | |||
264 | #include <asm-generic/memory_model.h> | 261 | #include <asm-generic/memory_model.h> |
265 | #include <asm-generic/getorder.h> | 262 | #include <asm-generic/getorder.h> |
266 | 263 | ||
diff --git a/arch/mips/jazz/jazzdma.c b/arch/mips/jazz/jazzdma.c index bedb5047aff3..1804dc9d8136 100644 --- a/arch/mips/jazz/jazzdma.c +++ b/arch/mips/jazz/jazzdma.c | |||
@@ -575,10 +575,6 @@ static void *jazz_dma_alloc(struct device *dev, size_t size, | |||
575 | return NULL; | 575 | return NULL; |
576 | } | 576 | } |
577 | 577 | ||
578 | if (!(attrs & DMA_ATTR_NON_CONSISTENT)) { | ||
579 | dma_cache_wback_inv((unsigned long)ret, size); | ||
580 | ret = (void *)UNCAC_ADDR(ret); | ||
581 | } | ||
582 | return ret; | 578 | return ret; |
583 | } | 579 | } |
584 | 580 | ||
@@ -586,8 +582,6 @@ static void jazz_dma_free(struct device *dev, size_t size, void *vaddr, | |||
586 | dma_addr_t dma_handle, unsigned long attrs) | 582 | dma_addr_t dma_handle, unsigned long attrs) |
587 | { | 583 | { |
588 | vdma_free(dma_handle); | 584 | vdma_free(dma_handle); |
589 | if (!(attrs & DMA_ATTR_NON_CONSISTENT)) | ||
590 | vaddr = (void *)CAC_ADDR((unsigned long)vaddr); | ||
591 | dma_direct_free_pages(dev, size, vaddr, dma_handle, attrs); | 585 | dma_direct_free_pages(dev, size, vaddr, dma_handle, attrs); |
592 | } | 586 | } |
593 | 587 | ||
diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c index 3da216988672..33b409391ddb 100644 --- a/arch/mips/mm/cache.c +++ b/arch/mips/mm/cache.c | |||
@@ -62,8 +62,6 @@ void (*_dma_cache_wback_inv)(unsigned long start, unsigned long size); | |||
62 | void (*_dma_cache_wback)(unsigned long start, unsigned long size); | 62 | void (*_dma_cache_wback)(unsigned long start, unsigned long size); |
63 | void (*_dma_cache_inv)(unsigned long start, unsigned long size); | 63 | void (*_dma_cache_inv)(unsigned long start, unsigned long size); |
64 | 64 | ||
65 | EXPORT_SYMBOL(_dma_cache_wback_inv); | ||
66 | |||
67 | #endif /* CONFIG_DMA_NONCOHERENT */ | 65 | #endif /* CONFIG_DMA_NONCOHERENT */ |
68 | 66 | ||
69 | /* | 67 | /* |
diff --git a/arch/mips/mm/dma-noncoherent.c b/arch/mips/mm/dma-noncoherent.c index f9549d2fbea3..ed56c6fa7be2 100644 --- a/arch/mips/mm/dma-noncoherent.c +++ b/arch/mips/mm/dma-noncoherent.c | |||
@@ -44,33 +44,25 @@ static inline bool cpu_needs_post_dma_flush(struct device *dev) | |||
44 | } | 44 | } |
45 | } | 45 | } |
46 | 46 | ||
47 | void *arch_dma_alloc(struct device *dev, size_t size, | 47 | void arch_dma_prep_coherent(struct page *page, size_t size) |
48 | dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs) | ||
49 | { | 48 | { |
50 | void *ret; | 49 | dma_cache_wback_inv((unsigned long)page_address(page), size); |
51 | 50 | } | |
52 | ret = dma_direct_alloc_pages(dev, size, dma_handle, gfp, attrs); | ||
53 | if (ret && !(attrs & DMA_ATTR_NON_CONSISTENT)) { | ||
54 | dma_cache_wback_inv((unsigned long) ret, size); | ||
55 | ret = (void *)UNCAC_ADDR(ret); | ||
56 | } | ||
57 | 51 | ||
58 | return ret; | 52 | void *uncached_kernel_address(void *addr) |
53 | { | ||
54 | return (void *)(__pa(addr) + UNCAC_BASE); | ||
59 | } | 55 | } |
60 | 56 | ||
61 | void arch_dma_free(struct device *dev, size_t size, void *cpu_addr, | 57 | void *cached_kernel_address(void *addr) |
62 | dma_addr_t dma_addr, unsigned long attrs) | ||
63 | { | 58 | { |
64 | if (!(attrs & DMA_ATTR_NON_CONSISTENT)) | 59 | return __va(addr) - UNCAC_BASE; |
65 | cpu_addr = (void *)CAC_ADDR((unsigned long)cpu_addr); | ||
66 | dma_direct_free_pages(dev, size, cpu_addr, dma_addr, attrs); | ||
67 | } | 60 | } |
68 | 61 | ||
69 | long arch_dma_coherent_to_pfn(struct device *dev, void *cpu_addr, | 62 | long arch_dma_coherent_to_pfn(struct device *dev, void *cpu_addr, |
70 | dma_addr_t dma_addr) | 63 | dma_addr_t dma_addr) |
71 | { | 64 | { |
72 | unsigned long addr = CAC_ADDR((unsigned long)cpu_addr); | 65 | return page_to_pfn(virt_to_page(cached_kernel_address(cpu_addr))); |
73 | return page_to_pfn(virt_to_page((void *)addr)); | ||
74 | } | 66 | } |
75 | 67 | ||
76 | pgprot_t arch_dma_mmap_pgprot(struct device *dev, pgprot_t prot, | 68 | pgprot_t arch_dma_mmap_pgprot(struct device *dev, pgprot_t prot, |
diff --git a/arch/nds32/Kconfig b/arch/nds32/Kconfig index fd0d0639454f..fbd68329737f 100644 --- a/arch/nds32/Kconfig +++ b/arch/nds32/Kconfig | |||
@@ -7,12 +7,14 @@ | |||
7 | config NDS32 | 7 | config NDS32 |
8 | def_bool y | 8 | def_bool y |
9 | select ARCH_32BIT_OFF_T | 9 | select ARCH_32BIT_OFF_T |
10 | select ARCH_HAS_DMA_PREP_COHERENT | ||
10 | select ARCH_HAS_SYNC_DMA_FOR_CPU | 11 | select ARCH_HAS_SYNC_DMA_FOR_CPU |
11 | select ARCH_HAS_SYNC_DMA_FOR_DEVICE | 12 | select ARCH_HAS_SYNC_DMA_FOR_DEVICE |
12 | select ARCH_WANT_FRAME_POINTERS if FTRACE | 13 | select ARCH_WANT_FRAME_POINTERS if FTRACE |
13 | select CLKSRC_MMIO | 14 | select CLKSRC_MMIO |
14 | select CLONE_BACKWARDS | 15 | select CLONE_BACKWARDS |
15 | select COMMON_CLK | 16 | select COMMON_CLK |
17 | select DMA_DIRECT_REMAP | ||
16 | select GENERIC_ATOMIC64 | 18 | select GENERIC_ATOMIC64 |
17 | select GENERIC_CPU_DEVICES | 19 | select GENERIC_CPU_DEVICES |
18 | select GENERIC_CLOCKEVENTS | 20 | select GENERIC_CLOCKEVENTS |
diff --git a/arch/nds32/kernel/dma.c b/arch/nds32/kernel/dma.c index d0dbd4fe9645..490e3720d694 100644 --- a/arch/nds32/kernel/dma.c +++ b/arch/nds32/kernel/dma.c | |||
@@ -3,327 +3,13 @@ | |||
3 | 3 | ||
4 | #include <linux/types.h> | 4 | #include <linux/types.h> |
5 | #include <linux/mm.h> | 5 | #include <linux/mm.h> |
6 | #include <linux/string.h> | ||
7 | #include <linux/dma-noncoherent.h> | 6 | #include <linux/dma-noncoherent.h> |
8 | #include <linux/io.h> | ||
9 | #include <linux/cache.h> | 7 | #include <linux/cache.h> |
10 | #include <linux/highmem.h> | 8 | #include <linux/highmem.h> |
11 | #include <linux/slab.h> | ||
12 | #include <asm/cacheflush.h> | 9 | #include <asm/cacheflush.h> |
13 | #include <asm/tlbflush.h> | 10 | #include <asm/tlbflush.h> |
14 | #include <asm/proc-fns.h> | 11 | #include <asm/proc-fns.h> |
15 | 12 | ||
16 | /* | ||
17 | * This is the page table (2MB) covering uncached, DMA consistent allocations | ||
18 | */ | ||
19 | static pte_t *consistent_pte; | ||
20 | static DEFINE_RAW_SPINLOCK(consistent_lock); | ||
21 | |||
22 | /* | ||
23 | * VM region handling support. | ||
24 | * | ||
25 | * This should become something generic, handling VM region allocations for | ||
26 | * vmalloc and similar (ioremap, module space, etc). | ||
27 | * | ||
28 | * I envisage vmalloc()'s supporting vm_struct becoming: | ||
29 | * | ||
30 | * struct vm_struct { | ||
31 | * struct vm_region region; | ||
32 | * unsigned long flags; | ||
33 | * struct page **pages; | ||
34 | * unsigned int nr_pages; | ||
35 | * unsigned long phys_addr; | ||
36 | * }; | ||
37 | * | ||
38 | * get_vm_area() would then call vm_region_alloc with an appropriate | ||
39 | * struct vm_region head (eg): | ||
40 | * | ||
41 | * struct vm_region vmalloc_head = { | ||
42 | * .vm_list = LIST_HEAD_INIT(vmalloc_head.vm_list), | ||
43 | * .vm_start = VMALLOC_START, | ||
44 | * .vm_end = VMALLOC_END, | ||
45 | * }; | ||
46 | * | ||
47 | * However, vmalloc_head.vm_start is variable (typically, it is dependent on | ||
48 | * the amount of RAM found at boot time.) I would imagine that get_vm_area() | ||
49 | * would have to initialise this each time prior to calling vm_region_alloc(). | ||
50 | */ | ||
51 | struct arch_vm_region { | ||
52 | struct list_head vm_list; | ||
53 | unsigned long vm_start; | ||
54 | unsigned long vm_end; | ||
55 | struct page *vm_pages; | ||
56 | }; | ||
57 | |||
58 | static struct arch_vm_region consistent_head = { | ||
59 | .vm_list = LIST_HEAD_INIT(consistent_head.vm_list), | ||
60 | .vm_start = CONSISTENT_BASE, | ||
61 | .vm_end = CONSISTENT_END, | ||
62 | }; | ||
63 | |||
64 | static struct arch_vm_region *vm_region_alloc(struct arch_vm_region *head, | ||
65 | size_t size, int gfp) | ||
66 | { | ||
67 | unsigned long addr = head->vm_start, end = head->vm_end - size; | ||
68 | unsigned long flags; | ||
69 | struct arch_vm_region *c, *new; | ||
70 | |||
71 | new = kmalloc(sizeof(struct arch_vm_region), gfp); | ||
72 | if (!new) | ||
73 | goto out; | ||
74 | |||
75 | raw_spin_lock_irqsave(&consistent_lock, flags); | ||
76 | |||
77 | list_for_each_entry(c, &head->vm_list, vm_list) { | ||
78 | if ((addr + size) < addr) | ||
79 | goto nospc; | ||
80 | if ((addr + size) <= c->vm_start) | ||
81 | goto found; | ||
82 | addr = c->vm_end; | ||
83 | if (addr > end) | ||
84 | goto nospc; | ||
85 | } | ||
86 | |||
87 | found: | ||
88 | /* | ||
89 | * Insert this entry _before_ the one we found. | ||
90 | */ | ||
91 | list_add_tail(&new->vm_list, &c->vm_list); | ||
92 | new->vm_start = addr; | ||
93 | new->vm_end = addr + size; | ||
94 | |||
95 | raw_spin_unlock_irqrestore(&consistent_lock, flags); | ||
96 | return new; | ||
97 | |||
98 | nospc: | ||
99 | raw_spin_unlock_irqrestore(&consistent_lock, flags); | ||
100 | kfree(new); | ||
101 | out: | ||
102 | return NULL; | ||
103 | } | ||
104 | |||
105 | static struct arch_vm_region *vm_region_find(struct arch_vm_region *head, | ||
106 | unsigned long addr) | ||
107 | { | ||
108 | struct arch_vm_region *c; | ||
109 | |||
110 | list_for_each_entry(c, &head->vm_list, vm_list) { | ||
111 | if (c->vm_start == addr) | ||
112 | goto out; | ||
113 | } | ||
114 | c = NULL; | ||
115 | out: | ||
116 | return c; | ||
117 | } | ||
118 | |||
119 | void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, | ||
120 | gfp_t gfp, unsigned long attrs) | ||
121 | { | ||
122 | struct page *page; | ||
123 | struct arch_vm_region *c; | ||
124 | unsigned long order; | ||
125 | u64 mask = ~0ULL, limit; | ||
126 | pgprot_t prot = pgprot_noncached(PAGE_KERNEL); | ||
127 | |||
128 | if (!consistent_pte) { | ||
129 | pr_err("%s: not initialized\n", __func__); | ||
130 | dump_stack(); | ||
131 | return NULL; | ||
132 | } | ||
133 | |||
134 | if (dev) { | ||
135 | mask = dev->coherent_dma_mask; | ||
136 | |||
137 | /* | ||
138 | * Sanity check the DMA mask - it must be non-zero, and | ||
139 | * must be able to be satisfied by a DMA allocation. | ||
140 | */ | ||
141 | if (mask == 0) { | ||
142 | dev_warn(dev, "coherent DMA mask is unset\n"); | ||
143 | goto no_page; | ||
144 | } | ||
145 | |||
146 | } | ||
147 | |||
148 | /* | ||
149 | * Sanity check the allocation size. | ||
150 | */ | ||
151 | size = PAGE_ALIGN(size); | ||
152 | limit = (mask + 1) & ~mask; | ||
153 | if ((limit && size >= limit) || | ||
154 | size >= (CONSISTENT_END - CONSISTENT_BASE)) { | ||
155 | pr_warn("coherent allocation too big " | ||
156 | "(requested %#x mask %#llx)\n", size, mask); | ||
157 | goto no_page; | ||
158 | } | ||
159 | |||
160 | order = get_order(size); | ||
161 | |||
162 | if (mask != 0xffffffff) | ||
163 | gfp |= GFP_DMA; | ||
164 | |||
165 | page = alloc_pages(gfp, order); | ||
166 | if (!page) | ||
167 | goto no_page; | ||
168 | |||
169 | /* | ||
170 | * Invalidate any data that might be lurking in the | ||
171 | * kernel direct-mapped region for device DMA. | ||
172 | */ | ||
173 | { | ||
174 | unsigned long kaddr = (unsigned long)page_address(page); | ||
175 | memset(page_address(page), 0, size); | ||
176 | cpu_dma_wbinval_range(kaddr, kaddr + size); | ||
177 | } | ||
178 | |||
179 | /* | ||
180 | * Allocate a virtual address in the consistent mapping region. | ||
181 | */ | ||
182 | c = vm_region_alloc(&consistent_head, size, | ||
183 | gfp & ~(__GFP_DMA | __GFP_HIGHMEM)); | ||
184 | if (c) { | ||
185 | pte_t *pte = consistent_pte + CONSISTENT_OFFSET(c->vm_start); | ||
186 | struct page *end = page + (1 << order); | ||
187 | |||
188 | c->vm_pages = page; | ||
189 | |||
190 | /* | ||
191 | * Set the "dma handle" | ||
192 | */ | ||
193 | *handle = page_to_phys(page); | ||
194 | |||
195 | do { | ||
196 | BUG_ON(!pte_none(*pte)); | ||
197 | |||
198 | /* | ||
199 | * x86 does not mark the pages reserved... | ||
200 | */ | ||
201 | SetPageReserved(page); | ||
202 | set_pte(pte, mk_pte(page, prot)); | ||
203 | page++; | ||
204 | pte++; | ||
205 | } while (size -= PAGE_SIZE); | ||
206 | |||
207 | /* | ||
208 | * Free the otherwise unused pages. | ||
209 | */ | ||
210 | while (page < end) { | ||
211 | __free_page(page); | ||
212 | page++; | ||
213 | } | ||
214 | |||
215 | return (void *)c->vm_start; | ||
216 | } | ||
217 | |||
218 | if (page) | ||
219 | __free_pages(page, order); | ||
220 | no_page: | ||
221 | *handle = ~0; | ||
222 | return NULL; | ||
223 | } | ||
224 | |||
225 | void arch_dma_free(struct device *dev, size_t size, void *cpu_addr, | ||
226 | dma_addr_t handle, unsigned long attrs) | ||
227 | { | ||
228 | struct arch_vm_region *c; | ||
229 | unsigned long flags, addr; | ||
230 | pte_t *ptep; | ||
231 | |||
232 | size = PAGE_ALIGN(size); | ||
233 | |||
234 | raw_spin_lock_irqsave(&consistent_lock, flags); | ||
235 | |||
236 | c = vm_region_find(&consistent_head, (unsigned long)cpu_addr); | ||
237 | if (!c) | ||
238 | goto no_area; | ||
239 | |||
240 | if ((c->vm_end - c->vm_start) != size) { | ||
241 | pr_err("%s: freeing wrong coherent size (%ld != %d)\n", | ||
242 | __func__, c->vm_end - c->vm_start, size); | ||
243 | dump_stack(); | ||
244 | size = c->vm_end - c->vm_start; | ||
245 | } | ||
246 | |||
247 | ptep = consistent_pte + CONSISTENT_OFFSET(c->vm_start); | ||
248 | addr = c->vm_start; | ||
249 | do { | ||
250 | pte_t pte = ptep_get_and_clear(&init_mm, addr, ptep); | ||
251 | unsigned long pfn; | ||
252 | |||
253 | ptep++; | ||
254 | addr += PAGE_SIZE; | ||
255 | |||
256 | if (!pte_none(pte) && pte_present(pte)) { | ||
257 | pfn = pte_pfn(pte); | ||
258 | |||
259 | if (pfn_valid(pfn)) { | ||
260 | struct page *page = pfn_to_page(pfn); | ||
261 | |||
262 | /* | ||
263 | * x86 does not mark the pages reserved... | ||
264 | */ | ||
265 | ClearPageReserved(page); | ||
266 | |||
267 | __free_page(page); | ||
268 | continue; | ||
269 | } | ||
270 | } | ||
271 | |||
272 | pr_crit("%s: bad page in kernel page table\n", __func__); | ||
273 | } while (size -= PAGE_SIZE); | ||
274 | |||
275 | flush_tlb_kernel_range(c->vm_start, c->vm_end); | ||
276 | |||
277 | list_del(&c->vm_list); | ||
278 | |||
279 | raw_spin_unlock_irqrestore(&consistent_lock, flags); | ||
280 | |||
281 | kfree(c); | ||
282 | return; | ||
283 | |||
284 | no_area: | ||
285 | raw_spin_unlock_irqrestore(&consistent_lock, flags); | ||
286 | pr_err("%s: trying to free invalid coherent area: %p\n", | ||
287 | __func__, cpu_addr); | ||
288 | dump_stack(); | ||
289 | } | ||
290 | |||
291 | /* | ||
292 | * Initialise the consistent memory allocation. | ||
293 | */ | ||
294 | static int __init consistent_init(void) | ||
295 | { | ||
296 | pgd_t *pgd; | ||
297 | pmd_t *pmd; | ||
298 | pte_t *pte; | ||
299 | int ret = 0; | ||
300 | |||
301 | do { | ||
302 | pgd = pgd_offset(&init_mm, CONSISTENT_BASE); | ||
303 | pmd = pmd_alloc(&init_mm, pgd, CONSISTENT_BASE); | ||
304 | if (!pmd) { | ||
305 | pr_err("%s: no pmd tables\n", __func__); | ||
306 | ret = -ENOMEM; | ||
307 | break; | ||
308 | } | ||
309 | /* The first level mapping may be created in somewhere. | ||
310 | * It's not necessary to warn here. */ | ||
311 | /* WARN_ON(!pmd_none(*pmd)); */ | ||
312 | |||
313 | pte = pte_alloc_kernel(pmd, CONSISTENT_BASE); | ||
314 | if (!pte) { | ||
315 | ret = -ENOMEM; | ||
316 | break; | ||
317 | } | ||
318 | |||
319 | consistent_pte = pte; | ||
320 | } while (0); | ||
321 | |||
322 | return ret; | ||
323 | } | ||
324 | |||
325 | core_initcall(consistent_init); | ||
326 | |||
327 | static inline void cache_op(phys_addr_t paddr, size_t size, | 13 | static inline void cache_op(phys_addr_t paddr, size_t size, |
328 | void (*fn)(unsigned long start, unsigned long end)) | 14 | void (*fn)(unsigned long start, unsigned long end)) |
329 | { | 15 | { |
@@ -389,3 +75,14 @@ void arch_sync_dma_for_cpu(struct device *dev, phys_addr_t paddr, | |||
389 | BUG(); | 75 | BUG(); |
390 | } | 76 | } |
391 | } | 77 | } |
78 | |||
79 | void arch_dma_prep_coherent(struct page *page, size_t size) | ||
80 | { | ||
81 | cache_op(page_to_phys(page), size, cpu_dma_wbinval_range); | ||
82 | } | ||
83 | |||
84 | static int __init atomic_pool_init(void) | ||
85 | { | ||
86 | return dma_atomic_pool_init(GFP_KERNEL, pgprot_noncached(PAGE_KERNEL)); | ||
87 | } | ||
88 | postcore_initcall(atomic_pool_init); | ||
diff --git a/arch/nios2/Kconfig b/arch/nios2/Kconfig index 26a9c760a98b..44b5da37e8bd 100644 --- a/arch/nios2/Kconfig +++ b/arch/nios2/Kconfig | |||
@@ -4,6 +4,7 @@ config NIOS2 | |||
4 | select ARCH_32BIT_OFF_T | 4 | select ARCH_32BIT_OFF_T |
5 | select ARCH_HAS_SYNC_DMA_FOR_CPU | 5 | select ARCH_HAS_SYNC_DMA_FOR_CPU |
6 | select ARCH_HAS_SYNC_DMA_FOR_DEVICE | 6 | select ARCH_HAS_SYNC_DMA_FOR_DEVICE |
7 | select ARCH_HAS_UNCACHED_SEGMENT | ||
7 | select ARCH_NO_SWAP | 8 | select ARCH_NO_SWAP |
8 | select TIMER_OF | 9 | select TIMER_OF |
9 | select GENERIC_ATOMIC64 | 10 | select GENERIC_ATOMIC64 |
diff --git a/arch/nios2/include/asm/page.h b/arch/nios2/include/asm/page.h index f1fbdc47bdaf..79fcac61f6ef 100644 --- a/arch/nios2/include/asm/page.h +++ b/arch/nios2/include/asm/page.h | |||
@@ -101,12 +101,6 @@ static inline bool pfn_valid(unsigned long pfn) | |||
101 | # define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | \ | 101 | # define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | \ |
102 | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) | 102 | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) |
103 | 103 | ||
104 | # define UNCAC_ADDR(addr) \ | ||
105 | ((void *)((unsigned)(addr) | CONFIG_NIOS2_IO_REGION_BASE)) | ||
106 | # define CAC_ADDR(addr) \ | ||
107 | ((void *)(((unsigned)(addr) & ~CONFIG_NIOS2_IO_REGION_BASE) | \ | ||
108 | CONFIG_NIOS2_KERNEL_REGION_BASE)) | ||
109 | |||
110 | #include <asm-generic/memory_model.h> | 104 | #include <asm-generic/memory_model.h> |
111 | 105 | ||
112 | #include <asm-generic/getorder.h> | 106 | #include <asm-generic/getorder.h> |
diff --git a/arch/nios2/mm/dma-mapping.c b/arch/nios2/mm/dma-mapping.c index 4af9e5b5ba1c..9cb238664584 100644 --- a/arch/nios2/mm/dma-mapping.c +++ b/arch/nios2/mm/dma-mapping.c | |||
@@ -60,32 +60,28 @@ void arch_sync_dma_for_cpu(struct device *dev, phys_addr_t paddr, | |||
60 | } | 60 | } |
61 | } | 61 | } |
62 | 62 | ||
63 | void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle, | 63 | void arch_dma_prep_coherent(struct page *page, size_t size) |
64 | gfp_t gfp, unsigned long attrs) | ||
65 | { | 64 | { |
66 | void *ret; | 65 | unsigned long start = (unsigned long)page_address(page); |
67 | 66 | ||
68 | /* optimized page clearing */ | 67 | flush_dcache_range(start, start + size); |
69 | gfp |= __GFP_ZERO; | 68 | } |
70 | 69 | ||
71 | if (dev == NULL || (dev->coherent_dma_mask < 0xffffffff)) | 70 | void *uncached_kernel_address(void *ptr) |
72 | gfp |= GFP_DMA; | 71 | { |
72 | unsigned long addr = (unsigned long)ptr; | ||
73 | 73 | ||
74 | ret = (void *) __get_free_pages(gfp, get_order(size)); | 74 | addr |= CONFIG_NIOS2_IO_REGION_BASE; |
75 | if (ret != NULL) { | ||
76 | *dma_handle = virt_to_phys(ret); | ||
77 | flush_dcache_range((unsigned long) ret, | ||
78 | (unsigned long) ret + size); | ||
79 | ret = UNCAC_ADDR(ret); | ||
80 | } | ||
81 | 75 | ||
82 | return ret; | 76 | return (void *)ptr; |
83 | } | 77 | } |
84 | 78 | ||
85 | void arch_dma_free(struct device *dev, size_t size, void *vaddr, | 79 | void *cached_kernel_address(void *ptr) |
86 | dma_addr_t dma_handle, unsigned long attrs) | ||
87 | { | 80 | { |
88 | unsigned long addr = (unsigned long) CAC_ADDR((unsigned long) vaddr); | 81 | unsigned long addr = (unsigned long)ptr; |
82 | |||
83 | addr &= ~CONFIG_NIOS2_IO_REGION_BASE; | ||
84 | addr |= CONFIG_NIOS2_KERNEL_REGION_BASE; | ||
89 | 85 | ||
90 | free_pages(addr, get_order(size)); | 86 | return (void *)ptr; |
91 | } | 87 | } |
diff --git a/arch/openrisc/kernel/dma.c b/arch/openrisc/kernel/dma.c index 43e340c4cd9c..b41a79fcdbd9 100644 --- a/arch/openrisc/kernel/dma.c +++ b/arch/openrisc/kernel/dma.c | |||
@@ -94,15 +94,13 @@ arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle, | |||
94 | 94 | ||
95 | va = (unsigned long)page; | 95 | va = (unsigned long)page; |
96 | 96 | ||
97 | if ((attrs & DMA_ATTR_NON_CONSISTENT) == 0) { | 97 | /* |
98 | /* | 98 | * We need to iterate through the pages, clearing the dcache for |
99 | * We need to iterate through the pages, clearing the dcache for | 99 | * them and setting the cache-inhibit bit. |
100 | * them and setting the cache-inhibit bit. | 100 | */ |
101 | */ | 101 | if (walk_page_range(va, va + size, &walk)) { |
102 | if (walk_page_range(va, va + size, &walk)) { | 102 | free_pages_exact(page, size); |
103 | free_pages_exact(page, size); | 103 | return NULL; |
104 | return NULL; | ||
105 | } | ||
106 | } | 104 | } |
107 | 105 | ||
108 | return (void *)va; | 106 | return (void *)va; |
@@ -118,10 +116,8 @@ arch_dma_free(struct device *dev, size_t size, void *vaddr, | |||
118 | .mm = &init_mm | 116 | .mm = &init_mm |
119 | }; | 117 | }; |
120 | 118 | ||
121 | if ((attrs & DMA_ATTR_NON_CONSISTENT) == 0) { | 119 | /* walk_page_range shouldn't be able to fail here */ |
122 | /* walk_page_range shouldn't be able to fail here */ | 120 | WARN_ON(walk_page_range(va, va + size, &walk)); |
123 | WARN_ON(walk_page_range(va, va + size, &walk)); | ||
124 | } | ||
125 | 121 | ||
126 | free_pages_exact(vaddr, size); | 122 | free_pages_exact(vaddr, size); |
127 | } | 123 | } |
diff --git a/arch/parisc/kernel/pci-dma.c b/arch/parisc/kernel/pci-dma.c index 239162355b58..ca35d9a76e50 100644 --- a/arch/parisc/kernel/pci-dma.c +++ b/arch/parisc/kernel/pci-dma.c | |||
@@ -394,17 +394,20 @@ pcxl_dma_init(void) | |||
394 | 394 | ||
395 | __initcall(pcxl_dma_init); | 395 | __initcall(pcxl_dma_init); |
396 | 396 | ||
397 | static void *pcxl_dma_alloc(struct device *dev, size_t size, | 397 | void *arch_dma_alloc(struct device *dev, size_t size, |
398 | dma_addr_t *dma_handle, gfp_t flag, unsigned long attrs) | 398 | dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs) |
399 | { | 399 | { |
400 | unsigned long vaddr; | 400 | unsigned long vaddr; |
401 | unsigned long paddr; | 401 | unsigned long paddr; |
402 | int order; | 402 | int order; |
403 | 403 | ||
404 | if (boot_cpu_data.cpu_type != pcxl2 && boot_cpu_data.cpu_type != pcxl) | ||
405 | return NULL; | ||
406 | |||
404 | order = get_order(size); | 407 | order = get_order(size); |
405 | size = 1 << (order + PAGE_SHIFT); | 408 | size = 1 << (order + PAGE_SHIFT); |
406 | vaddr = pcxl_alloc_range(size); | 409 | vaddr = pcxl_alloc_range(size); |
407 | paddr = __get_free_pages(flag | __GFP_ZERO, order); | 410 | paddr = __get_free_pages(gfp | __GFP_ZERO, order); |
408 | flush_kernel_dcache_range(paddr, size); | 411 | flush_kernel_dcache_range(paddr, size); |
409 | paddr = __pa(paddr); | 412 | paddr = __pa(paddr); |
410 | map_uncached_pages(vaddr, size, paddr); | 413 | map_uncached_pages(vaddr, size, paddr); |
@@ -421,44 +424,19 @@ static void *pcxl_dma_alloc(struct device *dev, size_t size, | |||
421 | return (void *)vaddr; | 424 | return (void *)vaddr; |
422 | } | 425 | } |
423 | 426 | ||
424 | static void *pcx_dma_alloc(struct device *dev, size_t size, | ||
425 | dma_addr_t *dma_handle, gfp_t flag, unsigned long attrs) | ||
426 | { | ||
427 | void *addr; | ||
428 | |||
429 | if ((attrs & DMA_ATTR_NON_CONSISTENT) == 0) | ||
430 | return NULL; | ||
431 | |||
432 | addr = (void *)__get_free_pages(flag | __GFP_ZERO, get_order(size)); | ||
433 | if (addr) | ||
434 | *dma_handle = (dma_addr_t)virt_to_phys(addr); | ||
435 | |||
436 | return addr; | ||
437 | } | ||
438 | |||
439 | void *arch_dma_alloc(struct device *dev, size_t size, | ||
440 | dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs) | ||
441 | { | ||
442 | |||
443 | if (boot_cpu_data.cpu_type == pcxl2 || boot_cpu_data.cpu_type == pcxl) | ||
444 | return pcxl_dma_alloc(dev, size, dma_handle, gfp, attrs); | ||
445 | else | ||
446 | return pcx_dma_alloc(dev, size, dma_handle, gfp, attrs); | ||
447 | } | ||
448 | |||
449 | void arch_dma_free(struct device *dev, size_t size, void *vaddr, | 427 | void arch_dma_free(struct device *dev, size_t size, void *vaddr, |
450 | dma_addr_t dma_handle, unsigned long attrs) | 428 | dma_addr_t dma_handle, unsigned long attrs) |
451 | { | 429 | { |
452 | int order = get_order(size); | 430 | int order = get_order(size); |
453 | 431 | ||
454 | if (boot_cpu_data.cpu_type == pcxl2 || boot_cpu_data.cpu_type == pcxl) { | 432 | WARN_ON_ONCE(boot_cpu_data.cpu_type != pcxl2 && |
455 | size = 1 << (order + PAGE_SHIFT); | 433 | boot_cpu_data.cpu_type != pcxl); |
456 | unmap_uncached_pages((unsigned long)vaddr, size); | ||
457 | pcxl_free_range((unsigned long)vaddr, size); | ||
458 | 434 | ||
459 | vaddr = __va(dma_handle); | 435 | size = 1 << (order + PAGE_SHIFT); |
460 | } | 436 | unmap_uncached_pages((unsigned long)vaddr, size); |
461 | free_pages((unsigned long)vaddr, get_order(size)); | 437 | pcxl_free_range((unsigned long)vaddr, size); |
438 | |||
439 | free_pages((unsigned long)__va(dma_handle), order); | ||
462 | } | 440 | } |
463 | 441 | ||
464 | void arch_sync_dma_for_device(struct device *dev, phys_addr_t paddr, | 442 | void arch_sync_dma_for_device(struct device *dev, phys_addr_t paddr, |
diff --git a/arch/xtensa/kernel/pci-dma.c b/arch/xtensa/kernel/pci-dma.c index a87f8a308cc1..65f05776d827 100644 --- a/arch/xtensa/kernel/pci-dma.c +++ b/arch/xtensa/kernel/pci-dma.c | |||
@@ -163,10 +163,6 @@ void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, | |||
163 | 163 | ||
164 | *handle = phys_to_dma(dev, page_to_phys(page)); | 164 | *handle = phys_to_dma(dev, page_to_phys(page)); |
165 | 165 | ||
166 | if (attrs & DMA_ATTR_NO_KERNEL_MAPPING) { | ||
167 | return page; | ||
168 | } | ||
169 | |||
170 | #ifdef CONFIG_MMU | 166 | #ifdef CONFIG_MMU |
171 | if (PageHighMem(page)) { | 167 | if (PageHighMem(page)) { |
172 | void *p; | 168 | void *p; |
@@ -192,9 +188,7 @@ void arch_dma_free(struct device *dev, size_t size, void *vaddr, | |||
192 | unsigned long count = PAGE_ALIGN(size) >> PAGE_SHIFT; | 188 | unsigned long count = PAGE_ALIGN(size) >> PAGE_SHIFT; |
193 | struct page *page; | 189 | struct page *page; |
194 | 190 | ||
195 | if (attrs & DMA_ATTR_NO_KERNEL_MAPPING) { | 191 | if (platform_vaddr_uncached(vaddr)) { |
196 | page = vaddr; | ||
197 | } else if (platform_vaddr_uncached(vaddr)) { | ||
198 | page = virt_to_page(platform_vaddr_to_cached(vaddr)); | 192 | page = virt_to_page(platform_vaddr_to_cached(vaddr)); |
199 | } else { | 193 | } else { |
200 | #ifdef CONFIG_MMU | 194 | #ifdef CONFIG_MMU |
diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c index f802255219d3..a7f9c3edbcb2 100644 --- a/drivers/iommu/dma-iommu.c +++ b/drivers/iommu/dma-iommu.c | |||
@@ -951,8 +951,8 @@ static void __iommu_dma_free(struct device *dev, size_t size, void *cpu_addr) | |||
951 | 951 | ||
952 | if (pages) | 952 | if (pages) |
953 | __iommu_dma_free_pages(pages, count); | 953 | __iommu_dma_free_pages(pages, count); |
954 | if (page && !dma_release_from_contiguous(dev, page, count)) | 954 | if (page) |
955 | __free_pages(page, get_order(alloc_size)); | 955 | dma_free_contiguous(dev, page, alloc_size); |
956 | } | 956 | } |
957 | 957 | ||
958 | static void iommu_dma_free(struct device *dev, size_t size, void *cpu_addr, | 958 | static void iommu_dma_free(struct device *dev, size_t size, void *cpu_addr, |
@@ -970,12 +970,7 @@ static void *iommu_dma_alloc_pages(struct device *dev, size_t size, | |||
970 | struct page *page = NULL; | 970 | struct page *page = NULL; |
971 | void *cpu_addr; | 971 | void *cpu_addr; |
972 | 972 | ||
973 | if (gfpflags_allow_blocking(gfp)) | 973 | page = dma_alloc_contiguous(dev, alloc_size, gfp); |
974 | page = dma_alloc_from_contiguous(dev, alloc_size >> PAGE_SHIFT, | ||
975 | get_order(alloc_size), | ||
976 | gfp & __GFP_NOWARN); | ||
977 | if (!page) | ||
978 | page = alloc_pages(gfp, get_order(alloc_size)); | ||
979 | if (!page) | 974 | if (!page) |
980 | return NULL; | 975 | return NULL; |
981 | 976 | ||
@@ -997,8 +992,7 @@ static void *iommu_dma_alloc_pages(struct device *dev, size_t size, | |||
997 | memset(cpu_addr, 0, alloc_size); | 992 | memset(cpu_addr, 0, alloc_size); |
998 | return cpu_addr; | 993 | return cpu_addr; |
999 | out_free_pages: | 994 | out_free_pages: |
1000 | if (!dma_release_from_contiguous(dev, page, alloc_size >> PAGE_SHIFT)) | 995 | dma_free_contiguous(dev, page, alloc_size); |
1001 | __free_pages(page, get_order(alloc_size)); | ||
1002 | return NULL; | 996 | return NULL; |
1003 | } | 997 | } |
1004 | 998 | ||
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig index 94573fb68304..6e59d370ef81 100644 --- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig | |||
@@ -45,6 +45,7 @@ config USB_ARCH_HAS_HCD | |||
45 | config USB | 45 | config USB |
46 | tristate "Support for Host-side USB" | 46 | tristate "Support for Host-side USB" |
47 | depends on USB_ARCH_HAS_HCD | 47 | depends on USB_ARCH_HAS_HCD |
48 | select GENERIC_ALLOCATOR | ||
48 | select USB_COMMON | 49 | select USB_COMMON |
49 | select NLS # for UTF-8 strings | 50 | select NLS # for UTF-8 strings |
50 | ---help--- | 51 | ---help--- |
diff --git a/drivers/usb/core/buffer.c b/drivers/usb/core/buffer.c index f641342cdec0..1359b78a624e 100644 --- a/drivers/usb/core/buffer.c +++ b/drivers/usb/core/buffer.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/io.h> | 16 | #include <linux/io.h> |
17 | #include <linux/dma-mapping.h> | 17 | #include <linux/dma-mapping.h> |
18 | #include <linux/dmapool.h> | 18 | #include <linux/dmapool.h> |
19 | #include <linux/genalloc.h> | ||
19 | #include <linux/usb.h> | 20 | #include <linux/usb.h> |
20 | #include <linux/usb/hcd.h> | 21 | #include <linux/usb/hcd.h> |
21 | 22 | ||
@@ -67,7 +68,7 @@ int hcd_buffer_create(struct usb_hcd *hcd) | |||
67 | 68 | ||
68 | if (!IS_ENABLED(CONFIG_HAS_DMA) || | 69 | if (!IS_ENABLED(CONFIG_HAS_DMA) || |
69 | (!is_device_dma_capable(hcd->self.sysdev) && | 70 | (!is_device_dma_capable(hcd->self.sysdev) && |
70 | !(hcd->driver->flags & HCD_LOCAL_MEM))) | 71 | !hcd->localmem_pool)) |
71 | return 0; | 72 | return 0; |
72 | 73 | ||
73 | for (i = 0; i < HCD_BUFFER_POOLS; i++) { | 74 | for (i = 0; i < HCD_BUFFER_POOLS; i++) { |
@@ -124,10 +125,12 @@ void *hcd_buffer_alloc( | |||
124 | if (size == 0) | 125 | if (size == 0) |
125 | return NULL; | 126 | return NULL; |
126 | 127 | ||
128 | if (hcd->localmem_pool) | ||
129 | return gen_pool_dma_alloc(hcd->localmem_pool, size, dma); | ||
130 | |||
127 | /* some USB hosts just use PIO */ | 131 | /* some USB hosts just use PIO */ |
128 | if (!IS_ENABLED(CONFIG_HAS_DMA) || | 132 | if (!IS_ENABLED(CONFIG_HAS_DMA) || |
129 | (!is_device_dma_capable(bus->sysdev) && | 133 | !is_device_dma_capable(bus->sysdev)) { |
130 | !(hcd->driver->flags & HCD_LOCAL_MEM))) { | ||
131 | *dma = ~(dma_addr_t) 0; | 134 | *dma = ~(dma_addr_t) 0; |
132 | return kmalloc(size, mem_flags); | 135 | return kmalloc(size, mem_flags); |
133 | } | 136 | } |
@@ -152,9 +155,13 @@ void hcd_buffer_free( | |||
152 | if (!addr) | 155 | if (!addr) |
153 | return; | 156 | return; |
154 | 157 | ||
158 | if (hcd->localmem_pool) { | ||
159 | gen_pool_free(hcd->localmem_pool, (unsigned long)addr, size); | ||
160 | return; | ||
161 | } | ||
162 | |||
155 | if (!IS_ENABLED(CONFIG_HAS_DMA) || | 163 | if (!IS_ENABLED(CONFIG_HAS_DMA) || |
156 | (!is_device_dma_capable(bus->sysdev) && | 164 | !is_device_dma_capable(bus->sysdev)) { |
157 | !(hcd->driver->flags & HCD_LOCAL_MEM))) { | ||
158 | kfree(addr); | 165 | kfree(addr); |
159 | return; | 166 | return; |
160 | } | 167 | } |
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 94d22551fc1b..88533938ce19 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
@@ -29,6 +29,8 @@ | |||
29 | #include <linux/workqueue.h> | 29 | #include <linux/workqueue.h> |
30 | #include <linux/pm_runtime.h> | 30 | #include <linux/pm_runtime.h> |
31 | #include <linux/types.h> | 31 | #include <linux/types.h> |
32 | #include <linux/genalloc.h> | ||
33 | #include <linux/io.h> | ||
32 | 34 | ||
33 | #include <linux/phy/phy.h> | 35 | #include <linux/phy/phy.h> |
34 | #include <linux/usb.h> | 36 | #include <linux/usb.h> |
@@ -1345,14 +1347,14 @@ EXPORT_SYMBOL_GPL(usb_hcd_unlink_urb_from_ep); | |||
1345 | * using regular system memory - like pci devices doing bus mastering. | 1347 | * using regular system memory - like pci devices doing bus mastering. |
1346 | * | 1348 | * |
1347 | * To support host controllers with limited dma capabilities we provide dma | 1349 | * To support host controllers with limited dma capabilities we provide dma |
1348 | * bounce buffers. This feature can be enabled using the HCD_LOCAL_MEM flag. | 1350 | * bounce buffers. This feature can be enabled by initializing |
1351 | * hcd->localmem_pool using usb_hcd_setup_local_mem(). | ||
1349 | * For this to work properly the host controller code must first use the | 1352 | * For this to work properly the host controller code must first use the |
1350 | * function dma_declare_coherent_memory() to point out which memory area | 1353 | * function dma_declare_coherent_memory() to point out which memory area |
1351 | * that should be used for dma allocations. | 1354 | * that should be used for dma allocations. |
1352 | * | 1355 | * |
1353 | * The HCD_LOCAL_MEM flag then tells the usb code to allocate all data for | 1356 | * The initialized hcd->localmem_pool then tells the usb code to allocate all |
1354 | * dma using dma_alloc_coherent() which in turn allocates from the memory | 1357 | * data for dma using the genalloc API. |
1355 | * area pointed out with dma_declare_coherent_memory(). | ||
1356 | * | 1358 | * |
1357 | * So, to summarize... | 1359 | * So, to summarize... |
1358 | * | 1360 | * |
@@ -1362,9 +1364,6 @@ EXPORT_SYMBOL_GPL(usb_hcd_unlink_urb_from_ep); | |||
1362 | * (a) "normal" kernel memory is no good, and | 1364 | * (a) "normal" kernel memory is no good, and |
1363 | * (b) there's not enough to share | 1365 | * (b) there's not enough to share |
1364 | * | 1366 | * |
1365 | * - The only *portable* hook for such stuff in the | ||
1366 | * DMA framework is dma_declare_coherent_memory() | ||
1367 | * | ||
1368 | * - So we use that, even though the primary requirement | 1367 | * - So we use that, even though the primary requirement |
1369 | * is that the memory be "local" (hence addressable | 1368 | * is that the memory be "local" (hence addressable |
1370 | * by that device), not "coherent". | 1369 | * by that device), not "coherent". |
@@ -1531,7 +1530,7 @@ int usb_hcd_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb, | |||
1531 | urb->setup_dma)) | 1530 | urb->setup_dma)) |
1532 | return -EAGAIN; | 1531 | return -EAGAIN; |
1533 | urb->transfer_flags |= URB_SETUP_MAP_SINGLE; | 1532 | urb->transfer_flags |= URB_SETUP_MAP_SINGLE; |
1534 | } else if (hcd->driver->flags & HCD_LOCAL_MEM) { | 1533 | } else if (hcd->localmem_pool) { |
1535 | ret = hcd_alloc_coherent( | 1534 | ret = hcd_alloc_coherent( |
1536 | urb->dev->bus, mem_flags, | 1535 | urb->dev->bus, mem_flags, |
1537 | &urb->setup_dma, | 1536 | &urb->setup_dma, |
@@ -1601,7 +1600,7 @@ int usb_hcd_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb, | |||
1601 | else | 1600 | else |
1602 | urb->transfer_flags |= URB_DMA_MAP_SINGLE; | 1601 | urb->transfer_flags |= URB_DMA_MAP_SINGLE; |
1603 | } | 1602 | } |
1604 | } else if (hcd->driver->flags & HCD_LOCAL_MEM) { | 1603 | } else if (hcd->localmem_pool) { |
1605 | ret = hcd_alloc_coherent( | 1604 | ret = hcd_alloc_coherent( |
1606 | urb->dev->bus, mem_flags, | 1605 | urb->dev->bus, mem_flags, |
1607 | &urb->transfer_dma, | 1606 | &urb->transfer_dma, |
@@ -3039,6 +3038,40 @@ usb_hcd_platform_shutdown(struct platform_device *dev) | |||
3039 | } | 3038 | } |
3040 | EXPORT_SYMBOL_GPL(usb_hcd_platform_shutdown); | 3039 | EXPORT_SYMBOL_GPL(usb_hcd_platform_shutdown); |
3041 | 3040 | ||
3041 | int usb_hcd_setup_local_mem(struct usb_hcd *hcd, phys_addr_t phys_addr, | ||
3042 | dma_addr_t dma, size_t size) | ||
3043 | { | ||
3044 | int err; | ||
3045 | void *local_mem; | ||
3046 | |||
3047 | hcd->localmem_pool = devm_gen_pool_create(hcd->self.sysdev, 4, | ||
3048 | dev_to_node(hcd->self.sysdev), | ||
3049 | dev_name(hcd->self.sysdev)); | ||
3050 | if (IS_ERR(hcd->localmem_pool)) | ||
3051 | return PTR_ERR(hcd->localmem_pool); | ||
3052 | |||
3053 | local_mem = devm_memremap(hcd->self.sysdev, phys_addr, | ||
3054 | size, MEMREMAP_WC); | ||
3055 | if (!local_mem) | ||
3056 | return -ENOMEM; | ||
3057 | |||
3058 | /* | ||
3059 | * Here we pass a dma_addr_t but the arg type is a phys_addr_t. | ||
3060 | * It's not backed by system memory and thus there's no kernel mapping | ||
3061 | * for it. | ||
3062 | */ | ||
3063 | err = gen_pool_add_virt(hcd->localmem_pool, (unsigned long)local_mem, | ||
3064 | dma, size, dev_to_node(hcd->self.sysdev)); | ||
3065 | if (err < 0) { | ||
3066 | dev_err(hcd->self.sysdev, "gen_pool_add_virt failed with %d\n", | ||
3067 | err); | ||
3068 | return err; | ||
3069 | } | ||
3070 | |||
3071 | return 0; | ||
3072 | } | ||
3073 | EXPORT_SYMBOL_GPL(usb_hcd_setup_local_mem); | ||
3074 | |||
3042 | /*-------------------------------------------------------------------------*/ | 3075 | /*-------------------------------------------------------------------------*/ |
3043 | 3076 | ||
3044 | #if IS_ENABLED(CONFIG_USB_MON) | 3077 | #if IS_ENABLED(CONFIG_USB_MON) |
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index cdafa97f632d..9da7e22848c9 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c | |||
@@ -559,7 +559,7 @@ static int ehci_init(struct usb_hcd *hcd) | |||
559 | ehci->command = temp; | 559 | ehci->command = temp; |
560 | 560 | ||
561 | /* Accept arbitrarily long scatter-gather lists */ | 561 | /* Accept arbitrarily long scatter-gather lists */ |
562 | if (!(hcd->driver->flags & HCD_LOCAL_MEM)) | 562 | if (!hcd->localmem_pool) |
563 | hcd->self.sg_tablesize = ~0; | 563 | hcd->self.sg_tablesize = ~0; |
564 | 564 | ||
565 | /* Prepare for unlinking active QHs */ | 565 | /* Prepare for unlinking active QHs */ |
diff --git a/drivers/usb/host/fotg210-hcd.c b/drivers/usb/host/fotg210-hcd.c index e835a22b12af..77cc36efae95 100644 --- a/drivers/usb/host/fotg210-hcd.c +++ b/drivers/usb/host/fotg210-hcd.c | |||
@@ -4996,7 +4996,7 @@ static int hcd_fotg210_init(struct usb_hcd *hcd) | |||
4996 | fotg210->command = temp; | 4996 | fotg210->command = temp; |
4997 | 4997 | ||
4998 | /* Accept arbitrarily long scatter-gather lists */ | 4998 | /* Accept arbitrarily long scatter-gather lists */ |
4999 | if (!(hcd->driver->flags & HCD_LOCAL_MEM)) | 4999 | if (!hcd->localmem_pool) |
5000 | hcd->self.sg_tablesize = ~0; | 5000 | hcd->self.sg_tablesize = ~0; |
5001 | return 0; | 5001 | return 0; |
5002 | } | 5002 | } |
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 210181fd98d2..b457fdaff297 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <linux/dmapool.h> | 40 | #include <linux/dmapool.h> |
41 | #include <linux/workqueue.h> | 41 | #include <linux/workqueue.h> |
42 | #include <linux/debugfs.h> | 42 | #include <linux/debugfs.h> |
43 | #include <linux/genalloc.h> | ||
43 | 44 | ||
44 | #include <asm/io.h> | 45 | #include <asm/io.h> |
45 | #include <asm/irq.h> | 46 | #include <asm/irq.h> |
@@ -447,7 +448,7 @@ static int ohci_init (struct ohci_hcd *ohci) | |||
447 | struct usb_hcd *hcd = ohci_to_hcd(ohci); | 448 | struct usb_hcd *hcd = ohci_to_hcd(ohci); |
448 | 449 | ||
449 | /* Accept arbitrarily long scatter-gather lists */ | 450 | /* Accept arbitrarily long scatter-gather lists */ |
450 | if (!(hcd->driver->flags & HCD_LOCAL_MEM)) | 451 | if (!hcd->localmem_pool) |
451 | hcd->self.sg_tablesize = ~0; | 452 | hcd->self.sg_tablesize = ~0; |
452 | 453 | ||
453 | if (distrust_firmware) | 454 | if (distrust_firmware) |
@@ -505,8 +506,15 @@ static int ohci_init (struct ohci_hcd *ohci) | |||
505 | timer_setup(&ohci->io_watchdog, io_watchdog_func, 0); | 506 | timer_setup(&ohci->io_watchdog, io_watchdog_func, 0); |
506 | ohci->prev_frame_no = IO_WATCHDOG_OFF; | 507 | ohci->prev_frame_no = IO_WATCHDOG_OFF; |
507 | 508 | ||
508 | ohci->hcca = dma_alloc_coherent (hcd->self.controller, | 509 | if (hcd->localmem_pool) |
509 | sizeof(*ohci->hcca), &ohci->hcca_dma, GFP_KERNEL); | 510 | ohci->hcca = gen_pool_dma_alloc_align(hcd->localmem_pool, |
511 | sizeof(*ohci->hcca), | ||
512 | &ohci->hcca_dma, 256); | ||
513 | else | ||
514 | ohci->hcca = dma_alloc_coherent(hcd->self.controller, | ||
515 | sizeof(*ohci->hcca), | ||
516 | &ohci->hcca_dma, | ||
517 | GFP_KERNEL); | ||
510 | if (!ohci->hcca) | 518 | if (!ohci->hcca) |
511 | return -ENOMEM; | 519 | return -ENOMEM; |
512 | 520 | ||
@@ -990,9 +998,14 @@ static void ohci_stop (struct usb_hcd *hcd) | |||
990 | remove_debug_files (ohci); | 998 | remove_debug_files (ohci); |
991 | ohci_mem_cleanup (ohci); | 999 | ohci_mem_cleanup (ohci); |
992 | if (ohci->hcca) { | 1000 | if (ohci->hcca) { |
993 | dma_free_coherent (hcd->self.controller, | 1001 | if (hcd->localmem_pool) |
994 | sizeof *ohci->hcca, | 1002 | gen_pool_free(hcd->localmem_pool, |
995 | ohci->hcca, ohci->hcca_dma); | 1003 | (unsigned long)ohci->hcca, |
1004 | sizeof(*ohci->hcca)); | ||
1005 | else | ||
1006 | dma_free_coherent(hcd->self.controller, | ||
1007 | sizeof(*ohci->hcca), | ||
1008 | ohci->hcca, ohci->hcca_dma); | ||
996 | ohci->hcca = NULL; | 1009 | ohci->hcca = NULL; |
997 | ohci->hcca_dma = 0; | 1010 | ohci->hcca_dma = 0; |
998 | } | 1011 | } |
diff --git a/drivers/usb/host/ohci-mem.c b/drivers/usb/host/ohci-mem.c index 3965ac0341eb..1425335c6baf 100644 --- a/drivers/usb/host/ohci-mem.c +++ b/drivers/usb/host/ohci-mem.c | |||
@@ -36,6 +36,13 @@ static void ohci_hcd_init (struct ohci_hcd *ohci) | |||
36 | 36 | ||
37 | static int ohci_mem_init (struct ohci_hcd *ohci) | 37 | static int ohci_mem_init (struct ohci_hcd *ohci) |
38 | { | 38 | { |
39 | /* | ||
40 | * HCs with local memory allocate from localmem_pool so there's | ||
41 | * no need to create the below dma pools. | ||
42 | */ | ||
43 | if (ohci_to_hcd(ohci)->localmem_pool) | ||
44 | return 0; | ||
45 | |||
39 | ohci->td_cache = dma_pool_create ("ohci_td", | 46 | ohci->td_cache = dma_pool_create ("ohci_td", |
40 | ohci_to_hcd(ohci)->self.controller, | 47 | ohci_to_hcd(ohci)->self.controller, |
41 | sizeof (struct td), | 48 | sizeof (struct td), |
@@ -84,8 +91,13 @@ td_alloc (struct ohci_hcd *hc, gfp_t mem_flags) | |||
84 | { | 91 | { |
85 | dma_addr_t dma; | 92 | dma_addr_t dma; |
86 | struct td *td; | 93 | struct td *td; |
94 | struct usb_hcd *hcd = ohci_to_hcd(hc); | ||
87 | 95 | ||
88 | td = dma_pool_zalloc (hc->td_cache, mem_flags, &dma); | 96 | if (hcd->localmem_pool) |
97 | td = gen_pool_dma_zalloc_align(hcd->localmem_pool, | ||
98 | sizeof(*td), &dma, 32); | ||
99 | else | ||
100 | td = dma_pool_zalloc(hc->td_cache, mem_flags, &dma); | ||
89 | if (td) { | 101 | if (td) { |
90 | /* in case hc fetches it, make it look dead */ | 102 | /* in case hc fetches it, make it look dead */ |
91 | td->hwNextTD = cpu_to_hc32 (hc, dma); | 103 | td->hwNextTD = cpu_to_hc32 (hc, dma); |
@@ -99,6 +111,7 @@ static void | |||
99 | td_free (struct ohci_hcd *hc, struct td *td) | 111 | td_free (struct ohci_hcd *hc, struct td *td) |
100 | { | 112 | { |
101 | struct td **prev = &hc->td_hash [TD_HASH_FUNC (td->td_dma)]; | 113 | struct td **prev = &hc->td_hash [TD_HASH_FUNC (td->td_dma)]; |
114 | struct usb_hcd *hcd = ohci_to_hcd(hc); | ||
102 | 115 | ||
103 | while (*prev && *prev != td) | 116 | while (*prev && *prev != td) |
104 | prev = &(*prev)->td_hash; | 117 | prev = &(*prev)->td_hash; |
@@ -106,7 +119,12 @@ td_free (struct ohci_hcd *hc, struct td *td) | |||
106 | *prev = td->td_hash; | 119 | *prev = td->td_hash; |
107 | else if ((td->hwINFO & cpu_to_hc32(hc, TD_DONE)) != 0) | 120 | else if ((td->hwINFO & cpu_to_hc32(hc, TD_DONE)) != 0) |
108 | ohci_dbg (hc, "no hash for td %p\n", td); | 121 | ohci_dbg (hc, "no hash for td %p\n", td); |
109 | dma_pool_free (hc->td_cache, td, td->td_dma); | 122 | |
123 | if (hcd->localmem_pool) | ||
124 | gen_pool_free(hcd->localmem_pool, (unsigned long)td, | ||
125 | sizeof(*td)); | ||
126 | else | ||
127 | dma_pool_free(hc->td_cache, td, td->td_dma); | ||
110 | } | 128 | } |
111 | 129 | ||
112 | /*-------------------------------------------------------------------------*/ | 130 | /*-------------------------------------------------------------------------*/ |
@@ -117,8 +135,13 @@ ed_alloc (struct ohci_hcd *hc, gfp_t mem_flags) | |||
117 | { | 135 | { |
118 | dma_addr_t dma; | 136 | dma_addr_t dma; |
119 | struct ed *ed; | 137 | struct ed *ed; |
138 | struct usb_hcd *hcd = ohci_to_hcd(hc); | ||
120 | 139 | ||
121 | ed = dma_pool_zalloc (hc->ed_cache, mem_flags, &dma); | 140 | if (hcd->localmem_pool) |
141 | ed = gen_pool_dma_zalloc_align(hcd->localmem_pool, | ||
142 | sizeof(*ed), &dma, 16); | ||
143 | else | ||
144 | ed = dma_pool_zalloc(hc->ed_cache, mem_flags, &dma); | ||
122 | if (ed) { | 145 | if (ed) { |
123 | INIT_LIST_HEAD (&ed->td_list); | 146 | INIT_LIST_HEAD (&ed->td_list); |
124 | ed->dma = dma; | 147 | ed->dma = dma; |
@@ -129,6 +152,12 @@ ed_alloc (struct ohci_hcd *hc, gfp_t mem_flags) | |||
129 | static void | 152 | static void |
130 | ed_free (struct ohci_hcd *hc, struct ed *ed) | 153 | ed_free (struct ohci_hcd *hc, struct ed *ed) |
131 | { | 154 | { |
132 | dma_pool_free (hc->ed_cache, ed, ed->dma); | 155 | struct usb_hcd *hcd = ohci_to_hcd(hc); |
156 | |||
157 | if (hcd->localmem_pool) | ||
158 | gen_pool_free(hcd->localmem_pool, (unsigned long)ed, | ||
159 | sizeof(*ed)); | ||
160 | else | ||
161 | dma_pool_free(hc->ed_cache, ed, ed->dma); | ||
133 | } | 162 | } |
134 | 163 | ||
diff --git a/drivers/usb/host/ohci-sm501.c b/drivers/usb/host/ohci-sm501.c index c26228c25f99..c158cda9e4b9 100644 --- a/drivers/usb/host/ohci-sm501.c +++ b/drivers/usb/host/ohci-sm501.c | |||
@@ -49,7 +49,7 @@ static const struct hc_driver ohci_sm501_hc_driver = { | |||
49 | * generic hardware linkage | 49 | * generic hardware linkage |
50 | */ | 50 | */ |
51 | .irq = ohci_irq, | 51 | .irq = ohci_irq, |
52 | .flags = HCD_USB11 | HCD_MEMORY | HCD_LOCAL_MEM, | 52 | .flags = HCD_USB11 | HCD_MEMORY, |
53 | 53 | ||
54 | /* | 54 | /* |
55 | * basic lifecycle operations | 55 | * basic lifecycle operations |
@@ -110,40 +110,18 @@ static int ohci_hcd_sm501_drv_probe(struct platform_device *pdev) | |||
110 | goto err0; | 110 | goto err0; |
111 | } | 111 | } |
112 | 112 | ||
113 | /* The sm501 chip is equipped with local memory that may be used | ||
114 | * by on-chip devices such as the video controller and the usb host. | ||
115 | * This driver uses dma_declare_coherent_memory() to make sure | ||
116 | * usb allocations with dma_alloc_coherent() allocate from | ||
117 | * this local memory. The dma_handle returned by dma_alloc_coherent() | ||
118 | * will be an offset starting from 0 for the first local memory byte. | ||
119 | * | ||
120 | * So as long as data is allocated using dma_alloc_coherent() all is | ||
121 | * fine. This is however not always the case - buffers may be allocated | ||
122 | * using kmalloc() - so the usb core needs to be told that it must copy | ||
123 | * data into our local memory if the buffers happen to be placed in | ||
124 | * regular memory. The HCD_LOCAL_MEM flag does just that. | ||
125 | */ | ||
126 | |||
127 | retval = dma_declare_coherent_memory(dev, mem->start, | ||
128 | mem->start - mem->parent->start, | ||
129 | resource_size(mem)); | ||
130 | if (retval) { | ||
131 | dev_err(dev, "cannot declare coherent memory\n"); | ||
132 | goto err1; | ||
133 | } | ||
134 | |||
135 | /* allocate, reserve and remap resources for registers */ | 113 | /* allocate, reserve and remap resources for registers */ |
136 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 114 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
137 | if (res == NULL) { | 115 | if (res == NULL) { |
138 | dev_err(dev, "no resource definition for registers\n"); | 116 | dev_err(dev, "no resource definition for registers\n"); |
139 | retval = -ENOENT; | 117 | retval = -ENOENT; |
140 | goto err2; | 118 | goto err1; |
141 | } | 119 | } |
142 | 120 | ||
143 | hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev)); | 121 | hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev)); |
144 | if (!hcd) { | 122 | if (!hcd) { |
145 | retval = -ENOMEM; | 123 | retval = -ENOMEM; |
146 | goto err2; | 124 | goto err1; |
147 | } | 125 | } |
148 | 126 | ||
149 | hcd->rsrc_start = res->start; | 127 | hcd->rsrc_start = res->start; |
@@ -164,6 +142,25 @@ static int ohci_hcd_sm501_drv_probe(struct platform_device *pdev) | |||
164 | 142 | ||
165 | ohci_hcd_init(hcd_to_ohci(hcd)); | 143 | ohci_hcd_init(hcd_to_ohci(hcd)); |
166 | 144 | ||
145 | /* The sm501 chip is equipped with local memory that may be used | ||
146 | * by on-chip devices such as the video controller and the usb host. | ||
147 | * This driver uses genalloc so that usb allocations with | ||
148 | * gen_pool_dma_alloc() allocate from this local memory. The dma_handle | ||
149 | * returned by gen_pool_dma_alloc() will be an offset starting from 0 | ||
150 | * for the first local memory byte. | ||
151 | * | ||
152 | * So as long as data is allocated using gen_pool_dma_alloc() all is | ||
153 | * fine. This is however not always the case - buffers may be allocated | ||
154 | * using kmalloc() - so the usb core needs to be told that it must copy | ||
155 | * data into our local memory if the buffers happen to be placed in | ||
156 | * regular memory. A non-null hcd->localmem_pool initialized by the | ||
157 | * the call to usb_hcd_setup_local_mem() below does just that. | ||
158 | */ | ||
159 | |||
160 | if (usb_hcd_setup_local_mem(hcd, mem->start, | ||
161 | mem->start - mem->parent->start, | ||
162 | resource_size(mem)) < 0) | ||
163 | goto err5; | ||
167 | retval = usb_add_hcd(hcd, irq, IRQF_SHARED); | 164 | retval = usb_add_hcd(hcd, irq, IRQF_SHARED); |
168 | if (retval) | 165 | if (retval) |
169 | goto err5; | 166 | goto err5; |
@@ -181,8 +178,6 @@ err4: | |||
181 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | 178 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); |
182 | err3: | 179 | err3: |
183 | usb_put_hcd(hcd); | 180 | usb_put_hcd(hcd); |
184 | err2: | ||
185 | dma_release_declared_memory(dev); | ||
186 | err1: | 181 | err1: |
187 | release_mem_region(mem->start, resource_size(mem)); | 182 | release_mem_region(mem->start, resource_size(mem)); |
188 | err0: | 183 | err0: |
@@ -197,7 +192,6 @@ static int ohci_hcd_sm501_drv_remove(struct platform_device *pdev) | |||
197 | usb_remove_hcd(hcd); | 192 | usb_remove_hcd(hcd); |
198 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | 193 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); |
199 | usb_put_hcd(hcd); | 194 | usb_put_hcd(hcd); |
200 | dma_release_declared_memory(&pdev->dev); | ||
201 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 1); | 195 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 1); |
202 | if (mem) | 196 | if (mem) |
203 | release_mem_region(mem->start, resource_size(mem)); | 197 | release_mem_region(mem->start, resource_size(mem)); |
diff --git a/drivers/usb/host/ohci-tmio.c b/drivers/usb/host/ohci-tmio.c index f88a0370659f..d5a293a707b6 100644 --- a/drivers/usb/host/ohci-tmio.c +++ b/drivers/usb/host/ohci-tmio.c | |||
@@ -153,7 +153,7 @@ static const struct hc_driver ohci_tmio_hc_driver = { | |||
153 | 153 | ||
154 | /* generic hardware linkage */ | 154 | /* generic hardware linkage */ |
155 | .irq = ohci_irq, | 155 | .irq = ohci_irq, |
156 | .flags = HCD_USB11 | HCD_MEMORY | HCD_LOCAL_MEM, | 156 | .flags = HCD_USB11 | HCD_MEMORY, |
157 | 157 | ||
158 | /* basic lifecycle operations */ | 158 | /* basic lifecycle operations */ |
159 | .start = ohci_tmio_start, | 159 | .start = ohci_tmio_start, |
@@ -224,11 +224,6 @@ static int ohci_hcd_tmio_drv_probe(struct platform_device *dev) | |||
224 | goto err_ioremap_regs; | 224 | goto err_ioremap_regs; |
225 | } | 225 | } |
226 | 226 | ||
227 | ret = dma_declare_coherent_memory(&dev->dev, sram->start, sram->start, | ||
228 | resource_size(sram)); | ||
229 | if (ret) | ||
230 | goto err_dma_declare; | ||
231 | |||
232 | if (cell->enable) { | 227 | if (cell->enable) { |
233 | ret = cell->enable(dev); | 228 | ret = cell->enable(dev); |
234 | if (ret) | 229 | if (ret) |
@@ -239,6 +234,11 @@ static int ohci_hcd_tmio_drv_probe(struct platform_device *dev) | |||
239 | ohci = hcd_to_ohci(hcd); | 234 | ohci = hcd_to_ohci(hcd); |
240 | ohci_hcd_init(ohci); | 235 | ohci_hcd_init(ohci); |
241 | 236 | ||
237 | ret = usb_hcd_setup_local_mem(hcd, sram->start, sram->start, | ||
238 | resource_size(sram)); | ||
239 | if (ret < 0) | ||
240 | goto err_enable; | ||
241 | |||
242 | ret = usb_add_hcd(hcd, irq, 0); | 242 | ret = usb_add_hcd(hcd, irq, 0); |
243 | if (ret) | 243 | if (ret) |
244 | goto err_add_hcd; | 244 | goto err_add_hcd; |
@@ -254,8 +254,6 @@ err_add_hcd: | |||
254 | if (cell->disable) | 254 | if (cell->disable) |
255 | cell->disable(dev); | 255 | cell->disable(dev); |
256 | err_enable: | 256 | err_enable: |
257 | dma_release_declared_memory(&dev->dev); | ||
258 | err_dma_declare: | ||
259 | iounmap(hcd->regs); | 257 | iounmap(hcd->regs); |
260 | err_ioremap_regs: | 258 | err_ioremap_regs: |
261 | iounmap(tmio->ccr); | 259 | iounmap(tmio->ccr); |
@@ -276,7 +274,6 @@ static int ohci_hcd_tmio_drv_remove(struct platform_device *dev) | |||
276 | tmio_stop_hc(dev); | 274 | tmio_stop_hc(dev); |
277 | if (cell->disable) | 275 | if (cell->disable) |
278 | cell->disable(dev); | 276 | cell->disable(dev); |
279 | dma_release_declared_memory(&dev->dev); | ||
280 | iounmap(hcd->regs); | 277 | iounmap(hcd->regs); |
281 | iounmap(tmio->ccr); | 278 | iounmap(tmio->ccr); |
282 | usb_put_hcd(hcd); | 279 | usb_put_hcd(hcd); |
diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h index ef4813bfc5bf..b015b00774b2 100644 --- a/drivers/usb/host/ohci.h +++ b/drivers/usb/host/ohci.h | |||
@@ -385,6 +385,8 @@ struct ohci_hcd { | |||
385 | 385 | ||
386 | /* | 386 | /* |
387 | * memory management for queue data structures | 387 | * memory management for queue data structures |
388 | * | ||
389 | * @td_cache and @ed_cache are %NULL if &usb_hcd.localmem_pool is used. | ||
388 | */ | 390 | */ |
389 | struct dma_pool *td_cache; | 391 | struct dma_pool *td_cache; |
390 | struct dma_pool *ed_cache; | 392 | struct dma_pool *ed_cache; |
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index 98deb5f64268..03bc59755123 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c | |||
@@ -581,7 +581,7 @@ static int uhci_start(struct usb_hcd *hcd) | |||
581 | 581 | ||
582 | hcd->uses_new_polling = 1; | 582 | hcd->uses_new_polling = 1; |
583 | /* Accept arbitrarily long scatter-gather lists */ | 583 | /* Accept arbitrarily long scatter-gather lists */ |
584 | if (!(hcd->driver->flags & HCD_LOCAL_MEM)) | 584 | if (!hcd->localmem_pool) |
585 | hcd->self.sg_tablesize = ~0; | 585 | hcd->self.sg_tablesize = ~0; |
586 | 586 | ||
587 | spin_lock_init(&uhci->lock); | 587 | spin_lock_init(&uhci->lock); |
diff --git a/drivers/video/fbdev/au1100fb.c b/drivers/video/fbdev/au1100fb.c index 0adf0683cf08..99941ae1f3a1 100644 --- a/drivers/video/fbdev/au1100fb.c +++ b/drivers/video/fbdev/au1100fb.c | |||
@@ -340,14 +340,12 @@ int au1100fb_fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *fbi) | |||
340 | */ | 340 | */ |
341 | int au1100fb_fb_mmap(struct fb_info *fbi, struct vm_area_struct *vma) | 341 | int au1100fb_fb_mmap(struct fb_info *fbi, struct vm_area_struct *vma) |
342 | { | 342 | { |
343 | struct au1100fb_device *fbdev; | 343 | struct au1100fb_device *fbdev = to_au1100fb_device(fbi); |
344 | |||
345 | fbdev = to_au1100fb_device(fbi); | ||
346 | 344 | ||
347 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); | ||
348 | pgprot_val(vma->vm_page_prot) |= (6 << 9); //CCA=6 | 345 | pgprot_val(vma->vm_page_prot) |= (6 << 9); //CCA=6 |
349 | 346 | ||
350 | return vm_iomap_memory(vma, fbdev->fb_phys, fbdev->fb_len); | 347 | return dma_mmap_coherent(fbdev->dev, vma, fbdev->fb_mem, fbdev->fb_phys, |
348 | fbdev->fb_len); | ||
351 | } | 349 | } |
352 | 350 | ||
353 | static struct fb_ops au1100fb_ops = | 351 | static struct fb_ops au1100fb_ops = |
@@ -412,7 +410,6 @@ static int au1100fb_drv_probe(struct platform_device *dev) | |||
412 | { | 410 | { |
413 | struct au1100fb_device *fbdev; | 411 | struct au1100fb_device *fbdev; |
414 | struct resource *regs_res; | 412 | struct resource *regs_res; |
415 | unsigned long page; | ||
416 | struct clk *c; | 413 | struct clk *c; |
417 | 414 | ||
418 | /* Allocate new device private */ | 415 | /* Allocate new device private */ |
@@ -424,6 +421,7 @@ static int au1100fb_drv_probe(struct platform_device *dev) | |||
424 | goto failed; | 421 | goto failed; |
425 | 422 | ||
426 | platform_set_drvdata(dev, (void *)fbdev); | 423 | platform_set_drvdata(dev, (void *)fbdev); |
424 | fbdev->dev = &dev->dev; | ||
427 | 425 | ||
428 | /* Allocate region for our registers and map them */ | 426 | /* Allocate region for our registers and map them */ |
429 | regs_res = platform_get_resource(dev, IORESOURCE_MEM, 0); | 427 | regs_res = platform_get_resource(dev, IORESOURCE_MEM, 0); |
@@ -472,20 +470,6 @@ static int au1100fb_drv_probe(struct platform_device *dev) | |||
472 | au1100fb_fix.smem_start = fbdev->fb_phys; | 470 | au1100fb_fix.smem_start = fbdev->fb_phys; |
473 | au1100fb_fix.smem_len = fbdev->fb_len; | 471 | au1100fb_fix.smem_len = fbdev->fb_len; |
474 | 472 | ||
475 | /* | ||
476 | * Set page reserved so that mmap will work. This is necessary | ||
477 | * since we'll be remapping normal memory. | ||
478 | */ | ||
479 | for (page = (unsigned long)fbdev->fb_mem; | ||
480 | page < PAGE_ALIGN((unsigned long)fbdev->fb_mem + fbdev->fb_len); | ||
481 | page += PAGE_SIZE) { | ||
482 | #ifdef CONFIG_DMA_NONCOHERENT | ||
483 | SetPageReserved(virt_to_page(CAC_ADDR((void *)page))); | ||
484 | #else | ||
485 | SetPageReserved(virt_to_page(page)); | ||
486 | #endif | ||
487 | } | ||
488 | |||
489 | print_dbg("Framebuffer memory map at %p", fbdev->fb_mem); | 473 | print_dbg("Framebuffer memory map at %p", fbdev->fb_mem); |
490 | print_dbg("phys=0x%08x, size=%dK", fbdev->fb_phys, fbdev->fb_len / 1024); | 474 | print_dbg("phys=0x%08x, size=%dK", fbdev->fb_phys, fbdev->fb_len / 1024); |
491 | 475 | ||
diff --git a/drivers/video/fbdev/au1100fb.h b/drivers/video/fbdev/au1100fb.h index 9af19939a9c6..e7239bceefd3 100644 --- a/drivers/video/fbdev/au1100fb.h +++ b/drivers/video/fbdev/au1100fb.h | |||
@@ -110,6 +110,7 @@ struct au1100fb_device { | |||
110 | dma_addr_t fb_phys; | 110 | dma_addr_t fb_phys; |
111 | int panel_idx; | 111 | int panel_idx; |
112 | struct clk *lcdclk; | 112 | struct clk *lcdclk; |
113 | struct device *dev; | ||
113 | }; | 114 | }; |
114 | 115 | ||
115 | /********************************************************************/ | 116 | /********************************************************************/ |
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); |
diff --git a/kernel/dma/contiguous.c b/kernel/dma/contiguous.c index b2a87905846d..bfc0c17f2a3d 100644 --- a/kernel/dma/contiguous.c +++ b/kernel/dma/contiguous.c | |||
@@ -214,6 +214,62 @@ bool dma_release_from_contiguous(struct device *dev, struct page *pages, | |||
214 | return cma_release(dev_get_cma_area(dev), pages, count); | 214 | return cma_release(dev_get_cma_area(dev), pages, count); |
215 | } | 215 | } |
216 | 216 | ||
217 | /** | ||
218 | * dma_alloc_contiguous() - allocate contiguous pages | ||
219 | * @dev: Pointer to device for which the allocation is performed. | ||
220 | * @size: Requested allocation size. | ||
221 | * @gfp: Allocation flags. | ||
222 | * | ||
223 | * This function allocates contiguous memory buffer for specified device. It | ||
224 | * first tries to use device specific contiguous memory area if available or | ||
225 | * the default global one, then tries a fallback allocation of normal pages. | ||
226 | * | ||
227 | * Note that it byapss one-page size of allocations from the global area as | ||
228 | * the addresses within one page are always contiguous, so there is no need | ||
229 | * to waste CMA pages for that kind; it also helps reduce fragmentations. | ||
230 | */ | ||
231 | struct page *dma_alloc_contiguous(struct device *dev, size_t size, gfp_t gfp) | ||
232 | { | ||
233 | int node = dev ? dev_to_node(dev) : NUMA_NO_NODE; | ||
234 | size_t count = PAGE_ALIGN(size) >> PAGE_SHIFT; | ||
235 | size_t align = get_order(PAGE_ALIGN(size)); | ||
236 | struct page *page = NULL; | ||
237 | struct cma *cma = NULL; | ||
238 | |||
239 | if (dev && dev->cma_area) | ||
240 | cma = dev->cma_area; | ||
241 | else if (count > 1) | ||
242 | cma = dma_contiguous_default_area; | ||
243 | |||
244 | /* CMA can be used only in the context which permits sleeping */ | ||
245 | if (cma && gfpflags_allow_blocking(gfp)) { | ||
246 | align = min_t(size_t, align, CONFIG_CMA_ALIGNMENT); | ||
247 | page = cma_alloc(cma, count, align, gfp & __GFP_NOWARN); | ||
248 | } | ||
249 | |||
250 | /* Fallback allocation of normal pages */ | ||
251 | if (!page) | ||
252 | page = alloc_pages_node(node, gfp, align); | ||
253 | return page; | ||
254 | } | ||
255 | |||
256 | /** | ||
257 | * dma_free_contiguous() - release allocated pages | ||
258 | * @dev: Pointer to device for which the pages were allocated. | ||
259 | * @page: Pointer to the allocated pages. | ||
260 | * @size: Size of allocated pages. | ||
261 | * | ||
262 | * This function releases memory allocated by dma_alloc_contiguous(). As the | ||
263 | * cma_release returns false when provided pages do not belong to contiguous | ||
264 | * area and true otherwise, this function then does a fallback __free_pages() | ||
265 | * upon a false-return. | ||
266 | */ | ||
267 | void dma_free_contiguous(struct device *dev, struct page *page, size_t size) | ||
268 | { | ||
269 | if (!cma_release(dev_get_cma_area(dev), page, size >> PAGE_SHIFT)) | ||
270 | __free_pages(page, get_order(size)); | ||
271 | } | ||
272 | |||
217 | /* | 273 | /* |
218 | * Support for reserved memory regions defined in device tree | 274 | * Support for reserved memory regions defined in device tree |
219 | */ | 275 | */ |
diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c index 2c2772e9702a..b90e1aede743 100644 --- a/kernel/dma/direct.c +++ b/kernel/dma/direct.c | |||
@@ -96,8 +96,6 @@ static bool dma_coherent_ok(struct device *dev, phys_addr_t phys, size_t size) | |||
96 | struct page *__dma_direct_alloc_pages(struct device *dev, size_t size, | 96 | struct page *__dma_direct_alloc_pages(struct device *dev, size_t size, |
97 | dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs) | 97 | dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs) |
98 | { | 98 | { |
99 | unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT; | ||
100 | int page_order = get_order(size); | ||
101 | struct page *page = NULL; | 99 | struct page *page = NULL; |
102 | u64 phys_mask; | 100 | u64 phys_mask; |
103 | 101 | ||
@@ -109,20 +107,9 @@ struct page *__dma_direct_alloc_pages(struct device *dev, size_t size, | |||
109 | gfp |= __dma_direct_optimal_gfp_mask(dev, dev->coherent_dma_mask, | 107 | gfp |= __dma_direct_optimal_gfp_mask(dev, dev->coherent_dma_mask, |
110 | &phys_mask); | 108 | &phys_mask); |
111 | again: | 109 | again: |
112 | /* CMA can be used only in the context which permits sleeping */ | 110 | page = dma_alloc_contiguous(dev, size, gfp); |
113 | if (gfpflags_allow_blocking(gfp)) { | ||
114 | page = dma_alloc_from_contiguous(dev, count, page_order, | ||
115 | gfp & __GFP_NOWARN); | ||
116 | if (page && !dma_coherent_ok(dev, page_to_phys(page), size)) { | ||
117 | dma_release_from_contiguous(dev, page, count); | ||
118 | page = NULL; | ||
119 | } | ||
120 | } | ||
121 | if (!page) | ||
122 | page = alloc_pages_node(dev_to_node(dev), gfp, page_order); | ||
123 | |||
124 | if (page && !dma_coherent_ok(dev, page_to_phys(page), size)) { | 111 | if (page && !dma_coherent_ok(dev, page_to_phys(page), size)) { |
125 | __free_pages(page, page_order); | 112 | dma_free_contiguous(dev, page, size); |
126 | page = NULL; | 113 | page = NULL; |
127 | 114 | ||
128 | if (IS_ENABLED(CONFIG_ZONE_DMA32) && | 115 | if (IS_ENABLED(CONFIG_ZONE_DMA32) && |
@@ -151,10 +138,18 @@ void *dma_direct_alloc_pages(struct device *dev, size_t size, | |||
151 | if (!page) | 138 | if (!page) |
152 | return NULL; | 139 | return NULL; |
153 | 140 | ||
141 | if (attrs & DMA_ATTR_NO_KERNEL_MAPPING) { | ||
142 | /* remove any dirty cache lines on the kernel alias */ | ||
143 | if (!PageHighMem(page)) | ||
144 | arch_dma_prep_coherent(page, size); | ||
145 | /* return the page pointer as the opaque cookie */ | ||
146 | return page; | ||
147 | } | ||
148 | |||
154 | if (PageHighMem(page)) { | 149 | if (PageHighMem(page)) { |
155 | /* | 150 | /* |
156 | * Depending on the cma= arguments and per-arch setup | 151 | * Depending on the cma= arguments and per-arch setup |
157 | * dma_alloc_from_contiguous could return highmem pages. | 152 | * dma_alloc_contiguous could return highmem pages. |
158 | * Without remapping there is no way to return them here, | 153 | * Without remapping there is no way to return them here, |
159 | * so log an error and fail. | 154 | * so log an error and fail. |
160 | */ | 155 | */ |
@@ -171,15 +166,19 @@ void *dma_direct_alloc_pages(struct device *dev, size_t size, | |||
171 | *dma_handle = phys_to_dma(dev, page_to_phys(page)); | 166 | *dma_handle = phys_to_dma(dev, page_to_phys(page)); |
172 | } | 167 | } |
173 | memset(ret, 0, size); | 168 | memset(ret, 0, size); |
169 | |||
170 | if (IS_ENABLED(CONFIG_ARCH_HAS_UNCACHED_SEGMENT) && | ||
171 | dma_alloc_need_uncached(dev, attrs)) { | ||
172 | arch_dma_prep_coherent(page, size); | ||
173 | ret = uncached_kernel_address(ret); | ||
174 | } | ||
175 | |||
174 | return ret; | 176 | return ret; |
175 | } | 177 | } |
176 | 178 | ||
177 | void __dma_direct_free_pages(struct device *dev, size_t size, struct page *page) | 179 | void __dma_direct_free_pages(struct device *dev, size_t size, struct page *page) |
178 | { | 180 | { |
179 | unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT; | 181 | dma_free_contiguous(dev, page, size); |
180 | |||
181 | if (!dma_release_from_contiguous(dev, page, count)) | ||
182 | __free_pages(page, get_order(size)); | ||
183 | } | 182 | } |
184 | 183 | ||
185 | void dma_direct_free_pages(struct device *dev, size_t size, void *cpu_addr, | 184 | void dma_direct_free_pages(struct device *dev, size_t size, void *cpu_addr, |
@@ -187,15 +186,26 @@ void dma_direct_free_pages(struct device *dev, size_t size, void *cpu_addr, | |||
187 | { | 186 | { |
188 | unsigned int page_order = get_order(size); | 187 | unsigned int page_order = get_order(size); |
189 | 188 | ||
189 | if (attrs & DMA_ATTR_NO_KERNEL_MAPPING) { | ||
190 | /* cpu_addr is a struct page cookie, not a kernel address */ | ||
191 | __dma_direct_free_pages(dev, size, cpu_addr); | ||
192 | return; | ||
193 | } | ||
194 | |||
190 | if (force_dma_unencrypted()) | 195 | if (force_dma_unencrypted()) |
191 | set_memory_encrypted((unsigned long)cpu_addr, 1 << page_order); | 196 | set_memory_encrypted((unsigned long)cpu_addr, 1 << page_order); |
197 | |||
198 | if (IS_ENABLED(CONFIG_ARCH_HAS_UNCACHED_SEGMENT) && | ||
199 | dma_alloc_need_uncached(dev, attrs)) | ||
200 | cpu_addr = cached_kernel_address(cpu_addr); | ||
192 | __dma_direct_free_pages(dev, size, virt_to_page(cpu_addr)); | 201 | __dma_direct_free_pages(dev, size, virt_to_page(cpu_addr)); |
193 | } | 202 | } |
194 | 203 | ||
195 | void *dma_direct_alloc(struct device *dev, size_t size, | 204 | void *dma_direct_alloc(struct device *dev, size_t size, |
196 | dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs) | 205 | dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs) |
197 | { | 206 | { |
198 | if (!dev_is_dma_coherent(dev)) | 207 | if (!IS_ENABLED(CONFIG_ARCH_HAS_UNCACHED_SEGMENT) && |
208 | dma_alloc_need_uncached(dev, attrs)) | ||
199 | return arch_dma_alloc(dev, size, dma_handle, gfp, attrs); | 209 | return arch_dma_alloc(dev, size, dma_handle, gfp, attrs); |
200 | return dma_direct_alloc_pages(dev, size, dma_handle, gfp, attrs); | 210 | return dma_direct_alloc_pages(dev, size, dma_handle, gfp, attrs); |
201 | } | 211 | } |
@@ -203,7 +213,8 @@ void *dma_direct_alloc(struct device *dev, size_t size, | |||
203 | void dma_direct_free(struct device *dev, size_t size, | 213 | void dma_direct_free(struct device *dev, size_t size, |
204 | void *cpu_addr, dma_addr_t dma_addr, unsigned long attrs) | 214 | void *cpu_addr, dma_addr_t dma_addr, unsigned long attrs) |
205 | { | 215 | { |
206 | if (!dev_is_dma_coherent(dev)) | 216 | if (!IS_ENABLED(CONFIG_ARCH_HAS_UNCACHED_SEGMENT) && |
217 | dma_alloc_need_uncached(dev, attrs)) | ||
207 | arch_dma_free(dev, size, cpu_addr, dma_addr, attrs); | 218 | arch_dma_free(dev, size, cpu_addr, dma_addr, attrs); |
208 | else | 219 | else |
209 | dma_direct_free_pages(dev, size, cpu_addr, dma_addr, attrs); | 220 | dma_direct_free_pages(dev, size, cpu_addr, dma_addr, attrs); |
diff --git a/kernel/dma/mapping.c b/kernel/dma/mapping.c index f7afdadb6770..1f628e7ac709 100644 --- a/kernel/dma/mapping.c +++ b/kernel/dma/mapping.c | |||
@@ -317,6 +317,12 @@ void arch_dma_set_mask(struct device *dev, u64 mask); | |||
317 | 317 | ||
318 | int dma_set_mask(struct device *dev, u64 mask) | 318 | int dma_set_mask(struct device *dev, u64 mask) |
319 | { | 319 | { |
320 | /* | ||
321 | * Truncate the mask to the actually supported dma_addr_t width to | ||
322 | * avoid generating unsupportable addresses. | ||
323 | */ | ||
324 | mask = (dma_addr_t)mask; | ||
325 | |||
320 | if (!dev->dma_mask || !dma_supported(dev, mask)) | 326 | if (!dev->dma_mask || !dma_supported(dev, mask)) |
321 | return -EIO; | 327 | return -EIO; |
322 | 328 | ||
@@ -330,6 +336,12 @@ EXPORT_SYMBOL(dma_set_mask); | |||
330 | #ifndef CONFIG_ARCH_HAS_DMA_SET_COHERENT_MASK | 336 | #ifndef CONFIG_ARCH_HAS_DMA_SET_COHERENT_MASK |
331 | int dma_set_coherent_mask(struct device *dev, u64 mask) | 337 | int dma_set_coherent_mask(struct device *dev, u64 mask) |
332 | { | 338 | { |
339 | /* | ||
340 | * Truncate the mask to the actually supported dma_addr_t width to | ||
341 | * avoid generating unsupportable addresses. | ||
342 | */ | ||
343 | mask = (dma_addr_t)mask; | ||
344 | |||
333 | if (!dma_supported(dev, mask)) | 345 | if (!dma_supported(dev, mask)) |
334 | return -EIO; | 346 | return -EIO; |
335 | 347 | ||
diff --git a/kernel/dma/remap.c b/kernel/dma/remap.c index 7a723194ecbe..a594aec07882 100644 --- a/kernel/dma/remap.c +++ b/kernel/dma/remap.c | |||
@@ -158,6 +158,9 @@ out: | |||
158 | 158 | ||
159 | bool dma_in_atomic_pool(void *start, size_t size) | 159 | bool dma_in_atomic_pool(void *start, size_t size) |
160 | { | 160 | { |
161 | if (unlikely(!atomic_pool)) | ||
162 | return false; | ||
163 | |||
161 | return addr_in_gen_pool(atomic_pool, (unsigned long)start, size); | 164 | return addr_in_gen_pool(atomic_pool, (unsigned long)start, size); |
162 | } | 165 | } |
163 | 166 | ||
@@ -199,8 +202,7 @@ void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle, | |||
199 | 202 | ||
200 | size = PAGE_ALIGN(size); | 203 | size = PAGE_ALIGN(size); |
201 | 204 | ||
202 | if (!gfpflags_allow_blocking(flags) && | 205 | if (!gfpflags_allow_blocking(flags)) { |
203 | !(attrs & DMA_ATTR_NO_KERNEL_MAPPING)) { | ||
204 | ret = dma_alloc_from_pool(size, &page, flags); | 206 | ret = dma_alloc_from_pool(size, &page, flags); |
205 | if (!ret) | 207 | if (!ret) |
206 | return NULL; | 208 | return NULL; |
@@ -214,11 +216,6 @@ void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle, | |||
214 | /* remove any dirty cache lines on the kernel alias */ | 216 | /* remove any dirty cache lines on the kernel alias */ |
215 | arch_dma_prep_coherent(page, size); | 217 | arch_dma_prep_coherent(page, size); |
216 | 218 | ||
217 | if (attrs & DMA_ATTR_NO_KERNEL_MAPPING) { | ||
218 | ret = page; /* opaque cookie */ | ||
219 | goto done; | ||
220 | } | ||
221 | |||
222 | /* create a coherent mapping */ | 219 | /* create a coherent mapping */ |
223 | ret = dma_common_contiguous_remap(page, size, VM_USERMAP, | 220 | ret = dma_common_contiguous_remap(page, size, VM_USERMAP, |
224 | arch_dma_mmap_pgprot(dev, PAGE_KERNEL, attrs), | 221 | arch_dma_mmap_pgprot(dev, PAGE_KERNEL, attrs), |
@@ -237,10 +234,7 @@ done: | |||
237 | void arch_dma_free(struct device *dev, size_t size, void *vaddr, | 234 | void arch_dma_free(struct device *dev, size_t size, void *vaddr, |
238 | dma_addr_t dma_handle, unsigned long attrs) | 235 | dma_addr_t dma_handle, unsigned long attrs) |
239 | { | 236 | { |
240 | if (attrs & DMA_ATTR_NO_KERNEL_MAPPING) { | 237 | if (!dma_free_from_pool(vaddr, PAGE_ALIGN(size))) { |
241 | /* vaddr is a struct page cookie, not a kernel address */ | ||
242 | __dma_direct_free_pages(dev, size, vaddr); | ||
243 | } else if (!dma_free_from_pool(vaddr, PAGE_ALIGN(size))) { | ||
244 | phys_addr_t phys = dma_to_phys(dev, dma_handle); | 238 | phys_addr_t phys = dma_to_phys(dev, dma_handle); |
245 | struct page *page = pfn_to_page(__phys_to_pfn(phys)); | 239 | struct page *page = pfn_to_page(__phys_to_pfn(phys)); |
246 | 240 | ||
diff --git a/lib/genalloc.c b/lib/genalloc.c index 5257f74fccf3..9fc31292cfa1 100644 --- a/lib/genalloc.c +++ b/lib/genalloc.c | |||
@@ -327,21 +327,45 @@ EXPORT_SYMBOL(gen_pool_alloc_algo_owner); | |||
327 | * gen_pool_dma_alloc - allocate special memory from the pool for DMA usage | 327 | * gen_pool_dma_alloc - allocate special memory from the pool for DMA usage |
328 | * @pool: pool to allocate from | 328 | * @pool: pool to allocate from |
329 | * @size: number of bytes to allocate from the pool | 329 | * @size: number of bytes to allocate from the pool |
330 | * @dma: dma-view physical address return value. Use NULL if unneeded. | 330 | * @dma: dma-view physical address return value. Use %NULL if unneeded. |
331 | * | 331 | * |
332 | * Allocate the requested number of bytes from the specified pool. | 332 | * Allocate the requested number of bytes from the specified pool. |
333 | * Uses the pool allocation function (with first-fit algorithm by default). | 333 | * Uses the pool allocation function (with first-fit algorithm by default). |
334 | * Can not be used in NMI handler on architectures without | 334 | * Can not be used in NMI handler on architectures without |
335 | * NMI-safe cmpxchg implementation. | 335 | * NMI-safe cmpxchg implementation. |
336 | * | ||
337 | * Return: virtual address of the allocated memory, or %NULL on failure | ||
336 | */ | 338 | */ |
337 | void *gen_pool_dma_alloc(struct gen_pool *pool, size_t size, dma_addr_t *dma) | 339 | void *gen_pool_dma_alloc(struct gen_pool *pool, size_t size, dma_addr_t *dma) |
338 | { | 340 | { |
341 | return gen_pool_dma_alloc_algo(pool, size, dma, pool->algo, pool->data); | ||
342 | } | ||
343 | EXPORT_SYMBOL(gen_pool_dma_alloc); | ||
344 | |||
345 | /** | ||
346 | * gen_pool_dma_alloc_algo - allocate special memory from the pool for DMA | ||
347 | * usage with the given pool algorithm | ||
348 | * @pool: pool to allocate from | ||
349 | * @size: number of bytes to allocate from the pool | ||
350 | * @dma: DMA-view physical address return value. Use %NULL if unneeded. | ||
351 | * @algo: algorithm passed from caller | ||
352 | * @data: data passed to algorithm | ||
353 | * | ||
354 | * Allocate the requested number of bytes from the specified pool. Uses the | ||
355 | * given pool allocation function. Can not be used in NMI handler on | ||
356 | * architectures without NMI-safe cmpxchg implementation. | ||
357 | * | ||
358 | * Return: virtual address of the allocated memory, or %NULL on failure | ||
359 | */ | ||
360 | void *gen_pool_dma_alloc_algo(struct gen_pool *pool, size_t size, | ||
361 | dma_addr_t *dma, genpool_algo_t algo, void *data) | ||
362 | { | ||
339 | unsigned long vaddr; | 363 | unsigned long vaddr; |
340 | 364 | ||
341 | if (!pool) | 365 | if (!pool) |
342 | return NULL; | 366 | return NULL; |
343 | 367 | ||
344 | vaddr = gen_pool_alloc(pool, size); | 368 | vaddr = gen_pool_alloc_algo(pool, size, algo, data); |
345 | if (!vaddr) | 369 | if (!vaddr) |
346 | return NULL; | 370 | return NULL; |
347 | 371 | ||
@@ -350,7 +374,102 @@ void *gen_pool_dma_alloc(struct gen_pool *pool, size_t size, dma_addr_t *dma) | |||
350 | 374 | ||
351 | return (void *)vaddr; | 375 | return (void *)vaddr; |
352 | } | 376 | } |
353 | EXPORT_SYMBOL(gen_pool_dma_alloc); | 377 | EXPORT_SYMBOL(gen_pool_dma_alloc_algo); |
378 | |||
379 | /** | ||
380 | * gen_pool_dma_alloc_align - allocate special memory from the pool for DMA | ||
381 | * usage with the given alignment | ||
382 | * @pool: pool to allocate from | ||
383 | * @size: number of bytes to allocate from the pool | ||
384 | * @dma: DMA-view physical address return value. Use %NULL if unneeded. | ||
385 | * @align: alignment in bytes for starting address | ||
386 | * | ||
387 | * Allocate the requested number bytes from the specified pool, with the given | ||
388 | * alignment restriction. Can not be used in NMI handler on architectures | ||
389 | * without NMI-safe cmpxchg implementation. | ||
390 | * | ||
391 | * Return: virtual address of the allocated memory, or %NULL on failure | ||
392 | */ | ||
393 | void *gen_pool_dma_alloc_align(struct gen_pool *pool, size_t size, | ||
394 | dma_addr_t *dma, int align) | ||
395 | { | ||
396 | struct genpool_data_align data = { .align = align }; | ||
397 | |||
398 | return gen_pool_dma_alloc_algo(pool, size, dma, | ||
399 | gen_pool_first_fit_align, &data); | ||
400 | } | ||
401 | EXPORT_SYMBOL(gen_pool_dma_alloc_align); | ||
402 | |||
403 | /** | ||
404 | * gen_pool_dma_zalloc - allocate special zeroed memory from the pool for | ||
405 | * DMA usage | ||
406 | * @pool: pool to allocate from | ||
407 | * @size: number of bytes to allocate from the pool | ||
408 | * @dma: dma-view physical address return value. Use %NULL if unneeded. | ||
409 | * | ||
410 | * Allocate the requested number of zeroed bytes from the specified pool. | ||
411 | * Uses the pool allocation function (with first-fit algorithm by default). | ||
412 | * Can not be used in NMI handler on architectures without | ||
413 | * NMI-safe cmpxchg implementation. | ||
414 | * | ||
415 | * Return: virtual address of the allocated zeroed memory, or %NULL on failure | ||
416 | */ | ||
417 | void *gen_pool_dma_zalloc(struct gen_pool *pool, size_t size, dma_addr_t *dma) | ||
418 | { | ||
419 | return gen_pool_dma_zalloc_algo(pool, size, dma, pool->algo, pool->data); | ||
420 | } | ||
421 | EXPORT_SYMBOL(gen_pool_dma_zalloc); | ||
422 | |||
423 | /** | ||
424 | * gen_pool_dma_zalloc_algo - allocate special zeroed memory from the pool for | ||
425 | * DMA usage with the given pool algorithm | ||
426 | * @pool: pool to allocate from | ||
427 | * @size: number of bytes to allocate from the pool | ||
428 | * @dma: DMA-view physical address return value. Use %NULL if unneeded. | ||
429 | * @algo: algorithm passed from caller | ||
430 | * @data: data passed to algorithm | ||
431 | * | ||
432 | * Allocate the requested number of zeroed bytes from the specified pool. Uses | ||
433 | * the given pool allocation function. Can not be used in NMI handler on | ||
434 | * architectures without NMI-safe cmpxchg implementation. | ||
435 | * | ||
436 | * Return: virtual address of the allocated zeroed memory, or %NULL on failure | ||
437 | */ | ||
438 | void *gen_pool_dma_zalloc_algo(struct gen_pool *pool, size_t size, | ||
439 | dma_addr_t *dma, genpool_algo_t algo, void *data) | ||
440 | { | ||
441 | void *vaddr = gen_pool_dma_alloc_algo(pool, size, dma, algo, data); | ||
442 | |||
443 | if (vaddr) | ||
444 | memset(vaddr, 0, size); | ||
445 | |||
446 | return vaddr; | ||
447 | } | ||
448 | EXPORT_SYMBOL(gen_pool_dma_zalloc_algo); | ||
449 | |||
450 | /** | ||
451 | * gen_pool_dma_zalloc_align - allocate special zeroed memory from the pool for | ||
452 | * DMA usage with the given alignment | ||
453 | * @pool: pool to allocate from | ||
454 | * @size: number of bytes to allocate from the pool | ||
455 | * @dma: DMA-view physical address return value. Use %NULL if unneeded. | ||
456 | * @align: alignment in bytes for starting address | ||
457 | * | ||
458 | * Allocate the requested number of zeroed bytes from the specified pool, | ||
459 | * with the given alignment restriction. Can not be used in NMI handler on | ||
460 | * architectures without NMI-safe cmpxchg implementation. | ||
461 | * | ||
462 | * Return: virtual address of the allocated zeroed memory, or %NULL on failure | ||
463 | */ | ||
464 | void *gen_pool_dma_zalloc_align(struct gen_pool *pool, size_t size, | ||
465 | dma_addr_t *dma, int align) | ||
466 | { | ||
467 | struct genpool_data_align data = { .align = align }; | ||
468 | |||
469 | return gen_pool_dma_zalloc_algo(pool, size, dma, | ||
470 | gen_pool_first_fit_align, &data); | ||
471 | } | ||
472 | EXPORT_SYMBOL(gen_pool_dma_zalloc_align); | ||
354 | 473 | ||
355 | /** | 474 | /** |
356 | * gen_pool_free - free allocated special memory back to the pool | 475 | * gen_pool_free - free allocated special memory back to the pool |