summaryrefslogtreecommitdiff
path: root/drivers/media/v4l2-core/v4l2-mem2mem.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/v4l2-core/v4l2-mem2mem.c')
-rw-r--r--drivers/media/v4l2-core/v4l2-mem2mem.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c
index b221b4e438a1..e7f4bf5bc8dd 100644
--- a/drivers/media/v4l2-core/v4l2-mem2mem.c
+++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
@@ -887,9 +887,6 @@ static __poll_t v4l2_m2m_poll_for_data(struct file *file,
src_q = v4l2_m2m_get_src_vq(m2m_ctx);
dst_q = v4l2_m2m_get_dst_vq(m2m_ctx);
- poll_wait(file, &src_q->done_wq, wait);
- poll_wait(file, &dst_q->done_wq, wait);
-
/*
* There has to be at least one buffer queued on each queued_list, which
* means either in driver already or waiting for driver to claim it
@@ -922,9 +919,21 @@ __poll_t v4l2_m2m_poll(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
struct poll_table_struct *wait)
{
struct video_device *vfd = video_devdata(file);
+ struct vb2_queue *src_q = v4l2_m2m_get_src_vq(m2m_ctx);
+ struct vb2_queue *dst_q = v4l2_m2m_get_dst_vq(m2m_ctx);
__poll_t req_events = poll_requested_events(wait);
__poll_t rc = 0;
+ /*
+ * poll_wait() MUST be called on the first invocation on all the
+ * potential queues of interest, even if we are not interested in their
+ * events during this first call. Failure to do so will result in
+ * queue's events to be ignored because the poll_table won't be capable
+ * of adding new wait queues thereafter.
+ */
+ poll_wait(file, &src_q->done_wq, wait);
+ poll_wait(file, &dst_q->done_wq, wait);
+
if (req_events & (EPOLLOUT | EPOLLWRNORM | EPOLLIN | EPOLLRDNORM))
rc = v4l2_m2m_poll_for_data(file, m2m_ctx, wait);