blob: d1595c767b12521c819734d558c274fed5eb297a [file] [log] [blame]
From 4099040eaaa4fe543c4e915b8cab51b1d843edee Mon Sep 17 00:00:00 2001
From: "Lad, Prabhakar" <prabhakar.lad@ti.com>
Date: Fri, 22 Jun 2012 06:19:28 -0300
Subject: media: videobuf-dma-contig: restore buffer mapping for uncached bufers
From: "Lad, Prabhakar" <prabhakar.lad@ti.com>
commit 4099040eaaa4fe543c4e915b8cab51b1d843edee upstream.
from commit a8f3c203e19b702fa5e8e83a9b6fb3c5a6d1cce4
restore the mapping scheme for uncached buffers,
which was changed in a common scheme for cached and uncached.
This apparently was wrong, and was probably intended only for cached buffers.
the fix fixes the crash observed while mapping uncached buffers.
Signed-off-by: Lad, Prabhakar <prabhakar.lad@ti.com>
Signed-off-by: Hadli, Manjunath <manjunath.hadli@ti.com>
Acked-by: Federico Vaga <federico.vaga@gmail.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/media/video/videobuf-dma-contig.c | 53 ++++++++++++++++++------------
1 file changed, 32 insertions(+), 21 deletions(-)
--- a/drivers/media/video/videobuf-dma-contig.c
+++ b/drivers/media/video/videobuf-dma-contig.c
@@ -359,32 +359,43 @@ static int __videobuf_mmap_mapper(struct
size = vma->vm_end - vma->vm_start;
size = (size < mem->size) ? size : mem->size;
- if (!mem->cached)
+ if (!mem->cached) {
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-
- pos = (unsigned long)mem->vaddr;
-
- while (size > 0) {
- page = virt_to_page((void *)pos);
- if (NULL == page) {
- dev_err(q->dev, "mmap: virt_to_page failed\n");
- __videobuf_dc_free(q->dev, mem);
- goto error;
- }
- retval = vm_insert_page(vma, start, page);
+ retval = remap_pfn_range(vma, vma->vm_start,
+ mem->dma_handle >> PAGE_SHIFT,
+ size, vma->vm_page_prot);
if (retval) {
- dev_err(q->dev, "mmap: insert failed with error %d\n",
- retval);
- __videobuf_dc_free(q->dev, mem);
+ dev_err(q->dev, "mmap: remap failed with error %d. ",
+ retval);
+ dma_free_coherent(q->dev, mem->size,
+ mem->vaddr, mem->dma_handle);
goto error;
}
- start += PAGE_SIZE;
- pos += PAGE_SIZE;
+ } else {
+ pos = (unsigned long)mem->vaddr;
+
+ while (size > 0) {
+ page = virt_to_page((void *)pos);
+ if (NULL == page) {
+ dev_err(q->dev, "mmap: virt_to_page failed\n");
+ __videobuf_dc_free(q->dev, mem);
+ goto error;
+ }
+ retval = vm_insert_page(vma, start, page);
+ if (retval) {
+ dev_err(q->dev, "mmap: insert failed with error %d\n",
+ retval);
+ __videobuf_dc_free(q->dev, mem);
+ goto error;
+ }
+ start += PAGE_SIZE;
+ pos += PAGE_SIZE;
- if (size > PAGE_SIZE)
- size -= PAGE_SIZE;
- else
- size = 0;
+ if (size > PAGE_SIZE)
+ size -= PAGE_SIZE;
+ else
+ size = 0;
+ }
}
vma->vm_ops = &videobuf_vm_ops;