Loading arch/arm/mm/dma-mapping.c +45 −23 Original line number Diff line number Diff line Loading @@ -375,10 +375,10 @@ __dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot, prot, caller); } static void __dma_free_remap(void *cpu_addr, size_t size) static void __dma_free_remap(void *cpu_addr, size_t size, bool no_warn) { dma_common_free_remap(cpu_addr, size, VM_ARM_DMA_CONSISTENT | VM_USERMAP, false); VM_ARM_DMA_CONSISTENT | VM_USERMAP, no_warn); } #define DEFAULT_DMA_COHERENT_POOL_SIZE SZ_256K Loading Loading @@ -527,21 +527,39 @@ static int __dma_update_pte(pte_t *pte, pgtable_t token, unsigned long addr, return 0; } static void __dma_remap(struct page *page, size_t size, pgprot_t prot) static int __dma_clear_pte(pte_t *pte, pgtable_t token, unsigned long addr, void *data) { pte_clear(&init_mm, addr, pte); return 0; } static void __dma_remap(struct page *page, size_t size, pgprot_t prot, bool want_vaddr) { unsigned long start = (unsigned long) page_address(page); unsigned end = start + size; int (*func)(pte_t *pte, pgtable_t token, unsigned long addr, void *data); apply_to_page_range(&init_mm, start, size, __dma_update_pte, &prot); if (!want_vaddr) func = __dma_clear_pte; else func = __dma_update_pte; apply_to_page_range(&init_mm, start, size, func, &prot); mb(); /*Ensure pte's are updated */ flush_tlb_kernel_range(start, end); } #define NO_KERNEL_MAPPING_DUMMY 0x2222 static void *__alloc_remap_buffer(struct device *dev, size_t size, gfp_t gfp, pgprot_t prot, struct page **ret_page, const void *caller, bool want_vaddr) { struct page *page; void *ptr = NULL; void *ptr = (void *)NO_KERNEL_MAPPING_DUMMY; /* * __alloc_remap_buffer is only called when the device is * non-coherent Loading Loading @@ -620,21 +638,27 @@ static void *__alloc_from_contiguous(struct device *dev, size_t size, if (!(skip_cpu_sync && skip_zeroing)) __dma_clear_buffer(page, size, skip_zeroing, coherent_flag); if (!want_vaddr) goto out; if (PageHighMem(page)) { ptr = __dma_alloc_remap(page, size, GFP_KERNEL, prot, caller); if (!want_vaddr) { /* * Something non-NULL needs to be returned here. Give * back a dummy address that is unmapped to catch * clients trying to use the address incorrectly */ ptr = (void *)NO_KERNEL_MAPPING_DUMMY; } else { ptr = __dma_alloc_remap(page, size, GFP_KERNEL, prot, caller); if (!ptr) { dma_release_from_contiguous(dev, page, count); return NULL; } } } else { __dma_remap(page, size, prot); __dma_remap(page, size, prot, want_vaddr); ptr = page_address(page); } out: *ret_page = page; return ptr; } Loading @@ -642,12 +666,10 @@ static void *__alloc_from_contiguous(struct device *dev, size_t size, static void __free_from_contiguous(struct device *dev, struct page *page, void *cpu_addr, size_t size, bool want_vaddr) { if (want_vaddr) { if (PageHighMem(page)) __dma_free_remap(cpu_addr, size); __dma_free_remap(cpu_addr, size, true); else __dma_remap(page, size, PAGE_KERNEL); } __dma_remap(page, size, PAGE_KERNEL, true); dma_release_from_contiguous(dev, page, size >> PAGE_SHIFT); } Loading @@ -672,7 +694,7 @@ static inline pgprot_t __get_dma_pgprot(unsigned long attrs, pgprot_t prot) wv, scs, sz, coherent_flag) NULL #define __free_from_pool(cpu_addr, size) do { } while (0) #define __free_from_contiguous(dev, page, cpu_addr, size, wv) do { } while (0) #define __dma_free_remap(cpu_addr, size) do { } while (0) #define __dma_free_remap(cpu_addr, size, w) do { } while (0) #endif /* CONFIG_MMU */ Loading Loading @@ -753,7 +775,7 @@ static void *remap_allocator_alloc(struct arm_dma_alloc_args *args, static void remap_allocator_free(struct arm_dma_free_args *args) { if (args->want_vaddr) __dma_free_remap(args->cpu_addr, args->size); __dma_free_remap(args->cpu_addr, args->size, false); __dma_free_buffer(args->page, args->size); } Loading Loading @@ -842,7 +864,7 @@ static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, kfree(buf); } return args.want_vaddr ? addr : page; return addr; } /* Loading Loading
arch/arm/mm/dma-mapping.c +45 −23 Original line number Diff line number Diff line Loading @@ -375,10 +375,10 @@ __dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot, prot, caller); } static void __dma_free_remap(void *cpu_addr, size_t size) static void __dma_free_remap(void *cpu_addr, size_t size, bool no_warn) { dma_common_free_remap(cpu_addr, size, VM_ARM_DMA_CONSISTENT | VM_USERMAP, false); VM_ARM_DMA_CONSISTENT | VM_USERMAP, no_warn); } #define DEFAULT_DMA_COHERENT_POOL_SIZE SZ_256K Loading Loading @@ -527,21 +527,39 @@ static int __dma_update_pte(pte_t *pte, pgtable_t token, unsigned long addr, return 0; } static void __dma_remap(struct page *page, size_t size, pgprot_t prot) static int __dma_clear_pte(pte_t *pte, pgtable_t token, unsigned long addr, void *data) { pte_clear(&init_mm, addr, pte); return 0; } static void __dma_remap(struct page *page, size_t size, pgprot_t prot, bool want_vaddr) { unsigned long start = (unsigned long) page_address(page); unsigned end = start + size; int (*func)(pte_t *pte, pgtable_t token, unsigned long addr, void *data); apply_to_page_range(&init_mm, start, size, __dma_update_pte, &prot); if (!want_vaddr) func = __dma_clear_pte; else func = __dma_update_pte; apply_to_page_range(&init_mm, start, size, func, &prot); mb(); /*Ensure pte's are updated */ flush_tlb_kernel_range(start, end); } #define NO_KERNEL_MAPPING_DUMMY 0x2222 static void *__alloc_remap_buffer(struct device *dev, size_t size, gfp_t gfp, pgprot_t prot, struct page **ret_page, const void *caller, bool want_vaddr) { struct page *page; void *ptr = NULL; void *ptr = (void *)NO_KERNEL_MAPPING_DUMMY; /* * __alloc_remap_buffer is only called when the device is * non-coherent Loading Loading @@ -620,21 +638,27 @@ static void *__alloc_from_contiguous(struct device *dev, size_t size, if (!(skip_cpu_sync && skip_zeroing)) __dma_clear_buffer(page, size, skip_zeroing, coherent_flag); if (!want_vaddr) goto out; if (PageHighMem(page)) { ptr = __dma_alloc_remap(page, size, GFP_KERNEL, prot, caller); if (!want_vaddr) { /* * Something non-NULL needs to be returned here. Give * back a dummy address that is unmapped to catch * clients trying to use the address incorrectly */ ptr = (void *)NO_KERNEL_MAPPING_DUMMY; } else { ptr = __dma_alloc_remap(page, size, GFP_KERNEL, prot, caller); if (!ptr) { dma_release_from_contiguous(dev, page, count); return NULL; } } } else { __dma_remap(page, size, prot); __dma_remap(page, size, prot, want_vaddr); ptr = page_address(page); } out: *ret_page = page; return ptr; } Loading @@ -642,12 +666,10 @@ static void *__alloc_from_contiguous(struct device *dev, size_t size, static void __free_from_contiguous(struct device *dev, struct page *page, void *cpu_addr, size_t size, bool want_vaddr) { if (want_vaddr) { if (PageHighMem(page)) __dma_free_remap(cpu_addr, size); __dma_free_remap(cpu_addr, size, true); else __dma_remap(page, size, PAGE_KERNEL); } __dma_remap(page, size, PAGE_KERNEL, true); dma_release_from_contiguous(dev, page, size >> PAGE_SHIFT); } Loading @@ -672,7 +694,7 @@ static inline pgprot_t __get_dma_pgprot(unsigned long attrs, pgprot_t prot) wv, scs, sz, coherent_flag) NULL #define __free_from_pool(cpu_addr, size) do { } while (0) #define __free_from_contiguous(dev, page, cpu_addr, size, wv) do { } while (0) #define __dma_free_remap(cpu_addr, size) do { } while (0) #define __dma_free_remap(cpu_addr, size, w) do { } while (0) #endif /* CONFIG_MMU */ Loading Loading @@ -753,7 +775,7 @@ static void *remap_allocator_alloc(struct arm_dma_alloc_args *args, static void remap_allocator_free(struct arm_dma_free_args *args) { if (args->want_vaddr) __dma_free_remap(args->cpu_addr, args->size); __dma_free_remap(args->cpu_addr, args->size, false); __dma_free_buffer(args->page, args->size); } Loading Loading @@ -842,7 +864,7 @@ static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, kfree(buf); } return args.want_vaddr ? addr : page; return addr; } /* Loading