dma-mapping: move the remap helpers to a separate file
authorChristoph Hellwig <hch@lst.de>
Fri, 24 Aug 2018 08:31:08 +0000 (10:31 +0200)
committerChristoph Hellwig <hch@lst.de>
Sat, 1 Dec 2018 16:58:34 +0000 (17:58 +0100)
The dma remap code only makes sense for not cache coherent architectures
(or possibly the corner case of highmem CMA allocations) and currently
is only used by arm, arm64, csky and xtensa.  Split it out into a
separate file with a separate Kconfig symbol, which gets the right
copyright notice given that this code was written by Laura Abbott
working for Code Aurora at that point.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Acked-by: Laura Abbott <labbott@redhat.com>
Reviewed-by: Robin Murphy <robin.murphy@arm.com>
arch/arm/Kconfig
arch/arm64/Kconfig
arch/csky/Kconfig
arch/xtensa/Kconfig
kernel/dma/Kconfig
kernel/dma/Makefile
kernel/dma/mapping.c
kernel/dma/remap.c [new file with mode: 0644]

index 91be74d8df658ccd5a4701fe7438053115dceeb9..3b2852df6eb32b52bb2c2bf2cb9a7ffd68320454 100644 (file)
@@ -30,6 +30,7 @@ config ARM
        select CPU_PM if (SUSPEND || CPU_IDLE)
        select DCACHE_WORD_ACCESS if HAVE_EFFICIENT_UNALIGNED_ACCESS
        select DMA_DIRECT_OPS if !MMU
+       select DMA_REMAP if MMU
        select EDAC_SUPPORT
        select EDAC_ATOMIC_SCRUB
        select GENERIC_ALLOCATOR
index 787d7850e0643d80197e29bcfbfedf6d40ab46eb..5d065acb6d1060094b7105c75e978aff30816e03 100644 (file)
@@ -82,6 +82,7 @@ config ARM64
        select CRC32
        select DCACHE_WORD_ACCESS
        select DMA_DIRECT_OPS
+       select DMA_REMAP
        select EDAC_SUPPORT
        select FRAME_POINTER
        select GENERIC_ALLOCATOR
index cb64f8dacd08ee6fa56f622ddb89299f1305f607..8a30e006a845e494cc012ff456a4c733d2e570a8 100644 (file)
@@ -9,6 +9,7 @@ config CSKY
        select CLKSRC_OF
        select DMA_DIRECT_OPS
        select DMA_NONCOHERENT_OPS
+       select DMA_REMAP
        select IRQ_DOMAIN
        select HANDLE_DOMAIN_IRQ
        select DW_APB_TIMER_OF
index d29b7365da8d9facd71a887a071b34bbb68ec5fc..239bfb16c58b67c41e6a2b949665d0f347e210ae 100644 (file)
@@ -11,6 +11,7 @@ config XTENSA
        select CLONE_BACKWARDS
        select COMMON_CLK
        select DMA_DIRECT_OPS
+       select DMA_REMAP if MMU
        select GENERIC_ATOMIC64
        select GENERIC_CLOCKEVENTS
        select GENERIC_IRQ_SHOW
index 645c7a2ecde8bf26801789cdb7418b6b448748f7..c92e08173ed8c276591d1199fa59234a0f50a8bf 100644 (file)
@@ -51,3 +51,7 @@ config SWIOTLB
        bool
        select DMA_DIRECT_OPS
        select NEED_DMA_MAP_STATE
+
+config DMA_REMAP
+       depends on MMU
+       bool
index 7d581e4eea4a2fd6c6602dc8bbac9c58cbc9653d..f4feeceb802005d1bb25c8c1e2b280555fe459a5 100644 (file)
@@ -7,4 +7,4 @@ obj-$(CONFIG_DMA_DIRECT_OPS)            += direct.o
 obj-$(CONFIG_DMA_VIRT_OPS)             += virt.o
 obj-$(CONFIG_DMA_API_DEBUG)            += debug.o
 obj-$(CONFIG_SWIOTLB)                  += swiotlb.o
-
+obj-$(CONFIG_DMA_REMAP)                        += remap.o
index 58dec7a92b7b51d3c1ec1b14236e120baf1277aa..dfbc3deb95cdce635e892b2079f13845829a1b1b 100644 (file)
@@ -262,87 +262,3 @@ int dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
 #endif /* !CONFIG_ARCH_NO_COHERENT_DMA_MMAP */
 }
 EXPORT_SYMBOL(dma_common_mmap);
