aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSylwester Nawrocki <s.nawrocki@samsung.com>2013-09-14 17:39:04 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2013-12-04 12:34:24 -0500
commit8e6e8f93f7cb3452b1c00da8a30d01558628d913 (patch)
tree0f1a5f470a68299a1f607be4b2426e9484bbd348
parent2e1ab9cb94a257dcd7561601be44ca8b35b27365 (diff)
[media] V4L: Add mem2mem ioctl and file operation helpers
This patch adds ioctl helpers to the V4L2 mem-to-mem API, so we can avoid several ioctl handlers in the mem-to-mem video node drivers that are simply a pass-through to the v4l2_m2m_* calls. These helpers will only be useful for drivers that use same mutex for both OUTPUT and CAPTURE queue, which is the case for all currently in tree v4l2 m2m drivers. In order to use the helpers the drivers are required to use struct v4l2_fh. Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> Acked-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/media/v4l2-core/v4l2-mem2mem.c126
-rw-r--r--include/media/v4l2-fh.h4
-rw-r--r--include/media/v4l2-mem2mem.h24
3 files changed, 154 insertions, 0 deletions
diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c
index 73035ee0f4de..178ce96556c6 100644
--- a/drivers/media/v4l2-core/v4l2-mem2mem.c
+++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
@@ -558,6 +558,8 @@ unsigned int v4l2_m2m_poll(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
558 558
559 if (m2m_ctx->m2m_dev->m2m_ops->unlock) 559 if (m2m_ctx->m2m_dev->m2m_ops->unlock)
560 m2m_ctx->m2m_dev->m2m_ops->unlock(m2m_ctx->priv); 560 m2m_ctx->m2m_dev->m2m_ops->unlock(m2m_ctx->priv);
561 else if (m2m_ctx->q_lock)
562 mutex_unlock(m2m_ctx->q_lock);
561 563
562 if (list_empty(&src_q->done_list)) 564 if (list_empty(&src_q->done_list))
563 poll_wait(file, &src_q->done_wq, wait); 565 poll_wait(file, &src_q->done_wq, wait);
@@ -566,6 +568,8 @@ unsigned int v4l2_m2m_poll(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
566 568
567 if (m2m_ctx->m2m_dev->m2m_ops->lock) 569 if (m2m_ctx->m2m_dev->m2m_ops->lock)
568 m2m_ctx->m2m_dev->m2m_ops->lock(m2m_ctx->priv); 570 m2m_ctx->m2m_dev->m2m_ops->lock(m2m_ctx->priv);
571 else if (m2m_ctx->q_lock)
572 mutex_lock(m2m_ctx->q_lock);
569 573
570 spin_lock_irqsave(&src_q->done_lock, flags); 574 spin_lock_irqsave(&src_q->done_lock, flags);
571 if (!list_empty(&src_q->done_list)) 575 if (!list_empty(&src_q->done_list))
@@ -693,6 +697,13 @@ struct v4l2_m2m_ctx *v4l2_m2m_ctx_init(struct v4l2_m2m_dev *m2m_dev,
693 697
694 if (ret) 698 if (ret)
695 goto err; 699 goto err;
700 /*
701 * If both queues use same mutex assign it as the common buffer
702 * queues lock to the m2m context. This lock is used in the
703 * v4l2_m2m_ioctl_* helpers.
704 */
705 if (out_q_ctx->q.lock == cap_q_ctx->q.lock)
706 m2m_ctx->q_lock = out_q_ctx->q.lock;
696 707
697 return m2m_ctx; 708 return m2m_ctx;
698err: 709err:
@@ -740,3 +751,118 @@ void v4l2_m2m_buf_queue(struct v4l2_m2m_ctx *m2m_ctx, struct vb2_buffer *vb)
740} 751}
741EXPORT_SYMBOL_GPL(v4l2_m2m_buf_queue); 752EXPORT_SYMBOL_GPL(v4l2_m2m_buf_queue);
742 753
754/* Videobuf2 ioctl helpers */
755
756int v4l2_m2m_ioctl_reqbufs(struct file *file, void *priv,
757 struct v4l2_requestbuffers *rb)
758{
759 struct v4l2_fh *fh = file->private_data;
760
761 return v4l2_m2m_reqbufs(file, fh->m2m_ctx, rb);
762}
763EXPORT_SYMBOL_GPL(v4l2_m2m_ioctl_reqbufs);
764
765int v4l2_m2m_ioctl_create_bufs(struct file *file, void *priv,
766 struct v4l2_create_buffers *create)
767{
768 struct v4l2_fh *fh = file->private_data;
769
770 return v4l2_m2m_create_bufs(file, fh->m2m_ctx, create);
771}
772EXPORT_SYMBOL_GPL(v4l2_m2m_ioctl_create_bufs);
773
774int v4l2_m2m_ioctl_querybuf(struct file *file, void *priv,
775 struct v4l2_buffer *buf)
776{
777 struct v4l2_fh *fh = file->private_data;
778
779 return v4l2_m2m_querybuf(file, fh->m2m_ctx, buf);
780}
781EXPORT_SYMBOL_GPL(v4l2_m2m_ioctl_querybuf);
782
783int v4l2_m2m_ioctl_qbuf(struct file *file, void *priv,
784 struct v4l2_buffer *buf)
785{
786 struct v4l2_fh *fh = file->private_data;
787
788 return v4l2_m2m_qbuf(file, fh->m2m_ctx, buf);
789}
790EXPORT_SYMBOL_GPL(v4l2_m2m_ioctl_qbuf);
791
792int v4l2_m2m_ioctl_dqbuf(struct file *file, void *priv,
793 struct v4l2_buffer *buf)
794{
795 struct v4l2_fh *fh = file->private_data;
796
797 return v4l2_m2m_dqbuf(file, fh->m2m_ctx, buf);
798}
799EXPORT_SYMBOL_GPL(v4l2_m2m_ioctl_dqbuf);
800
801int v4l2_m2m_ioctl_expbuf(struct file *file, void *priv,
802 struct v4l2_exportbuffer *eb)
803{
804 struct v4l2_fh *fh = file->private_data;
805
806 return v4l2_m2m_expbuf(file, fh->m2m_ctx, eb);
807}
808EXPORT_SYMBOL_GPL(v4l2_m2m_ioctl_expbuf);
809
810int v4l2_m2m_ioctl_streamon(struct file *file, void *priv,
811 enum v4l2_buf_type type)
812{
813 struct v4l2_fh *fh = file->private_data;
814
815 return v4l2_m2m_streamon(file, fh->m2m_ctx, type);
816}
817EXPORT_SYMBOL_GPL(v4l2_m2m_ioctl_streamon);
818
819int v4l2_m2m_ioctl_streamoff(struct file *file, void *priv,
820 enum v4l2_buf_type type)
821{
822 struct v4l2_fh *fh = file->private_data;
823
824 return v4l2_m2m_streamoff(file, fh->m2m_ctx, type);
825}
826EXPORT_SYMBOL_GPL(v4l2_m2m_ioctl_streamoff);
827
828/*
829 * v4l2_file_operations helpers. It is assumed here same lock is used
830 * for the output and the capture buffer queue.
831 */
832
833int v4l2_m2m_fop_mmap(struct file *file, struct vm_area_struct *vma)
834{
835 struct v4l2_fh *fh = file->private_data;
836 struct v4l2_m2m_ctx *m2m_ctx = fh->m2m_ctx;
837 int ret;
838
839 if (m2m_ctx->q_lock && mutex_lock_interruptible(m2m_ctx->q_lock))
840 return -ERESTARTSYS;
841
842 ret = v4l2_m2m_mmap(file, m2m_ctx, vma);
843
844 if (m2m_ctx->q_lock)
845 mutex_unlock(m2m_ctx->q_lock);
846
847 return ret;
848}
849EXPORT_SYMBOL_GPL(v4l2_m2m_fop_mmap);
850
851unsigned int v4l2_m2m_fop_poll(struct file *file, poll_table *wait)
852{
853 struct v4l2_fh *fh = file->private_data;
854 struct v4l2_m2m_ctx *m2m_ctx = fh->m2m_ctx;
855 unsigned int ret;
856
857 if (m2m_ctx->q_lock)
858 mutex_lock(m2m_ctx->q_lock);
859
860 ret = v4l2_m2m_poll(file, m2m_ctx, wait);
861
862 if (m2m_ctx->q_lock)
863 mutex_unlock(m2m_ctx->q_lock);
864
865 return ret;
866}
867EXPORT_SYMBOL_GPL(v4l2_m2m_fop_poll);
868
diff --git a/include/media/v4l2-fh.h b/include/media/v4l2-fh.h
index 528cdaf622e1..803516775162 100644
--- a/include/media/v4l2-fh.h
+++ b/include/media/v4l2-fh.h
@@ -45,6 +45,10 @@ struct v4l2_fh {
45 struct list_head available; /* Dequeueable event */ 45 struct list_head available; /* Dequeueable event */
46 unsigned int navailable; 46 unsigned int navailable;
47 u32 sequence; 47 u32 sequence;
48
49#if IS_ENABLED(CONFIG_V4L2_MEM2MEM_DEV)
50 struct v4l2_m2m_ctx *m2m_ctx;
51#endif
48}; 52};
49 53
50/* 54/*
diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h
index 44542a20ab81..12ea5a6a4331 100644
--- a/include/media/v4l2-mem2mem.h
+++ b/include/media/v4l2-mem2mem.h
@@ -64,6 +64,9 @@ struct v4l2_m2m_queue_ctx {
64}; 64};
65 65
66struct v4l2_m2m_ctx { 66struct v4l2_m2m_ctx {
67 /* optional cap/out vb2 queues lock */
68 struct mutex *q_lock;
69
67/* private: internal use only */ 70/* private: internal use only */
68 struct v4l2_m2m_dev *m2m_dev; 71 struct v4l2_m2m_dev *m2m_dev;
69 72
@@ -229,5 +232,26 @@ static inline void *v4l2_m2m_dst_buf_remove(struct v4l2_m2m_ctx *m2m_ctx)
229 return v4l2_m2m_buf_remove(&m2m_ctx->cap_q_ctx); 232 return v4l2_m2m_buf_remove(&m2m_ctx->cap_q_ctx);
230} 233}
231 234
235/* v4l2 ioctl helpers */
236
237int v4l2_m2m_ioctl_reqbufs(struct file *file, void *priv,
238 struct v4l2_requestbuffers *rb);
239int v4l2_m2m_ioctl_create_bufs(struct file *file, void *fh,
240 struct v4l2_create_buffers *create);
241int v4l2_m2m_ioctl_querybuf(struct file *file, void *fh,
242 struct v4l2_buffer *buf);
243int v4l2_m2m_ioctl_expbuf(struct file *file, void *fh,
244 struct v4l2_exportbuffer *eb);
245int v4l2_m2m_ioctl_qbuf(struct file *file, void *fh,
246 struct v4l2_buffer *buf);
247int v4l2_m2m_ioctl_dqbuf(struct file *file, void *fh,
248 struct v4l2_buffer *buf);
249int v4l2_m2m_ioctl_streamon(struct file *file, void *fh,
250 enum v4l2_buf_type type);
251int v4l2_m2m_ioctl_streamoff(struct file *file, void *fh,
252 enum v4l2_buf_type type);
253int v4l2_m2m_fop_mmap(struct file *file, struct vm_area_struct *vma);
254unsigned int v4l2_m2m_fop_poll(struct file *file, poll_table *wait);
255
232#endif /* _MEDIA_V4L2_MEM2MEM_H */ 256#endif /* _MEDIA_V4L2_MEM2MEM_H */
233 257