summaryrefslogtreecommitdiffstats
path: root/kernel/drivers/media/platform/omap
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/drivers/media/platform/omap')
-rw-r--r--kernel/drivers/media/platform/omap/Kconfig1
-rw-r--r--kernel/drivers/media/platform/omap/omap_vout.c81
2 files changed, 36 insertions, 46 deletions
diff --git a/kernel/drivers/media/platform/omap/Kconfig b/kernel/drivers/media/platform/omap/Kconfig
index dc2aaab54..217d613b0 100644
--- a/kernel/drivers/media/platform/omap/Kconfig
+++ b/kernel/drivers/media/platform/omap/Kconfig
@@ -10,6 +10,7 @@ config VIDEO_OMAP2_VOUT
select OMAP2_DSS if HAS_IOMEM && ARCH_OMAP2PLUS
select OMAP2_VRFB if ARCH_OMAP2 || ARCH_OMAP3
select VIDEO_OMAP2_VOUT_VRFB if VIDEO_OMAP2_VOUT && OMAP2_VRFB
+ select FRAME_VECTOR
default n
---help---
V4L2 Display driver support for OMAP2/3 based boards.
diff --git a/kernel/drivers/media/platform/omap/omap_vout.c b/kernel/drivers/media/platform/omap/omap_vout.c
index 17b189a81..70c28d19e 100644
--- a/kernel/drivers/media/platform/omap/omap_vout.c
+++ b/kernel/drivers/media/platform/omap/omap_vout.c
@@ -195,46 +195,34 @@ static int omap_vout_try_format(struct v4l2_pix_format *pix)
}
/*
- * omap_vout_uservirt_to_phys: This inline function is used to convert user
- * space virtual address to physical address.
+ * omap_vout_get_userptr: Convert user space virtual address to physical
+ * address.
*/
-static unsigned long omap_vout_uservirt_to_phys(unsigned long virtp)
+static int omap_vout_get_userptr(struct videobuf_buffer *vb, u32 virtp,
+ u32 *physp)
{
- unsigned long physp = 0;
- struct vm_area_struct *vma;
- struct mm_struct *mm = current->mm;
+ struct frame_vector *vec;
+ int ret;
/* For kernel direct-mapped memory, take the easy way */
- if (virtp >= PAGE_OFFSET)
- return virt_to_phys((void *) virtp);
-
- down_read(&current->mm->mmap_sem);
- vma = find_vma(mm, virtp);
- if (vma && (vma->vm_flags & VM_IO) && vma->vm_pgoff) {
- /* this will catch, kernel-allocated, mmaped-to-usermode
- addresses */
- physp = (vma->vm_pgoff << PAGE_SHIFT) + (virtp - vma->vm_start);
- up_read(&current->mm->mmap_sem);
- } else {
- /* otherwise, use get_user_pages() for general userland pages */
- int res, nr_pages = 1;
- struct page *pages;
+ if (virtp >= PAGE_OFFSET) {
+ *physp = virt_to_phys((void *)virtp);
+ return 0;
+ }
- res = get_user_pages(current, current->mm, virtp, nr_pages, 1,
- 0, &pages, NULL);
- up_read(&current->mm->mmap_sem);
+ vec = frame_vector_create(1);
+ if (!vec)
+ return -ENOMEM;
- if (res == nr_pages) {
- physp = __pa(page_address(&pages[0]) +
- (virtp & ~PAGE_MASK));
- } else {
- printk(KERN_WARNING VOUT_NAME
- "get_user_pages failed\n");
- return 0;
- }
+ ret = get_vaddr_frames(virtp, 1, true, false, vec);
+ if (ret != 1) {
+ frame_vector_destroy(vec);
+ return -EINVAL;
}
+ *physp = __pfn_to_phys(frame_vector_pfns(vec)[0]);
+ vb->priv = vec;
- return physp;
+ return 0;
}
/*
@@ -445,7 +433,7 @@ static int omapvid_init(struct omap_vout_device *vout, u32 addr)
int ret = 0, i;
struct v4l2_window *win;
struct omap_overlay *ovl;
- int posx, posy, outw, outh, temp;
+ int posx, posy, outw, outh;
struct omap_video_timings *timing;
struct omapvideo_info *ovid = &vout->vid_info;
@@ -468,9 +456,7 @@ static int omapvid_init(struct omap_vout_device *vout, u32 addr)
/* Invert the height and width for 90
* and 270 degree rotation
*/
- temp = outw;
- outw = outh;
- outh = temp;
+ swap(outw, outh);
posy = (timing->y_res - win->w.width) - win->w.left;
posx = win->w.top;
break;
@@ -481,9 +467,7 @@ static int omapvid_init(struct omap_vout_device *vout, u32 addr)
break;
case dss_rotation_270_degree:
- temp = outw;
- outw = outh;
- outh = temp;
+ swap(outw, outh);
posy = win->w.left;
posx = (timing->x_res - win->w.height) - win->w.top;
break;
@@ -788,11 +772,15 @@ static int omap_vout_buffer_prepare(struct videobuf_queue *q,
* address of the buffer
*/
if (V4L2_MEMORY_USERPTR == vb->memory) {
+ int ret;
+
if (0 == vb->baddr)
return -EINVAL;
/* Physical address */
- vout->queued_buf_addr[vb->i] = (u8 *)
- omap_vout_uservirt_to_phys(vb->baddr);
+ ret = omap_vout_get_userptr(vb, vb->baddr,
+ (u32 *)&vout->queued_buf_addr[vb->i]);
+ if (ret < 0)
+ return ret;
} else {
unsigned long addr, dma_addr;
unsigned long size;
@@ -838,12 +826,13 @@ static void omap_vout_buffer_queue(struct videobuf_queue *q,
static void omap_vout_buffer_release(struct videobuf_queue *q,
struct videobuf_buffer *vb)
{
- struct omap_vout_device *vout = q->priv_data;
-
vb->state = VIDEOBUF_NEEDS_INIT;
+ if (vb->memory == V4L2_MEMORY_USERPTR && vb->priv) {
+ struct frame_vector *vec = vb->priv;
- if (V4L2_MEMORY_MMAP != vout->memory)
- return;
+ put_vaddr_frames(vec);
+ frame_vector_destroy(vec);
+ }
}
/*
@@ -876,7 +865,7 @@ static void omap_vout_vm_close(struct vm_area_struct *vma)
vout->mmap_count--;
}
-static struct vm_operations_struct omap_vout_vm_ops = {
+static const struct vm_operations_struct omap_vout_vm_ops = {
.open = omap_vout_vm_open,
.close = omap_vout_vm_close,
};