]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
media: chips-media: wave5: Fix a hang after seeking
authorJackson.lee <jackson.lee@chipsnmedia.com>
Tue, 17 Dec 2024 04:51:24 +0000 (13:51 +0900)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 20 Apr 2025 08:15:38 +0000 (10:15 +0200)
commit a2c75e964e51b096e9fe6adfa3eaed53594a668b upstream.

While seeking, the driver calls the flush command. Before the flush
command is sent to the VPU, the driver should handle the display buffer
flags and should get all decoded information from the VPU if the VCORE
is running.

Fixes: 9707a6254a8a ("media: chips-media: wave5: Add the v4l2 layer")
Cc: stable@vger.kernel.org
Signed-off-by: Jackson.lee <jackson.lee@chipsnmedia.com>
Signed-off-by: Nas Chung <nas.chung@chipsnmedia.com>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Signed-off-by: Sebastian Fricke <sebastian.fricke@collabora.com>
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c
drivers/media/platform/chips-media/wave5/wave5-vpuapi.c

index 0c5c9a8de91faa4cf67e594747fc9cdc2bd41db7..1ca14032f8b94f5b61fee21ef9111283215b56eb 100644 (file)
@@ -1446,6 +1446,16 @@ static int streamoff_output(struct vb2_queue *q)
        struct vb2_v4l2_buffer *buf;
        int ret;
        dma_addr_t new_rd_ptr;
+       struct dec_output_info dec_info;
+       unsigned int i;
+
+       for (i = 0; i < v4l2_m2m_num_dst_bufs_ready(m2m_ctx); i++) {
+               ret = wave5_vpu_dec_set_disp_flag(inst, i);
+               if (ret)
+                       dev_dbg(inst->dev->dev,
+                               "%s: Setting display flag of buf index: %u, fail: %d\n",
+                               __func__, i, ret);
+       }
 
        while ((buf = v4l2_m2m_src_buf_remove(m2m_ctx))) {
                dev_dbg(inst->dev->dev, "%s: (Multiplanar) buf type %4u | index %4u\n",
@@ -1453,6 +1463,11 @@ static int streamoff_output(struct vb2_queue *q)
                v4l2_m2m_buf_done(buf, VB2_BUF_STATE_ERROR);
        }
 
+       while (wave5_vpu_dec_get_output_info(inst, &dec_info) == 0) {
+               if (dec_info.index_frame_display >= 0)
+                       wave5_vpu_dec_set_disp_flag(inst, dec_info.index_frame_display);
+       }
+
        ret = wave5_vpu_flush_instance(inst);
        if (ret)
                return ret;
@@ -1535,7 +1550,7 @@ static void wave5_vpu_dec_stop_streaming(struct vb2_queue *q)
                        break;
 
                if (wave5_vpu_dec_get_output_info(inst, &dec_output_info))
-                       dev_dbg(inst->dev->dev, "Getting decoding results from fw, fail\n");
+                       dev_dbg(inst->dev->dev, "there is no output info\n");
        }
 
        v4l2_m2m_update_stop_streaming_state(m2m_ctx, q);
index 1a3efb638dde5a6b5116dcec5c3c03c7e16f493b..65fdabcd9d2921e0bf71ee57eff34883beda7a69 100644 (file)
@@ -73,6 +73,16 @@ int wave5_vpu_flush_instance(struct vpu_instance *inst)
                                 inst->type == VPU_INST_TYPE_DEC ? "DECODER" : "ENCODER", inst->id);
                        mutex_unlock(&inst->dev->hw_lock);
                        return -ETIMEDOUT;
+               } else if (ret == -EBUSY) {
+                       struct dec_output_info dec_info;
+
+                       mutex_unlock(&inst->dev->hw_lock);
+                       wave5_vpu_dec_get_output_info(inst, &dec_info);
+                       ret = mutex_lock_interruptible(&inst->dev->hw_lock);
+                       if (ret)
+                               return ret;
+                       if (dec_info.index_frame_display > 0)
+                               wave5_vpu_dec_set_disp_flag(inst, dec_info.index_frame_display);
                }
        } while (ret != 0);
        mutex_unlock(&inst->dev->hw_lock);