1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2014 The Linux Foundation
5 #include <linux/dma-map-ops.h>
6 #include <linux/slab.h>
7 #include <linux/vmalloc.h>
9 struct page
**dma_common_find_pages(void *cpu_addr
)
11 struct vm_struct
*area
= find_vm_area(cpu_addr
);
13 if (!area
|| area
->flags
!= VM_DMA_COHERENT
)
19 * Remaps an array of PAGE_SIZE pages into another vm_area.
20 * Cannot be used in non-sleeping contexts
22 void *dma_common_pages_remap(struct page
**pages
, size_t size
,
23 pgprot_t prot
, const void *caller
)
27 vaddr
= vmap(pages
, PAGE_ALIGN(size
) >> PAGE_SHIFT
,
28 VM_DMA_COHERENT
, prot
);
30 find_vm_area(vaddr
)->pages
= pages
;
35 * Remaps an allocated contiguous region into another vm_area.
36 * Cannot be used in non-sleeping contexts
38 void *dma_common_contiguous_remap(struct page
*page
, size_t size
,
39 pgprot_t prot
, const void *caller
)
41 int count
= PAGE_ALIGN(size
) >> PAGE_SHIFT
;
46 pages
= kmalloc_array(count
, sizeof(struct page
*), GFP_KERNEL
);
49 for (i
= 0; i
< count
; i
++)
50 pages
[i
] = nth_page(page
, i
);
51 vaddr
= vmap(pages
, count
, VM_DMA_COHERENT
, prot
);
58 * Unmaps a range previously mapped by dma_common_*_remap
60 void dma_common_free_remap(void *cpu_addr
, size_t size
)
62 struct vm_struct
*area
= find_vm_area(cpu_addr
);
64 if (!area
|| area
->flags
!= VM_DMA_COHERENT
) {
65 WARN(1, "trying to free invalid coherent area: %p\n", cpu_addr
);
69 unmap_kernel_range((unsigned long)cpu_addr
, PAGE_ALIGN(size
));