-
-#ifdef CONFIG_MMU
-static struct vm_struct *__dma_common_pages_remap(struct page **pages,
-                       size_t size, unsigned long vm_flags, pgprot_t prot,
-                       const void *caller)
-{
-       struct vm_struct *area;
-
-       area = get_vm_area_caller(size, vm_flags, caller);
-       if (!area)
-               return NULL;
-
-       if (map_vm_area(area, prot, pages)) {
-               vunmap(area->addr);
-               return NULL;
-       }
-
-       return area;
-}
-
-/*
- * remaps an array of PAGE_SIZE pages into another vm_area
- * Cannot be used in non-sleeping contexts
- */
-void *dma_common_pages_remap(struct page **pages, size_t size,
-                       unsigned long vm_flags, pgprot_t prot,
-                       const void *caller)
-{
-       struct vm_struct *area;
-
-       area = __dma_common_pages_remap(pages, size, vm_flags, prot, caller);
-       if (!area)
-               return NULL;
-
-       area->pages = pages;
-
-       return area->addr;
-}
-
-/*
- * remaps an allocated contiguous region into another vm_area.
- * Cannot be used in non-sleeping contexts
- */
-
-void *dma_common_contiguous_remap(struct page *page, size_t size,
-                       unsigned long vm_flags,
-                       pgprot_t prot, const void *caller)
-{
-       int i;
-       struct page **pages;
-       struct vm_struct *area;
-
-       pages = kmalloc(sizeof(struct page *) << get_order(size), GFP_KERNEL);
-       if (!pages)
-               return NULL;
-
-       for (i = 0; i < (size >> PAGE_SHIFT); i++)
-               pages[i] = nth_page(page, i);
-
-       area = __dma_common_pages_remap(pages, size, vm_flags, prot, caller);
-
-       kfree(pages);
-
-       if (!area)
-               return NULL;
-       return area->addr;
-}
-
-/*
- * unmaps a range previously mapped by dma_common_*_remap
- */
-void dma_common_free_remap(void *cpu_addr, size_t size, unsigned long vm_flags)
-{
-       struct vm_struct *area = find_vm_area(cpu_addr);
-
-       if (!area || (area->flags & vm_flags) != vm_flags) {
-               WARN(1, "trying to free invalid coherent area: %p\n", cpu_addr);
-               return;
-       }
-
-       unmap_kernel_range((unsigned long)cpu_addr, PAGE_ALIGN(size));
-       vunmap(cpu_addr);
-}
-#endif
diff --git a/kernel/dma/remap.c b/kernel/dma/remap.c
new file mode 100644 (file)
index 0000000..a15c393
--- /dev/null
@@ -0,0 +1,88 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2014 The Linux Foundation
+ */
+#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+
+static struct vm_struct *__dma_common_pages_remap(struct page **pages,
+                       size_t size, unsigned long vm_flags, pgprot_t prot,
+                       const void *caller)
+{
+       struct vm_struct *area;
+
+       area = get_vm_area_caller(size, vm_flags, caller);
+       if (!area)
+               return NULL;
+
+       if (map_vm_area(area, prot, pages)) {
+               vunmap(area->addr);
+               return NULL;
+       }
+
+       return area;
+}
+
+/*
+ * Remaps an array of PAGE_SIZE pages into another vm_area.
+ * Cannot be used in non-sleeping contexts
+ */
+void *dma_common_pages_remap(struct page **pages, size_t size,
+                       unsigned long vm_flags, pgprot_t prot,
+                       const void *caller)
+{
+       struct vm_struct *area;
+
+       area = __dma_common_pages_remap(pages, size, vm_flags, prot, caller);
+       if (!area)
+               return NULL;
+
+       area->pages = pages;
+
+       return area->addr;
+}
+
+/*
+ * Remaps an allocated contiguous region into another vm_area.
+ * Cannot be used in non-sleeping contexts
+ */
+void *dma_common_contiguous_remap(struct page *page, size_t size,
+                       unsigned long vm_flags,
+                       pgprot_t prot, const void *caller)
+{
+       int i;
+       struct page **pages;
+       struct vm_struct *area;
+
+       pages = kmalloc(sizeof(struct page *) << get_order(size), GFP_KERNEL);
+       if (!pages)
+               return NULL;
+
+       for (i = 0; i < (size >> PAGE_SHIFT); i++)
+               pages[i] = nth_page(page, i);
+
+       area = __dma_common_pages_remap(pages, size, vm_flags, prot, caller);
+
+       kfree(pages);
+
+       if (!area)
+               return NULL;
+       return area->addr;
+}
+
+/*
+ * Unmaps a range previously mapped by dma_common_*_remap
+ */
+void dma_common_free_remap(void *cpu_addr, size_t size, unsigned long vm_flags)
+{
+       struct vm_struct *area = find_vm_area(cpu_addr);
+
+       if (!area || (area->flags & vm_flags) != vm_flags) {
+               WARN(1, "trying to free invalid coherent area: %p\n", cpu_addr);
+               return;
+       }
+
+       unmap_kernel_range((unsigned long)cpu_addr, PAGE_ALIGN(size));
+       vunmap(cpu_addr);
+}