diff --git a/drivers/media/video/msm_wfd/wfd-ioctl.c b/drivers/media/video/msm_wfd/wfd-ioctl.c index d3c5936a073..e016b02071c 100644 --- a/drivers/media/video/msm_wfd/wfd-ioctl.c +++ b/drivers/media/video/msm_wfd/wfd-ioctl.c @@ -91,6 +91,7 @@ struct wfd_inst { u32 out_buf_size; struct list_head input_mem_list; struct wfd_stats stats; + struct completion stop_mdp_thread; }; struct wfd_vid_buffer { @@ -522,7 +523,7 @@ void wfd_vidbuf_buf_cleanup(struct vb2_buffer *vb) static int mdp_output_thread(void *data) { - int rc = 0; + int rc = 0, no_sig_wait = 0; struct file *filp = (struct file *)data; struct wfd_inst *inst = filp->private_data; struct wfd_device *wfd_dev = @@ -531,6 +532,14 @@ static int mdp_output_thread(void *data) struct mem_region *mregion; struct vsg_buf_info ibuf_vsg; while (!kthread_should_stop()) { + if (rc) { + WFD_MSG_DBG("%s() error in output thread\n", __func__); + if (!no_sig_wait) { + wait_for_completion(&inst->stop_mdp_thread); + no_sig_wait = 1; + } + continue; + } WFD_MSG_DBG("waiting for mdp output\n"); rc = v4l2_subdev_call(&wfd_dev->mdp_sdev, core, ioctl, MDP_DQ_BUFFER, (void *)&obuf_mdp); @@ -540,7 +549,7 @@ static int mdp_output_thread(void *data) WFD_MSG_ERR("MDP reported err %d\n", rc); WFD_MSG_ERR("Streamoff called\n"); - break; + continue; } else { wfd_stats_update(&inst->stats, WFD_STAT_EVENT_MDP_DEQUEUE); @@ -550,7 +559,7 @@ static int mdp_output_thread(void *data) if (!mregion) { WFD_MSG_ERR("mdp cookie is null\n"); rc = -EINVAL; - break; + continue; } ibuf_vsg.mdp_buf_info = obuf_mdp; @@ -565,7 +574,7 @@ static int mdp_output_thread(void *data) if (rc) { WFD_MSG_ERR("Failed to queue frame to vsg\n"); - break; + continue; } else { wfd_stats_update(&inst->stats, WFD_STAT_EVENT_VSG_QUEUE); @@ -599,7 +608,7 @@ int wfd_vidbuf_start_streaming(struct vb2_queue *q, unsigned int count) WFD_MSG_ERR("Failed to start vsg\n"); goto subdev_start_fail; } - + init_completion(&inst->stop_mdp_thread); inst->mdp_task = kthread_run(mdp_output_thread, priv_data, "mdp_output_thread"); if (IS_ERR(inst->mdp_task)) { @@ -634,6 +643,7 @@ int wfd_vidbuf_stop_streaming(struct vb2_queue *q) if (rc) WFD_MSG_ERR("Failed to stop VSG\n"); + complete(&inst->stop_mdp_thread); kthread_stop(inst->mdp_task); rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core, ioctl, ENCODE_FLUSH, (void *)inst->venc_inst);