aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorTomasz Stanislawski <t.stanislaws@samsung.com>2012-06-14 10:32:24 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-11-25 14:21:00 -0500
commit83ae7c5a1b5b5cd4380ff70797e4c5dcfb61a70d (patch)
tree2b1b4741b24b73c9a61ebe48fb9a399b194e01e0 /drivers/media
parent19b6ef51640fb35666884c7b577b1a24a4be8e34 (diff)
[media] v4l: vb2: add buffer exporting via dmabuf
This patch adds extension to videobuf2-core. It allow to export an mmap buffer as a DMABUF file descriptor. Signed-off-by: Tomasz Stanislawski <t.stanislaws@samsung.com> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Acked-by: Hans Verkuil <hans.verkuil@cisco.com> Tested-by: Mauro Carvalho Chehab <mchehab@redhat.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/v4l2-core/v4l2-mem2mem.c13
-rw-r--r--drivers/media/v4l2-core/videobuf2-core.c83
2 files changed, 96 insertions, 0 deletions
diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c
index 017fed8ad2ab..438ea45d1074 100644
--- a/drivers/media/v4l2-core/v4l2-mem2mem.c
+++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
@@ -369,6 +369,19 @@ int v4l2_m2m_dqbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
369EXPORT_SYMBOL_GPL(v4l2_m2m_dqbuf); 369EXPORT_SYMBOL_GPL(v4l2_m2m_dqbuf);
370 370
371/** 371/**
372 * v4l2_m2m_expbuf() - export a source or destination buffer, depending on
373 * the type
374 */
375int v4l2_m2m_expbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
376 struct v4l2_exportbuffer *eb)
377{
378 struct vb2_queue *vq;
379
380 vq = v4l2_m2m_get_vq(m2m_ctx, eb->type);
381 return vb2_expbuf(vq, eb);
382}
383EXPORT_SYMBOL_GPL(v4l2_m2m_expbuf);
384/**
372 * v4l2_m2m_streamon() - turn on streaming for a video queue 385 * v4l2_m2m_streamon() - turn on streaming for a video queue
373 */ 386 */
374int v4l2_m2m_streamon(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, 387int v4l2_m2m_streamon(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c
index 613dea16a304..9f81be23a81f 100644
--- a/drivers/media/v4l2-core/videobuf2-core.c
+++ b/drivers/media/v4l2-core/videobuf2-core.c
@@ -1751,6 +1751,79 @@ static int __find_plane_by_offset(struct vb2_queue *q, unsigned long off,
1751} 1751}
1752 1752
1753/** 1753/**
1754 * vb2_expbuf() - Export a buffer as a file descriptor
1755 * @q: videobuf2 queue
1756 * @eb: export buffer structure passed from userspace to vidioc_expbuf
1757 * handler in driver
1758 *
1759 * The return values from this function are intended to be directly returned
1760 * from vidioc_expbuf handler in driver.
1761 */
1762int vb2_expbuf(struct vb2_queue *q, struct v4l2_exportbuffer *eb)
1763{
1764 struct vb2_buffer *vb = NULL;
1765 struct vb2_plane *vb_plane;
1766 int ret;
1767 struct dma_buf *dbuf;
1768
1769 if (q->memory != V4L2_MEMORY_MMAP) {
1770 dprintk(1, "Queue is not currently set up for mmap\n");
1771 return -EINVAL;
1772 }
1773
1774 if (!q->mem_ops->get_dmabuf) {
1775 dprintk(1, "Queue does not support DMA buffer exporting\n");
1776 return -EINVAL;
1777 }
1778
1779 if (eb->flags & ~O_CLOEXEC) {
1780 dprintk(1, "Queue does support only O_CLOEXEC flag\n");
1781 return -EINVAL;
1782 }
1783
1784 if (eb->type != q->type) {
1785 dprintk(1, "qbuf: invalid buffer type\n");
1786 return -EINVAL;
1787 }
1788
1789 if (eb->index >= q->num_buffers) {
1790 dprintk(1, "buffer index out of range\n");
1791 return -EINVAL;
1792 }
1793
1794 vb = q->bufs[eb->index];
1795
1796 if (eb->plane >= vb->num_planes) {
1797 dprintk(1, "buffer plane out of range\n");
1798 return -EINVAL;
1799 }
1800
1801 vb_plane = &vb->planes[eb->plane];
1802
1803 dbuf = call_memop(q, get_dmabuf, vb_plane->mem_priv);
1804 if (IS_ERR_OR_NULL(dbuf)) {
1805 dprintk(1, "Failed to export buffer %d, plane %d\n",
1806 eb->index, eb->plane);
1807 return -EINVAL;
1808 }
1809
1810 ret = dma_buf_fd(dbuf, eb->flags);
1811 if (ret < 0) {
1812 dprintk(3, "buffer %d, plane %d failed to export (%d)\n",
1813 eb->index, eb->plane, ret);
1814 dma_buf_put(dbuf);
1815 return ret;
1816 }
1817
1818 dprintk(3, "buffer %d, plane %d exported as %d descriptor\n",
1819 eb->index, eb->plane, ret);
1820 eb->fd = ret;
1821
1822 return 0;
1823}
1824EXPORT_SYMBOL_GPL(vb2_expbuf);
1825
1826/**
1754 * vb2_mmap() - map video buffers into application address space 1827 * vb2_mmap() - map video buffers into application address space
1755 * @q: videobuf2 queue 1828 * @q: videobuf2 queue
1756 * @vma: vma passed to the mmap file operation handler in the driver 1829 * @vma: vma passed to the mmap file operation handler in the driver
@@ -2456,6 +2529,16 @@ int vb2_ioctl_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
2456} 2529}
2457EXPORT_SYMBOL_GPL(vb2_ioctl_streamoff); 2530EXPORT_SYMBOL_GPL(vb2_ioctl_streamoff);
2458 2531
2532int vb2_ioctl_expbuf(struct file *file, void *priv, struct v4l2_exportbuffer *p)
2533{
2534 struct video_device *vdev = video_devdata(file);
2535
2536 if (vb2_queue_is_busy(vdev, file))
2537 return -EBUSY;
2538 return vb2_expbuf(vdev->queue, p);
2539}
2540EXPORT_SYMBOL_GPL(vb2_ioctl_expbuf);
2541
2459/* v4l2_file_operations helpers */ 2542/* v4l2_file_operations helpers */
2460 2543
2461int vb2_fop_mmap(struct file *file, struct vm_area_struct *vma) 2544int vb2_fop_mmap(struct file *file, struct vm_area_struct *vma)