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:
Gopikrishnaiah Anandan
2012-09-19 16:07:03 -04:00
committed by Stephen Boyd
parent 5a2080e1a3
commit 8367fb6c84

View File

@@ -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);