diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c index f309ad38fa94..3edcbd008507 100644 --- a/arch/arm64/mm/dma-mapping.c +++ b/arch/arm64/mm/dma-mapping.c @@ -45,9 +45,7 @@ static int swiotlb __ro_after_init; static pgprot_t __get_dma_pgprot(unsigned long attrs, pgprot_t prot, bool coherent) { - if (attrs & DMA_ATTR_STRONGLY_ORDERED) - return pgprot_noncached(prot); - else if (!coherent || (attrs & DMA_ATTR_WRITE_COMBINE)) + if (!coherent || (attrs & DMA_ATTR_WRITE_COMBINE)) return pgprot_writecombine(prot); return prot; } @@ -66,7 +64,6 @@ static bool is_dma_coherent(struct device *dev, unsigned long attrs) } static struct gen_pool *atomic_pool __ro_after_init; -#define NO_KERNEL_MAPPING_DUMMY 0x2222 #define DEFAULT_DMA_COHERENT_POOL_SIZE SZ_256K static size_t atomic_pool_size __initdata = DEFAULT_DMA_COHERENT_POOL_SIZE; @@ -114,43 +111,6 @@ static int __free_from_pool(void *start, size_t size) return 1; } -static int __dma_update_pte(pte_t *pte, pgtable_t token, unsigned long addr, - void *data) -{ - struct page *page = virt_to_page(addr); - pgprot_t prot = *(pgprot_t *)data; - - set_pte(pte, mk_pte(page, prot)); - return 0; -} - -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 no_kernel_map) -{ - unsigned long start = (unsigned long) page_address(page); - unsigned long end = start + size; - int (*func)(pte_t *pte, pgtable_t token, unsigned long addr, - void *data); - - if (no_kernel_map) - func = __dma_clear_pte; - else - func = __dma_update_pte; - - apply_to_page_range(&init_mm, start, size, func, &prot); - /* ensure prot is applied before returning */ - mb(); - flush_tlb_kernel_range(start, end); -} - - static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flags, unsigned long attrs) @@ -181,31 +141,19 @@ static void *__dma_alloc(struct device *dev, size_t size, if (coherent) return ptr; + /* remove any dirty cache lines on the kernel alias */ __dma_flush_area(ptr, size); - if (attrs & DMA_ATTR_NO_KERNEL_MAPPING) { - coherent_ptr = (void *)NO_KERNEL_MAPPING_DUMMY; - __dma_remap(virt_to_page(ptr), size, __pgprot(0), true); - } else { - if ((attrs & DMA_ATTR_STRONGLY_ORDERED)) - __dma_remap(virt_to_page(ptr), size, __pgprot(0), true); + /* create a coherent mapping */ + page = virt_to_page(ptr); + coherent_ptr = dma_common_contiguous_remap(page, size, VM_USERMAP, + prot, __builtin_return_address(0)); + if (!coherent_ptr) + goto no_map; - /* create a coherent mapping */ - page = virt_to_page(ptr); - coherent_ptr = dma_common_contiguous_remap( - page, size, VM_USERMAP, prot, - __builtin_return_address(0)); - if (!coherent_ptr) - goto no_map; - } return coherent_ptr; no_map: - if ((attrs & DMA_ATTR_NO_KERNEL_MAPPING) || - (attrs & DMA_ATTR_STRONGLY_ORDERED)) - __dma_remap(phys_to_page(dma_to_phys(dev, *dma_handle)), - size, PAGE_KERNEL, false); - swiotlb_free(dev, size, ptr, *dma_handle, attrs); no_mem: return NULL; @@ -219,17 +167,11 @@ static void __dma_free(struct device *dev, size_t size, size = PAGE_ALIGN(size); - if (!is_dma_coherent(dev, attrs)) { + if (!is_device_dma_coherent(dev)) { if (__free_from_pool(vaddr, size)) return; - if (!(attrs & DMA_ATTR_NO_KERNEL_MAPPING)) - vunmap(vaddr); + vunmap(vaddr); } - if ((attrs & DMA_ATTR_NO_KERNEL_MAPPING) || - (attrs & DMA_ATTR_STRONGLY_ORDERED)) - __dma_remap(phys_to_page(dma_to_phys(dev, dma_handle)), - size, PAGE_KERNEL, false); - swiotlb_free(dev, size, swiotlb_addr, dma_handle, attrs); }