diff options
-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 | ||