diff options
author | Laura Abbott <lauraa@codeaurora.org> | 2013-12-12 19:28:33 +0000 |
---|---|---|
committer | Catalin Marinas <catalin.marinas@arm.com> | 2013-12-19 17:44:09 +0000 |
commit | 6ac2104debc235b745265b64d610237a6833fd53 (patch) | |
tree | 220521d71f3799ec7d1510a00910ffb7efad1722 /arch/arm64/mm/dma-mapping.c | |
parent | c666e8d5cae745b1515898f8b7a033c468a899d0 (diff) | |
download | lwn-6ac2104debc235b745265b64d610237a6833fd53.tar.gz lwn-6ac2104debc235b745265b64d610237a6833fd53.zip |
arm64: Enable CMA
arm64 bit targets need the features CMA provides. Add the appropriate
hooks, header files, and Kconfig to allow this to happen.
Cc: Will Deacon <will.deacon@arm.com>
Cc: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Laura Abbott <lauraa@codeaurora.org>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Diffstat (limited to 'arch/arm64/mm/dma-mapping.c')
-rw-r--r-- | arch/arm64/mm/dma-mapping.c | 25 |
1 files changed, 23 insertions, 2 deletions
diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c index 83e643131e10..45b5ab54c9ee 100644 --- a/arch/arm64/mm/dma-mapping.c +++ b/arch/arm64/mm/dma-mapping.c @@ -21,6 +21,7 @@ #include <linux/export.h> #include <linux/slab.h> #include <linux/dma-mapping.h> +#include <linux/dma-contiguous.h> #include <linux/vmalloc.h> #include <linux/swiotlb.h> @@ -41,7 +42,19 @@ static void *arm64_swiotlb_alloc_coherent(struct device *dev, size_t size, if (IS_ENABLED(CONFIG_ZONE_DMA32) && dev->coherent_dma_mask <= DMA_BIT_MASK(32)) flags |= GFP_DMA32; - return swiotlb_alloc_coherent(dev, size, dma_handle, flags); + if (IS_ENABLED(CONFIG_DMA_CMA)) { + struct page *page; + + page = dma_alloc_from_contiguous(dev, size >> PAGE_SHIFT, + get_order(size)); + if (!page) + return NULL; + + *dma_handle = phys_to_dma(dev, page_to_phys(page)); + return page_address(page); + } else { + return swiotlb_alloc_coherent(dev, size, dma_handle, flags); + } } static void arm64_swiotlb_free_coherent(struct device *dev, size_t size, @@ -53,7 +66,15 @@ static void arm64_swiotlb_free_coherent(struct device *dev, size_t size, return; } - swiotlb_free_coherent(dev, size, vaddr, dma_handle); + if (IS_ENABLED(CONFIG_DMA_CMA)) { + phys_addr_t paddr = dma_to_phys(dev, dma_handle); + + dma_release_from_contiguous(dev, + phys_to_page(paddr), + size >> PAGE_SHIFT); + } else { + swiotlb_free_coherent(dev, size, vaddr, dma_handle); + } } static struct dma_map_ops arm64_swiotlb_dma_ops = { |