{
struct rkisp1_params *params = vq->drv_priv;
struct rkisp1_buffer *buf;
+ struct list_head tmp_list;
unsigned long flags;
- unsigned int i;
- /* stop params input firstly */
+ INIT_LIST_HEAD(&tmp_list);
+
+ /*
+ * we first move the buffers into a local list 'tmp_list'
+ * and then we can iterate it and call vb2_buffer_done
+ * without holding the lock
+ */
spin_lock_irqsave(¶ms->config_lock, flags);
params->is_streaming = false;
+ list_cut_position(&tmp_list, ¶ms->params, params->params.prev);
spin_unlock_irqrestore(¶ms->config_lock, flags);
- for (i = 0; i < RKISP1_ISP_PARAMS_REQ_BUFS_MAX; i++) {
- spin_lock_irqsave(¶ms->config_lock, flags);
- if (!list_empty(¶ms->params)) {
- buf = list_first_entry(¶ms->params,
- struct rkisp1_buffer, queue);
- list_del(&buf->queue);
- spin_unlock_irqrestore(¶ms->config_lock,
- flags);
- } else {
- spin_unlock_irqrestore(¶ms->config_lock,
- flags);
- break;
- }
-
- if (buf)
- vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
- buf = NULL;
- }
+ list_for_each_entry(buf, &tmp_list, queue)
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
}
static int