msm: wfd: Avoid exiting mdp task thread on error.
Sometimes during suspend resume, the mdp task thread fails to dequeue buffer and errors out and exits. Later when kthread_stop is called on mdp task, the device crashes in kthread_stop because the mdp task thread is invalid. Change-Id: I42aee61b82c97c378c8497ea70eb53b3eeb24191 CRs-fixed: 394139 Signed-off-by: Gopikrishnaiah Anandan <agopik@codeaurora.org> Signed-off-by: Arun Menon <menon@codeaurora.org> Signed-off-by: Neha Pandey <nehap@codeaurora.org>
This commit is contained in:
committed by
Stephen Boyd
parent
5a2080e1a3
commit
8367fb6c84
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user