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
))
15 WARN(area
->flags
!= VM_DMA_COHERENT
,
16 "unexpected flags in area: %p\n", cpu_addr
);
21 * Remaps an array of PAGE_SIZE pages into another vm_area.
22 * Cannot be used in non-sleeping contexts
24 void *dma_common_pages_remap(struct page
**pages
, size_t size
,
25 pgprot_t prot
, const void *caller
)
29 vaddr
= vmap(pages
, PAGE_ALIGN(size
) >> PAGE_SHIFT
,
30 VM_DMA_COHERENT
, prot
);
32 find_vm_area(vaddr
)->pages
= pages
;
37 * Remaps an allocated contiguous region into another vm_area.
38 * Cannot be used in non-sleeping contexts
40 void *dma_common_contiguous_remap(struct page
*page
, size_t size
,
41 pgprot_t prot
, const void *caller
)
43 int count
= PAGE_ALIGN(size
) >> PAGE_SHIFT
;
48 pages
= kvmalloc_array(count
, sizeof(struct page
*), GFP_KERNEL
);
51 for (i
= 0; i
< count
; i
++)
52 pages
[i
] = nth_page(page
, i
);
53 vaddr
= vmap(pages
, count
, VM_DMA_COHERENT
, prot
);
60 * Unmaps a range previously mapped by dma_common_*_remap
62 void dma_common_free_remap(void *cpu_addr
, size_t size
)
64 struct vm_struct
*area
= find_vm_area(cpu_addr
);
66 if (!area
|| !(area
->flags
& VM_DMA_COHERENT
)) {
67 WARN(1, "trying to free invalid coherent area: %p\n", cpu_addr
);