diff options
-rw-r--r-- | drivers/media/v4l2-core/v4l2-mem2mem.c | 47 |
1 files changed, 27 insertions, 20 deletions
diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c index 4f5176702937..19937dd3c6f6 100644 --- a/drivers/media/v4l2-core/v4l2-mem2mem.c +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c @@ -603,11 +603,10 @@ int v4l2_m2m_streamoff(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, } EXPORT_SYMBOL_GPL(v4l2_m2m_streamoff); -__poll_t v4l2_m2m_poll(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, - struct poll_table_struct *wait) +static __poll_t v4l2_m2m_poll_for_data(struct file *file, + struct v4l2_m2m_ctx *m2m_ctx, + struct poll_table_struct *wait) { - struct video_device *vfd = video_devdata(file); - __poll_t req_events = poll_requested_events(wait); struct vb2_queue *src_q, *dst_q; struct vb2_buffer *src_vb = NULL, *dst_vb = NULL; __poll_t rc = 0; @@ -619,16 +618,6 @@ __poll_t v4l2_m2m_poll(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, poll_wait(file, &src_q->done_wq, wait); poll_wait(file, &dst_q->done_wq, wait); - if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags)) { - struct v4l2_fh *fh = file->private_data; - - poll_wait(file, &fh->wait, wait); - if (v4l2_event_pending(fh)) - rc = EPOLLPRI; - if (!(req_events & (EPOLLOUT | EPOLLWRNORM | EPOLLIN | EPOLLRDNORM))) - return rc; - } - /* * 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 @@ -637,10 +626,8 @@ __poll_t v4l2_m2m_poll(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, if ((!src_q->streaming || src_q->error || list_empty(&src_q->queued_list)) && (!dst_q->streaming || dst_q->error || - list_empty(&dst_q->queued_list))) { - rc |= EPOLLERR; - goto end; - } + list_empty(&dst_q->queued_list))) + return EPOLLERR; spin_lock_irqsave(&dst_q->done_lock, flags); if (list_empty(&dst_q->done_list)) { @@ -650,7 +637,7 @@ __poll_t v4l2_m2m_poll(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, */ if (dst_q->last_buffer_dequeued) { spin_unlock_irqrestore(&dst_q->done_lock, flags); - return rc | EPOLLIN | EPOLLRDNORM; + return EPOLLIN | EPOLLRDNORM; } } spin_unlock_irqrestore(&dst_q->done_lock, flags); @@ -673,7 +660,27 @@ __poll_t v4l2_m2m_poll(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, rc |= EPOLLIN | EPOLLRDNORM; spin_unlock_irqrestore(&dst_q->done_lock, flags); -end: + return rc; +} + +__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); + __poll_t req_events = poll_requested_events(wait); + __poll_t rc = 0; + + if (req_events & (EPOLLOUT | EPOLLWRNORM | EPOLLIN | EPOLLRDNORM)) + rc = v4l2_m2m_poll_for_data(file, m2m_ctx, wait); + + if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags)) { + struct v4l2_fh *fh = file->private_data; + + poll_wait(file, &fh->wait, wait); + if (v4l2_event_pending(fh)) + rc |= EPOLLPRI; + } + return rc; } EXPORT_SYMBOL_GPL(v4l2_m2m_poll); |