diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/avs/avs.c b/drivers/amlogic/media_modules/frame_provider/decoder/avs/avs.c index 810d5bcaf36a..4277153d00ff 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/avs/avs.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/avs/avs.c @@ -780,7 +780,7 @@ static void vavs_vf_put(struct vframe_s *vf, void *op_arg) int vavs_dec_status(struct vdec_s *vdec, struct vdec_info *vstatus) { if (!(stat & STAT_VDEC_RUN)) - return 0; + return -1; vstatus->frame_width = frame_width; vstatus->frame_height = frame_height; @@ -1661,7 +1661,7 @@ static int amvdec_avs_probe(struct platform_device *pdev) pr_info("amvdec_avs init failed.\n"); kfree(gvs); gvs = NULL; - + pdata->dec_status = NULL; return -ENODEV; } vdec = pdata; diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/avs2/vavs2.c b/drivers/amlogic/media_modules/frame_provider/decoder/avs2/vavs2.c index 612aafd27609..cc2a42c202b4 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/avs2/vavs2.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/avs2/vavs2.c @@ -5444,7 +5444,7 @@ int vavs2_dec_status(struct vdec_s *vdec, struct vdec_info *vstatus) struct AVS2Decoder_s *dec = (struct AVS2Decoder_s *)vdec->private; - if (!dec || !(dec->stat & STAT_VDEC_RUN)) + if (!dec) return -1; vstatus->frame_width = dec->frame_width; @@ -5888,6 +5888,7 @@ static int amvdec_avs2_probe(struct platform_device *pdev) pr_info("\namvdec_avs2 init failed.\n"); avs2_local_uninit(dec); uninit_mmu_buffers(dec); + pdata->dec_status = NULL; mutex_unlock(&vavs2_mutex); return -ENODEV; } @@ -6688,6 +6689,7 @@ static int ammvdec_avs2_probe(struct platform_device *pdev) uninit_mmu_buffers(dec); /* devm_kfree(&pdev->dev, (void *)dec); */ vfree((void *)dec); + pdata->dec_status = NULL; return -ENODEV; } vdec_set_prepare_level(pdata, start_decode_buf_level); diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/h264/vh264.c b/drivers/amlogic/media_modules/frame_provider/decoder/h264/vh264.c index 274cfbb6851e..bc494654ea1f 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/h264/vh264.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/h264/vh264.c @@ -3059,6 +3059,7 @@ static int amvdec_h264_probe(struct platform_device *pdev) pr_info("\namvdec_h264 init failed.\n"); kfree(gvs); gvs = NULL; + pdata->dec_status = NULL; mutex_unlock(&vh264_mutex); return -ENODEV; } diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/h264_multi/vmh264.c b/drivers/amlogic/media_modules/frame_provider/decoder/h264_multi/vmh264.c index 13d6cae87959..2092b360f792 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/h264_multi/vmh264.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/h264_multi/vmh264.c @@ -5238,7 +5238,7 @@ static int dec_status(struct vdec_s *vdec, struct vdec_info *vstatus) { struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private; - if (!hw || !(hw->stat & STAT_VDEC_RUN)) + if (!hw) return -1; vstatus->frame_width = hw->frame_width; @@ -7381,6 +7381,7 @@ static int ammvdec_h264_probe(struct platform_device *pdev) if (decoder_bmmu_box_alloc_buf_phy(hw->bmmu_box, BMMU_DPB_IDX, V_BUF_ADDR_OFFSET, DRIVER_NAME, &hw->cma_alloc_addr) < 0) { h264_free_hw_stru(&pdev->dev, (void *)hw); + pdata->dec_status = NULL; return -ENOMEM; } @@ -7393,6 +7394,7 @@ static int ammvdec_h264_probe(struct platform_device *pdev) if (decoder_bmmu_box_alloc_buf_phy(hw->bmmu_box, BMMU_EXTIF_IDX, extif_size, DRIVER_NAME, &hw->extif_addr) < 0) { h264_free_hw_stru(&pdev->dev, (void *)hw); + pdata->dec_status = NULL; return -ENOMEM; } } @@ -7464,6 +7466,7 @@ static int ammvdec_h264_probe(struct platform_device *pdev) pr_info("\nammvdec_h264 init failed.\n"); ammvdec_h264_mmu_release(hw); h264_free_hw_stru(&pdev->dev, (void *)hw); + pdata->dec_status = NULL; return -ENODEV; } #ifdef MH264_USERDATA_ENABLE diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/h265/vh265.c b/drivers/amlogic/media_modules/frame_provider/decoder/h265/vh265.c index c4595031ef4d..3cfabcb56207 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/h265/vh265.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/h265/vh265.c @@ -9078,7 +9078,7 @@ int vh265_dec_status(struct vdec_info *vstatus) #else struct hevc_state_s *hevc = gHevc; #endif - if (!hevc || !(hevc->stat & STAT_VDEC_RUN)) + if (!hevc) return -1; vstatus->frame_width = hevc->frame_width; @@ -10488,6 +10488,7 @@ static int amvdec_h265_probe(struct platform_device *pdev) hevc_local_uninit(hevc); uninit_mmu_buffers(hevc); vfree(hevc); + pdata->dec_status = NULL; mutex_unlock(&vh265_mutex); return -ENODEV; } @@ -10830,6 +10831,7 @@ static int ammvdec_h265_probe(struct platform_device *pdev) /* devm_kfree(&pdev->dev, (void *)hevc);*/ if (hevc) vfree((void *)hevc); + pdata->dec_status = NULL; return -EFAULT; } #if 0 @@ -10845,6 +10847,7 @@ static int ammvdec_h265_probe(struct platform_device *pdev) /* devm_kfree(&pdev->dev, (void *)hevc); */ if (hevc) vfree((void *)hevc); + pdata->dec_status = NULL; mutex_unlock(&vh265_mutex); return ret; } @@ -10887,6 +10890,7 @@ static int ammvdec_h265_probe(struct platform_device *pdev) /* devm_kfree(&pdev->dev, (void *)hevc); */ if (hevc) vfree((void *)hevc); + pdata->dec_status = NULL; return -ENODEV; } diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/mjpeg/vmjpeg.c b/drivers/amlogic/media_modules/frame_provider/decoder/mjpeg/vmjpeg.c index f3c7f68398a0..95bb2229bace 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/mjpeg/vmjpeg.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/mjpeg/vmjpeg.c @@ -844,6 +844,7 @@ static int amvdec_mjpeg_probe(struct platform_device *pdev) mutex_unlock(&vmjpeg_mutex); kfree(gvs); gvs = NULL; + pdata->dec_status = NULL; return -ENODEV; } diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/mjpeg/vmjpeg_multi.c b/drivers/amlogic/media_modules/frame_provider/decoder/mjpeg/vmjpeg_multi.c index 8b7f9fb5eecb..b914e139976b 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/mjpeg/vmjpeg_multi.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/mjpeg/vmjpeg_multi.c @@ -385,7 +385,7 @@ static int vmjpeg_dec_status(struct vdec_s *vdec, struct vdec_info *vstatus) { struct vdec_mjpeg_hw_s *hw = (struct vdec_mjpeg_hw_s *)vdec->private; - if (!hw || !(hw->stat & STAT_VDEC_RUN)) + if (!hw) return -1; vstatus->frame_width = hw->frame_width; @@ -1148,6 +1148,7 @@ static int ammvdec_mjpeg_probe(struct platform_device *pdev) if (vmjpeg_init(pdata) < 0) { pr_info("ammvdec_mjpeg init failed.\n"); devm_kfree(&pdev->dev, (void *)hw); + pdata->dec_status = NULL; return -ENODEV; } diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/mpeg12/vmpeg12.c b/drivers/amlogic/media_modules/frame_provider/decoder/mpeg12/vmpeg12.c index ee2078c20fe4..f758076c4232 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/mpeg12/vmpeg12.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/mpeg12/vmpeg12.c @@ -2057,7 +2057,7 @@ static int amvdec_mpeg12_probe(struct platform_device *pdev) amlog_level(LOG_LEVEL_ERROR, "amvdec_mpeg12 init failed.\n"); kfree(gvs); gvs = NULL; - + pdata->dec_status = NULL; return -ENODEV; } vdec = pdata; diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/mpeg12/vmpeg12_multi.c b/drivers/amlogic/media_modules/frame_provider/decoder/mpeg12/vmpeg12_multi.c index 1b110046b321..ea3449c726a2 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/mpeg12/vmpeg12_multi.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/mpeg12/vmpeg12_multi.c @@ -1085,7 +1085,7 @@ static int vmmpeg12_dec_status(struct vdec_s *vdec, struct vdec_info *vstatus) struct vdec_mpeg12_hw_s *hw = (struct vdec_mpeg12_hw_s *)vdec->private; - if (!hw || !(hw->stat & STAT_VDEC_RUN)) + if (!hw) return -1; vstatus->frame_width = hw->frame_width; @@ -1785,6 +1785,7 @@ static int ammvdec_mpeg12_probe(struct platform_device *pdev) if (vmpeg12_init(hw) < 0) { pr_info("ammvdec_mpeg12 init failed.\n"); devm_kfree(&pdev->dev, (void *)hw); + pdata->dec_status = NULL; return -ENODEV; } diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/mpeg4/vmpeg4.c b/drivers/amlogic/media_modules/frame_provider/decoder/mpeg4/vmpeg4.c index 7f638085f416..56351f7bcc2c 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/mpeg4/vmpeg4.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/mpeg4/vmpeg4.c @@ -1142,6 +1142,7 @@ static int amvdec_mpeg4_probe(struct platform_device *pdev) amlog_level(LOG_LEVEL_ERROR, "amvdec_mpeg4 init failed.\n"); kfree(gvs); gvs = NULL; + pdata->dec_status = NULL; return -ENODEV; } diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/mpeg4/vmpeg4_multi.c b/drivers/amlogic/media_modules/frame_provider/decoder/mpeg4/vmpeg4_multi.c index 4f62d601a284..965e5588e42e 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/mpeg4/vmpeg4_multi.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/mpeg4/vmpeg4_multi.c @@ -1040,7 +1040,7 @@ static int dec_status(struct vdec_s *vdec, struct vdec_info *vstatus) { struct vdec_mpeg4_hw_s *hw = (struct vdec_mpeg4_hw_s *)vdec->private; - if (!hw || !(hw->stat & STAT_VDEC_RUN)) + if (!hw) return -1; vstatus->frame_width = hw->vmpeg4_amstream_dec_info.width; @@ -1855,6 +1855,7 @@ static int ammvdec_mpeg4_probe(struct platform_device *pdev) vfree((void *)hw); hw = NULL; } + pdata->dec_status = NULL; return -ENODEV; } diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/real/vreal.c b/drivers/amlogic/media_modules/frame_provider/decoder/real/vreal.c index b6135cd993de..88911ec80cd0 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/real/vreal.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/real/vreal.c @@ -944,6 +944,7 @@ static int amvdec_real_probe(struct platform_device *pdev) if (vreal_init(pdata) < 0) { pr_info("amvdec_real init failed.\n"); + pdata->dec_status = NULL; return -ENODEV; } INIT_WORK(&set_clk_work, vreal_set_clk); diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/utils/vdec.c b/drivers/amlogic/media_modules/frame_provider/decoder/utils/vdec.c index be29c334b9ee..185c01a2d724 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/utils/vdec.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/utils/vdec.c @@ -227,10 +227,12 @@ static int get_canvas(unsigned int index, unsigned int base) int vdec_status(struct vdec_s *vdec, struct vdec_info *vstatus) { - if (vdec && vdec->dec_status) + if (vdec && vdec->dec_status && + ((vdec->status == VDEC_STATUS_CONNECTED || + vdec->status == VDEC_STATUS_ACTIVE))) return vdec->dec_status(vdec, vstatus); - return -1; + return 0; } EXPORT_SYMBOL(vdec_status); @@ -3617,7 +3619,8 @@ static ssize_t vdec_status_show(struct class *class, } list_for_each_entry(vdec, &core->connected_vdec_list, list) { - if (VDEC_STATUS_CONNECTED == vdec->status) { + if ((vdec->status == VDEC_STATUS_CONNECTED + || vdec->status == VDEC_STATUS_ACTIVE)) { memset(&vs, 0, sizeof(vs)); if (vdec_status(vdec, &vs)) { pbuf += sprintf(pbuf, "err.\n"); diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/vc1/vvc1.c b/drivers/amlogic/media_modules/frame_provider/decoder/vc1/vvc1.c index 687c78dd1972..4de5c3cb2758 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/vc1/vvc1.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/vc1/vvc1.c @@ -1150,6 +1150,7 @@ static int amvdec_vc1_probe(struct platform_device *pdev) pr_info("amvdec_vc1 init failed.\n"); kfree(gvs); gvs = NULL; + pdata->dec_status = NULL; return -ENODEV; } INIT_WORK(&set_clk_work, vvc1_set_clk); diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/vp9/vvp9.c b/drivers/amlogic/media_modules/frame_provider/decoder/vp9/vvp9.c index 835201d40038..8b371c724701 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/vp9/vvp9.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/vp9/vvp9.c @@ -7743,7 +7743,7 @@ int vvp9_dec_status(struct vdec_s *vdec, struct vdec_info *vstatus) struct VP9Decoder_s *vp9 = (struct VP9Decoder_s *)vdec->private; - if (!vp9 || !(vp9->stat & STAT_VDEC_RUN)) + if (!vp9) return -1; vstatus->frame_width = frame_width; @@ -8366,6 +8366,7 @@ static int amvdec_vp9_probe(struct platform_device *pdev) vp9_local_uninit(pbi); uninit_mmu_buffers(pbi); vfree(pbi); + pdata->dec_status = NULL; mutex_unlock(&vvp9_mutex); return -ENODEV; } @@ -9364,6 +9365,7 @@ static int ammvdec_vp9_probe(struct platform_device *pdev) pr_err("vp9 alloc bmmu box failed!!\n"); /* devm_kfree(&pdev->dev, (void *)pbi); */ vfree((void *)pbi); + pdata->dec_status = NULL; return -1; } @@ -9375,6 +9377,7 @@ static int ammvdec_vp9_probe(struct platform_device *pdev) uninit_mmu_buffers(pbi); /* devm_kfree(&pdev->dev, (void *)pbi); */ vfree((void *)pbi); + pdata->dec_status = NULL; return ret; } pbi->buf_start = pbi->cma_alloc_addr; @@ -9406,6 +9409,7 @@ static int ammvdec_vp9_probe(struct platform_device *pdev) uninit_mmu_buffers(pbi); /* devm_kfree(&pdev->dev, (void *)pbi); */ vfree((void *)pbi); + pdata->dec_status = NULL; return -ENODEV; } vdec_set_prepare_level(pdata, start_decode_buf_level); diff --git a/drivers/amlogic/media_modules/stream_input/amports/amports_priv.h b/drivers/amlogic/media_modules/stream_input/amports/amports_priv.h index c65368e295e8..7a4479113165 100644 --- a/drivers/amlogic/media_modules/stream_input/amports/amports_priv.h +++ b/drivers/amlogic/media_modules/stream_input/amports/amports_priv.h @@ -26,6 +26,7 @@ struct port_priv_s { struct vdec_s *vdec; struct stream_port_s *port; + struct mutex mutex; }; struct stream_buf_s *get_buf_by_type(u32 type); diff --git a/drivers/amlogic/media_modules/stream_input/amports/amstream.c b/drivers/amlogic/media_modules/stream_input/amports/amstream.c index 658451ccb11c..d6aeab4090b5 100644 --- a/drivers/amlogic/media_modules/stream_input/amports/amstream.c +++ b/drivers/amlogic/media_modules/stream_input/amports/amstream.c @@ -917,11 +917,14 @@ static int amstream_port_init(struct port_priv_s *priv) port->vformat == VFORMAT_VP9) pvbuf = &bufs[BUF_TYPE_HEVC]; } + mutex_lock(&priv->mutex); r = video_port_init(priv, pvbuf); if (r < 0) { + mutex_unlock(&priv->mutex); pr_err("video_port_init failed\n"); goto error2; } + mutex_unlock(&priv->mutex); } if ((port->type & PORT_TYPE_SUB) && (port->flag & PORT_FLAG_SID)) { @@ -1597,6 +1600,8 @@ static int amstream_open(struct inode *inode, struct file *file) return -ENOMEM; } + mutex_init(&priv->mutex); + priv->port = port; if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_M6) { @@ -1775,6 +1780,8 @@ static int amstream_release(struct inode *inode, struct file *file) amports_switch_gate("demux", 0); } + mutex_destroy(&priv->mutex); + kfree(priv); mutex_unlock(&amstream_mutex); @@ -2317,8 +2324,15 @@ static long amstream_ioctl_get_ex(struct port_priv_s *priv, ulong arg) struct vdec_info vstatus; struct am_ioctl_parm_ex *p = &parm; - if (vdec_status(priv->vdec, &vstatus) == -1) + memset(&vstatus, 0, sizeof(vstatus)); + + mutex_lock(&priv->mutex); + if (vdec_status(priv->vdec, &vstatus) == -1) { + mutex_unlock(&priv->mutex); return -ENODEV; + } + mutex_unlock(&priv->mutex); + p->vstatus.width = vstatus.frame_width; p->vstatus.height = vstatus.frame_height; p->vstatus.fps = vstatus.frame_rate; @@ -2790,13 +2804,21 @@ static long amstream_do_ioctl_old(struct port_priv_s *priv, struct am_io_param para; struct am_io_param *p = ¶ - if (vdec_status(priv->vdec, &vstatus) == -1) + memset(&vstatus, 0, sizeof(vstatus)); + + mutex_lock(&priv->mutex); + if (vdec_status(priv->vdec, &vstatus) == -1) { + mutex_unlock(&priv->mutex); return -ENODEV; + } + mutex_unlock(&priv->mutex); + p->vstatus.width = vstatus.frame_width; p->vstatus.height = vstatus.frame_height; p->vstatus.fps = vstatus.frame_rate; p->vstatus.error_count = vstatus.error_count; p->vstatus.status = vstatus.status; + if (copy_to_user((void *)arg, p, sizeof(para))) r = -EFAULT; return r; @@ -2810,8 +2832,14 @@ static long amstream_do_ioctl_old(struct port_priv_s *priv, struct am_io_info para; memset(¶, 0x0, sizeof(struct am_io_info)); - if (vdec_status(priv->vdec, &vinfo) == -1) + + mutex_lock(&priv->mutex); + if (vdec_status(priv->vdec, &vinfo) == -1) { + mutex_unlock(&priv->mutex); return -ENODEV; + } + mutex_unlock(&priv->mutex); + memcpy(¶.vinfo, &vinfo, sizeof(struct vdec_info)); if (copy_to_user((void *)arg, ¶, sizeof(para))) r = -EFAULT;