if (intr)
ret = wait_event_interruptible(vb->done, is_state_active_or_queued(q, vb));
else
- wait_event(vb->done, is_state_active_or_queued(q, vb));
+ wait_event(vb->done, is_state_active_or_queued(q, vb));
/* Relock */
if (is_ext_locked)
- mutex_lock(q->ext_lock);
-
+ mutex_lock(q->ext_lock);
+
return ret;
}
EXPORT_SYMBOL_GPL(videobuf_waiton);
static int stream_next_buffer_check_queue(struct videobuf_queue *q, int noblock)
{
int retval;
+ bool is_ext_locked;
checks:
if (!q->streaming) {
} else {
dprintk(2, "next_buffer: waiting on buffer\n");
- /* Drop lock to avoid deadlock with qbuf */
- videobuf_queue_unlock(q);
-
+ /* Drop lock to avoid deadlock with qbuf */
+ videobuf_queue_unlock(q);
+ /*ddl@rock-chips.com */
+ is_ext_locked = q->ext_lock && mutex_is_locked(q->ext_lock);
+
+ /* Release vdev lock to prevent this wait from blocking outside access to
+ the device. */
+ if (is_ext_locked)
+ mutex_unlock(q->ext_lock);
+
+
/* Checking list_empty and streaming is safe without
* locks because we goto checks to validate while
* holding locks before proceeding */
retval = wait_event_interruptible(q->wait,
!list_empty(&q->stream) || !q->streaming);
- videobuf_queue_lock(q);
+ videobuf_queue_lock(q);
+ /*ddl@rock-chips.com */
+ if (is_ext_locked)
+ mutex_lock(q->ext_lock);
+
if (retval)
goto done;
MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS);
- memset(b, 0, sizeof(*b));
+ memset(b, 0, sizeof(*b));
videobuf_queue_lock(q);
retval = stream_next_buffer(q, &buf, nonblocking);