0001
0002
0003
0004
0005 #include <linux/dma-map-ops.h>
0006 #include <linux/slab.h>
0007 #include <linux/vmalloc.h>
0008
0009 struct page **dma_common_find_pages(void *cpu_addr)
0010 {
0011 struct vm_struct *area = find_vm_area(cpu_addr);
0012
0013 if (!area || area->flags != VM_DMA_COHERENT)
0014 return NULL;
0015 return area->pages;
0016 }
0017
0018
0019
0020
0021
0022 void *dma_common_pages_remap(struct page **pages, size_t size,
0023 pgprot_t prot, const void *caller)
0024 {
0025 void *vaddr;
0026
0027 vaddr = vmap(pages, PAGE_ALIGN(size) >> PAGE_SHIFT,
0028 VM_DMA_COHERENT, prot);
0029 if (vaddr)
0030 find_vm_area(vaddr)->pages = pages;
0031 return vaddr;
0032 }
0033
0034
0035
0036
0037
0038 void *dma_common_contiguous_remap(struct page *page, size_t size,
0039 pgprot_t prot, const void *caller)
0040 {
0041 int count = PAGE_ALIGN(size) >> PAGE_SHIFT;
0042 struct page **pages;
0043 void *vaddr;
0044 int i;
0045
0046 pages = kmalloc_array(count, sizeof(struct page *), GFP_KERNEL);
0047 if (!pages)
0048 return NULL;
0049 for (i = 0; i < count; i++)
0050 pages[i] = nth_page(page, i);
0051 vaddr = vmap(pages, count, VM_DMA_COHERENT, prot);
0052 kfree(pages);
0053
0054 return vaddr;
0055 }
0056
0057
0058
0059
0060 void dma_common_free_remap(void *cpu_addr, size_t size)
0061 {
0062 struct vm_struct *area = find_vm_area(cpu_addr);
0063
0064 if (!area || area->flags != VM_DMA_COHERENT) {
0065 WARN(1, "trying to free invalid coherent area: %p\n", cpu_addr);
0066 return;
0067 }
0068
0069 vunmap(cpu_addr);
0070 }