aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-07-30 13:11:31 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-07-30 13:11:31 -0400
commit6f51f51582e793ea13e7de7ed6b138f71c51784b (patch)
tree211ecbf88cdf2f183e23da3f8f23153ac6133410 /drivers/base
parent76159c20c0bcf5b38178fbfb61049eeb6380bb54 (diff)
parent97ef952a20853fad72087a53fa556fbec45edd8f (diff)
Merge branch 'for-linus-for-3.6-rc1' of git://git.linaro.org/people/mszyprowski/linux-dma-mapping
Pull DMA-mapping updates from Marek Szyprowski: "Those patches are continuation of my earlier work. They contains extensions to DMA-mapping framework to remove limitation of the current ARM implementation (like limited total size of DMA coherent/write combine buffers), improve performance of buffer sharing between devices (attributes to skip cpu cache operations or creation of additional kernel mapping for some specific use cases) as well as some unification of the common code for dma_mmap_attrs() and dma_mmap_coherent() functions. All extensions have been implemented and tested for ARM architecture." * 'for-linus-for-3.6-rc1' of git://git.linaro.org/people/mszyprowski/linux-dma-mapping: ARM: dma-mapping: add support for DMA_ATTR_SKIP_CPU_SYNC attribute common: DMA-mapping: add DMA_ATTR_SKIP_CPU_SYNC attribute ARM: dma-mapping: add support for dma_get_sgtable() common: dma-mapping: introduce dma_get_sgtable() function ARM: dma-mapping: add support for DMA_ATTR_NO_KERNEL_MAPPING attribute common: DMA-mapping: add DMA_ATTR_NO_KERNEL_MAPPING attribute common: dma-mapping: add support for generic dma_mmap_* calls ARM: dma-mapping: fix error path for memory allocation failure ARM: dma-mapping: add more sanity checks in arm_dma_mmap() ARM: dma-mapping: remove custom consistent dma region mm: vmalloc: use const void * for caller argument scatterlist: add sg_alloc_table_from_pages function
Diffstat (limited to 'drivers/base')
-rw-r--r--drivers/base/dma-mapping.c49
1 files changed, 49 insertions, 0 deletions
diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c
index 6f3676f1559f..3fbedc75e7c5 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
@@ -217,4 +218,52 @@ void dmam_release_declared_memory(struct device *dev)
217} 218}
218EXPORT_SYMBOL(dmam_release_declared_memory); 219EXPORT_SYMBOL(dmam_release_declared_memory);
219 220
221/*
222 * Create scatter-list for the already allocated DMA buffer.
223 */
224int dma_common_get_sgtable(struct device *dev, struct sg_table *sgt,
225 void *cpu_addr, dma_addr_t handle, size_t size)
226{
227 struct page *page = virt_to_page(cpu_addr);
228 int ret;
229
230 ret = sg_alloc_table(sgt, 1, GFP_KERNEL);
231 if (unlikely(ret))
232 return ret;
233
234 sg_set_page(sgt->sgl, page, PAGE_ALIGN(size), 0);
235 return 0;
236}
237EXPORT_SYMBOL(dma_common_get_sgtable);
238
220#endif 239#endif
240
241/*
242 * Create userspace mapping for the DMA-coherent memory.
243 */
244int dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
245 void *cpu_addr, dma_addr_t dma_addr, size_t size)
246{
247 int ret = -ENXIO;
248#ifdef CONFIG_MMU
249 unsigned long user_count = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
250 unsigned long count = PAGE_ALIGN(size) >> PAGE_SHIFT;
251 unsigned long pfn = page_to_pfn(virt_to_page(cpu_addr));
252 unsigned long off = vma->vm_pgoff;
253
254 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
255
256 if (dma_mmap_from_coherent(dev, vma, cpu_addr, size, &ret))
257 return ret;
258
259 if (off < count && user_count <= (count - off)) {
260 ret = remap_pfn_range(vma, vma->vm_start,
261 pfn + off,
262 user_count << PAGE_SHIFT,
263 vma->vm_page_prot);
264 }
265#endif /* CONFIG_MMU */
266
267 return ret;
268}
269EXPORT_SYMBOL(dma_common_mmap);