summaryrefslogtreecommitdiff
path: root/drivers/media/platform/qcom/venus/vdec.c
diff options
context:
space:
mode:
authorStanimir Varbanov <stanimir.varbanov@linaro.org>2021-04-23 12:41:25 +0300
committerMauro Carvalho Chehab <mchehab+huawei@kernel.org>2021-10-21 16:23:15 +0300
commit3227a8f7cf331ed5be4b6c26339366b8d2d83b09 (patch)
treea6f6d36141b69c347723ab5f6fbb1dd439eb80b8 /drivers/media/platform/qcom/venus/vdec.c
parentaa6dcf171ab71910960f53ffcae3c8fa48928a85 (diff)
downloadlinux-3227a8f7cf331ed5be4b6c26339366b8d2d83b09.tar.xz
media: venus: Handle fatal errors during encoding and decoding
According to stateful decoder docs a fatal failure of decoding (and encoding) could be recover it by closing the corresponding file handle and open new one or reinitialize decoding (and encoding) by stop streaming on both queues. In order to satisfy this requirement we add a mechanism ins sys_error_handler and corresponding decoder and encoder drivers to wait for sys_error_done waitqueue in reqbuf. Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org> Tested-by: Vikash Garodia <vgarodia@codeaurora.org> Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
Diffstat (limited to 'drivers/media/platform/qcom/venus/vdec.c')
-rw-r--r--drivers/media/platform/qcom/venus/vdec.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/drivers/media/platform/qcom/venus/vdec.c b/drivers/media/platform/qcom/venus/vdec.c
index 11990a95d346..36e783eeafe9 100644
--- a/drivers/media/platform/qcom/venus/vdec.c
+++ b/drivers/media/platform/qcom/venus/vdec.c
@@ -846,6 +846,7 @@ static int vdec_queue_setup(struct vb2_queue *q,
unsigned int sizes[], struct device *alloc_devs[])
{
struct venus_inst *inst = vb2_get_drv_priv(q);
+ struct venus_core *core = inst->core;
unsigned int in_num, out_num;
int ret = 0;
@@ -871,6 +872,16 @@ static int vdec_queue_setup(struct vb2_queue *q,
return 0;
}
+ if (test_bit(0, &core->sys_error)) {
+ if (inst->nonblock)
+ return -EAGAIN;
+
+ ret = wait_event_interruptible(core->sys_err_done,
+ !test_bit(0, &core->sys_error));
+ if (ret)
+ return ret;
+ }
+
ret = vdec_pm_get(inst);
if (ret)
return ret;
@@ -1198,6 +1209,8 @@ static void vdec_stop_streaming(struct vb2_queue *q)
venus_helper_buffers_done(inst, q->type, VB2_BUF_STATE_ERROR);
+ inst->session_error = 0;
+
if (ret)
goto unlock;
@@ -1473,6 +1486,7 @@ static void vdec_event_notify(struct venus_inst *inst, u32 event,
switch (event) {
case EVT_SESSION_ERROR:
inst->session_error = true;
+ venus_helper_vb2_queue_error(inst);
dev_err(dev, "dec: event session error %x\n", inst->error);
break;
case EVT_SYS_EVENT_CHANGE:
@@ -1594,6 +1608,8 @@ static int vdec_open(struct file *file)
inst->bit_depth = VIDC_BITDEPTH_8;
inst->pic_struct = HFI_INTERLACE_FRAME_PROGRESSIVE;
init_waitqueue_head(&inst->reconf_wait);
+ inst->nonblock = file->f_flags & O_NONBLOCK;
+
venus_helper_init_instance(inst);
ret = vdec_ctrl_init(inst);