aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base
diff options
context:
space:
mode:
authorMarek Szyprowski <m.szyprowski@samsung.com>2012-06-14 07:03:04 -0400
committerMarek Szyprowski <m.szyprowski@samsung.com>2012-07-30 06:25:46 -0400
commit64ccc9c033c6089b2d426dad3c56477ab066c999 (patch)
treeffaec86ca326dfc83b78ce4005bf46c3ad98ceb9 /drivers/base
parent9fa8af91f0679f2abbebe1382b937264f3a8b981 (diff)
common: dma-mapping: add support for generic dma_mmap_* calls
Commit 9adc5374 ('common: dma-mapping: introduce mmap method') added a generic method for implementing mmap user call to dma_map_ops structure. This patch converts ARM and PowerPC architectures (the only providers of dma_mmap_coherent/dma_mmap_writecombine calls) to use this generic dma_map_ops based call and adds a generic cross architecture definition for dma_mmap_attrs, dma_mmap_coherent, dma_mmap_writecombine functions. The generic mmap virt_to_page-based fallback implementation is provided for architectures which don't provide their own implementation for mmap method. Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> Reviewed-by: Kyungmin Park <kyungmin.park@samsung.com>
Diffstat (limited to 'drivers/base')
-rw-r--r--drivers/base/dma-mapping.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c
index 6f3676f1559f..db5db02e885f 100644
--- a/drivers/base/dma-mapping.c
+++ b/drivers/base/dma-mapping.c
@@ -10,6 +10,7 @@
10#include <linux/dma-mapping.h> 10#include <linux/dma-mapping.h>
11#include <linux/export.h> 11#include <linux/export.h>
12#include <linux/gfp.h> 12#include <linux/gfp.h>
13#include <asm-generic/dma-coherent.h>
13 14
14/* 15/*
15 * Managed DMA API 16 * Managed DMA API
@@ -218,3 +219,33 @@ void dmam_release_declared_memory(struct device *dev)
218EXPORT_SYMBOL(dmam_release_declared_memory); 219EXPORT_SYMBOL(dmam_release_declared_memory);
219 220
220#endif 221#endif
222
223/*
224 * Create userspace mapping for the DMA-coherent memory.
225 */
226int dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
227 void *cpu_addr, dma_addr_t dma_addr, size_t size)
228{
229 int ret = -ENXIO;
230#ifdef CONFIG_MMU
231 unsigned long user_count = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
232 unsigned long count = PAGE_ALIGN(size) >> PAGE_SHIFT;
233 unsigned long pfn = page_to_pfn(virt_to_page(cpu_addr));
234 unsigned long off = vma->vm_pgoff;
235
236 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
237
238 if (dma_mmap_from_coherent(dev, vma, cpu_addr, size, &ret))
239 return ret;
240
241 if (off < count && user_count <= (count - off)) {
242 ret = remap_pfn_range(vma, vma->vm_start,
243 pfn + off,
244 user_count << PAGE_SHIFT,
245 vma->vm_page_prot);
246 }
247#endif /* CONFIG_MMU */
248
249 return ret;
250}
251EXPORT_SYMBOL(dma_common_mmap);