diff options
author | John Sheu <sheu@chromium.org> | 2013-02-06 18:03:01 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2013-03-19 14:13:33 -0400 |
commit | 401f6a2729988c7229c3a78bba0d2f73851e3f51 (patch) | |
tree | 03f0331a3557b262fd508a769cf48673c3f39e1c /drivers/media/v4l2-core | |
parent | f1a0569be680a1bfb9d624cc4893cba0c6ad4172 (diff) |
[media] v4l2-mem2mem: drop rdy_queue on STREAMOFF
When a v4l2-mem2mem context gets a STREAMOFF call on either its CAPTURE
or OUTPUT queues, we should:
* Drop the corresponding rdy_queue, since a subsequent STREAMON expects
an empty queue.
* Deschedule the context, as it now has at least one empty queue and
cannot run.
Signed-off-by: John Sheu <sheu@google.com>
Acked-by: Pawel Osciak <pawel@osciak.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/v4l2-core')
-rw-r--r-- | drivers/media/v4l2-core/v4l2-mem2mem.c | 31 |
1 files changed, 28 insertions, 3 deletions
diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c index 27ddb3d15251..66f599fcb829 100644 --- a/drivers/media/v4l2-core/v4l2-mem2mem.c +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c | |||
@@ -408,10 +408,35 @@ EXPORT_SYMBOL_GPL(v4l2_m2m_streamon); | |||
408 | int v4l2_m2m_streamoff(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, | 408 | int v4l2_m2m_streamoff(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, |
409 | enum v4l2_buf_type type) | 409 | enum v4l2_buf_type type) |
410 | { | 410 | { |
411 | struct vb2_queue *vq; | 411 | struct v4l2_m2m_dev *m2m_dev; |
412 | struct v4l2_m2m_queue_ctx *q_ctx; | ||
413 | unsigned long flags_job, flags; | ||
414 | int ret; | ||
412 | 415 | ||
413 | vq = v4l2_m2m_get_vq(m2m_ctx, type); | 416 | q_ctx = get_queue_ctx(m2m_ctx, type); |
414 | return vb2_streamoff(vq, type); | 417 | ret = vb2_streamoff(&q_ctx->q, type); |
418 | if (ret) | ||
419 | return ret; | ||
420 | |||
421 | m2m_dev = m2m_ctx->m2m_dev; | ||
422 | spin_lock_irqsave(&m2m_dev->job_spinlock, flags_job); | ||
423 | /* We should not be scheduled anymore, since we're dropping a queue. */ | ||
424 | INIT_LIST_HEAD(&m2m_ctx->queue); | ||
425 | m2m_ctx->job_flags = 0; | ||
426 | |||
427 | spin_lock_irqsave(&q_ctx->rdy_spinlock, flags); | ||
428 | /* Drop queue, since streamoff returns device to the same state as after | ||
429 | * calling reqbufs. */ | ||
430 | INIT_LIST_HEAD(&q_ctx->rdy_queue); | ||
431 | spin_unlock_irqrestore(&q_ctx->rdy_spinlock, flags); | ||
432 | |||
433 | if (m2m_dev->curr_ctx == m2m_ctx) { | ||
434 | m2m_dev->curr_ctx = NULL; | ||
435 | wake_up(&m2m_ctx->finished); | ||
436 | } | ||
437 | spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags_job); | ||
438 | |||
439 | return 0; | ||
415 | } | 440 | } |
416 | EXPORT_SYMBOL_GPL(v4l2_m2m_streamoff); | 441 | EXPORT_SYMBOL_GPL(v4l2_m2m_streamoff); |
417 | 442 | ||