{
        struct vb2_buffer *src_buf;
        struct coda_buffer_meta *meta;
+       unsigned long flags;
        u32 start;
 
        if (ctx->bit_stream_param & CODA_BIT_STREAM_END_FLAG)
                                meta->start = start;
                                meta->end = ctx->bitstream_fifo.kfifo.in &
                                            ctx->bitstream_fifo.kfifo.mask;
+                               spin_lock_irqsave(&ctx->buffer_meta_lock,
+                                                 flags);
                                list_add_tail(&meta->list,
                                              &ctx->buffer_meta_list);
+                               ctx->num_metas++;
+                               spin_unlock_irqrestore(&ctx->buffer_meta_lock,
+                                                      flags);
 
                                trace_coda_bit_queue(ctx, src_buf, meta);
                        }
        struct coda_dev *dev = ctx->dev;
        struct coda_q_data *q_data_dst;
        struct coda_buffer_meta *meta;
+       unsigned long flags;
        u32 reg_addr, reg_stride;
 
        dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
                coda_write(dev, ctx->iram_info.axi_sram_use,
                                CODA7_REG_BIT_AXI_SRAM_USE);
 
+       spin_lock_irqsave(&ctx->buffer_meta_lock, flags);
        meta = list_first_entry_or_null(&ctx->buffer_meta_list,
                                        struct coda_buffer_meta, list);
 
                        kfifo_in(&ctx->bitstream_fifo, buf, pad);
                }
        }
+       spin_unlock_irqrestore(&ctx->buffer_meta_lock, flags);
 
        coda_kfifo_sync_to_device_full(ctx);
 
        struct vb2_buffer *dst_buf;
        struct coda_buffer_meta *meta;
        unsigned long payload;
+       unsigned long flags;
        int width, height;
        int decoded_idx;
        int display_idx;
        } else {
                val = coda_read(dev, CODA_RET_DEC_PIC_FRAME_NUM) - 1;
                val -= ctx->sequence_offset;
-               mutex_lock(&ctx->bitstream_mutex);
+               spin_lock_irqsave(&ctx->buffer_meta_lock, flags);
                if (!list_empty(&ctx->buffer_meta_list)) {
                        meta = list_first_entry(&ctx->buffer_meta_list,
                                              struct coda_buffer_meta, list);
                        list_del(&meta->list);
+                       ctx->num_metas--;
+                       spin_unlock_irqrestore(&ctx->buffer_meta_lock, flags);
                        /*
                         * Clamp counters to 16 bits for comparison, as the HW
                         * counter rolls over at this point for h.264. This
                        ctx->frame_metas[decoded_idx] = *meta;
                        kfree(meta);
                } else {
+                       spin_unlock_irqrestore(&ctx->buffer_meta_lock, flags);
                        v4l2_err(&dev->v4l2_dev, "empty timestamp list!\n");
                        memset(&ctx->frame_metas[decoded_idx], 0,
                               sizeof(struct coda_buffer_meta));
                        ctx->frame_metas[decoded_idx].sequence = val;
                        ctx->sequence_offset++;
                }
-               mutex_unlock(&ctx->bitstream_mutex);
 
                trace_coda_dec_pic_done(ctx, &ctx->frame_metas[decoded_idx]);
 
 
        }
 
        if (ctx->inst_type == CODA_INST_DECODER && ctx->use_bit) {
-               struct list_head *meta;
-               bool stream_end;
-               int num_metas;
+               bool stream_end = ctx->bit_stream_param &
+                                 CODA_BIT_STREAM_END_FLAG;
+               int num_metas = ctx->num_metas;
 
                if (ctx->hold && !src_bufs) {
                        v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
                        return 0;
                }
 
-               stream_end = ctx->bit_stream_param &
-                            CODA_BIT_STREAM_END_FLAG;
-
-               num_metas = 0;
-               list_for_each(meta, &ctx->buffer_meta_list)
-                       num_metas++;
-
                if (!stream_end && (num_metas + src_bufs) < 2) {
                        v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
                                 "%d: not ready: need 2 buffers available (%d, %d)\n",
 
        v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
                        "job ready\n");
+
        return 1;
 }
 
        struct coda_ctx *ctx = vb2_get_drv_priv(q);
        struct coda_dev *dev = ctx->dev;
        struct vb2_buffer *buf;
+       unsigned long flags;
        bool stop;
 
        stop = ctx->streamon_out && ctx->streamon_cap;
                        queue_work(dev->workqueue, &ctx->seq_end_work);
                        flush_work(&ctx->seq_end_work);
                }
-               mutex_lock(&ctx->bitstream_mutex);
+               spin_lock_irqsave(&ctx->buffer_meta_lock, flags);
                while (!list_empty(&ctx->buffer_meta_list)) {
                        meta = list_first_entry(&ctx->buffer_meta_list,
                                                struct coda_buffer_meta, list);
                        list_del(&meta->list);
                        kfree(meta);
                }
-               mutex_unlock(&ctx->bitstream_mutex);
+               ctx->num_metas = 0;
+               spin_unlock_irqrestore(&ctx->buffer_meta_lock, flags);
                kfifo_init(&ctx->bitstream_fifo,
                        ctx->bitstream.vaddr, ctx->bitstream.size);
                ctx->runcounter = 0;
        mutex_init(&ctx->bitstream_mutex);
        mutex_init(&ctx->buffer_mutex);
        INIT_LIST_HEAD(&ctx->buffer_meta_list);
+       spin_lock_init(&ctx->buffer_meta_lock);
 
        coda_lock(ctx);
        list_add(&ctx->list, &dev->instances);