summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/media/video/videobuf2-dma-nvmap.c42
1 files changed, 35 insertions, 7 deletions
diff --git a/drivers/media/video/videobuf2-dma-nvmap.c b/drivers/media/video/videobuf2-dma-nvmap.c
index 27f43e5a3a57..5ab3c62ac05b 100644
--- a/drivers/media/video/videobuf2-dma-nvmap.c
+++ b/drivers/media/video/videobuf2-dma-nvmap.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2012-2013, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -54,7 +54,7 @@ static void *vb2_dma_nvmap_alloc(void *alloc_ctx, unsigned long size)
}
buf->nvmap_ref = nvmap_alloc(conf->nvmap_client, size, 32,
- NVMAP_HANDLE_CACHEABLE, NVMAP_HEAP_SYSMEM);
+ NVMAP_HANDLE_UNCACHEABLE, 0);
if (IS_ERR(buf->nvmap_ref)) {
dev_err(conf->dev, "nvmap_alloc failed\n");
ret = -ENOMEM;
@@ -134,14 +134,42 @@ static unsigned int vb2_dma_nvmap_num_users(void *buf_priv)
static int vb2_dma_nvmap_mmap(void *buf_priv, struct vm_area_struct *vma)
{
struct vb2_dc_buf *buf = buf_priv;
+ unsigned long vm_start, paddr;
+ void *vaddr;
+ int size;
+ int ret;
if (!buf) {
- printk(KERN_ERR "No buffer to map\n");
+ pr_err("No buffer to map\n");
return -EINVAL;
}
- return vb2_mmap_pfn_range(vma, buf->paddr, buf->size,
- &vb2_common_vm_ops, &buf->handler);
+ size = min_t(unsigned long, vma->vm_end - vma->vm_start, buf->size);
+
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+
+ for (vaddr = buf->vaddr; vaddr < buf->vaddr + size;
+ vaddr += PAGE_SIZE) {
+ paddr = page_to_phys(vmalloc_to_page(vaddr));
+ vm_start = vma->vm_start + (unsigned long) (vaddr - buf->vaddr);
+ ret = remap_pfn_range(vma, vm_start, paddr >> PAGE_SHIFT,
+ PAGE_SIZE, vma->vm_page_prot);
+ if (ret) {
+ pr_err("Remapping memory failed, error: %d\n",
+ ret);
+ return ret;
+ }
+ pr_debug("%s: mapped paddr 0x%08lx at 0x%08lx, size %ld\n",
+ __func__, paddr, vm_start, PAGE_SIZE);
+ }
+
+ vma->vm_flags |= VM_DONTEXPAND | VM_RESERVED;
+ vma->vm_private_data = &buf->handler;
+ vma->vm_ops = &vb2_common_vm_ops;
+
+ vma->vm_ops->open(vma);
+
+ return 0;
}
static void *vb2_dma_nvmap_get_userptr(void *alloc_ctx, unsigned long vaddr,
@@ -158,8 +186,8 @@ static void *vb2_dma_nvmap_get_userptr(void *alloc_ctx, unsigned long vaddr,
ret = vb2_get_contig_userptr(vaddr, size, &vma, &paddr);
if (ret) {
- printk(KERN_ERR "Failed acquiring VMA for vaddr 0x%08lx\n",
- vaddr);
+ pr_err("Failed acquiring VMA for vaddr 0x%08lx\n",
+ vaddr);
kfree(buf);
return ERR_PTR(ret);
}