]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
media: videobuf-dma-contig: restore buffer mapping for uncached bufers
authorLad, Prabhakar <prabhakar.lad@ti.com>
Fri, 22 Jun 2012 09:19:28 +0000 (06:19 -0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 15 Aug 2012 14:52:32 +0000 (07:52 -0700)
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

index b6b5cc1a43cb9261023f52fd7c78fdb77e49066d..358f4c0c4b2a47228f0a7a8039173d11a94df7d9 100644 (file)
@@ -359,32 +359,43 @@ static int __videobuf_mmap_mapper(struct videobuf_queue *q,
        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;