diff --git a/drivers/video/fbdev/msm/mdss_fb.c b/drivers/video/fbdev/msm/mdss_fb.c index d3e0a883fc4c..ff70c94d7d1c 100644 --- a/drivers/video/fbdev/msm/mdss_fb.c +++ b/drivers/video/fbdev/msm/mdss_fb.c @@ -166,13 +166,31 @@ static int mdss_fb_notify_update(struct msm_fb_data_type *mfd, if (notify > NOTIFY_UPDATE_POWER_OFF) return -EINVAL; - if (mfd->update.is_suspend) { + if (notify == NOTIFY_UPDATE_INIT) { + mutex_lock(&mfd->update.lock); + mfd->update.init_done = true; + mutex_unlock(&mfd->update.lock); + ret = 1; + } else if (notify == NOTIFY_UPDATE_DEINIT) { + mutex_lock(&mfd->update.lock); + mfd->update.init_done = false; + mutex_unlock(&mfd->update.lock); + complete(&mfd->update.comp); + complete(&mfd->no_update.comp); + ret = 1; + } else if (mfd->update.is_suspend) { to_user = NOTIFY_TYPE_SUSPEND; mfd->update.is_suspend = 0; ret = 1; } else if (notify == NOTIFY_UPDATE_START) { - reinit_completion(&mfd->update.comp); mutex_lock(&mfd->update.lock); + if (mfd->update.init_done) + reinit_completion(&mfd->update.comp); + else { + mutex_unlock(&mfd->update.lock); + pr_err("notify update start called without init\n"); + return -EINVAL; + } mfd->update.ref_count++; mutex_unlock(&mfd->update.lock); ret = wait_for_completion_interruptible_timeout( @@ -186,8 +204,14 @@ static int mdss_fb_notify_update(struct msm_fb_data_type *mfd, ret = 1; } } else if (notify == NOTIFY_UPDATE_STOP) { - reinit_completion(&mfd->no_update.comp); - mutex_lock(&mfd->no_update.lock); + mutex_lock(&mfd->update.lock); + if (mfd->update.init_done) + reinit_completion(&mfd->no_update.comp); + else { + mutex_unlock(&mfd->update.lock); + pr_err("notify update stop called without init\n"); + return -EINVAL; + } mfd->no_update.ref_count++; mutex_unlock(&mfd->no_update.lock); ret = wait_for_completion_interruptible_timeout( @@ -2059,6 +2083,7 @@ static int mdss_fb_register(struct msm_fb_data_type *mfd) mfd->no_update.timer.data = (unsigned long)mfd; mfd->update.ref_count = 0; mfd->no_update.ref_count = 0; + mfd->update.init_done = false; init_completion(&mfd->update.comp); init_completion(&mfd->no_update.comp); init_completion(&mfd->power_off_comp); diff --git a/drivers/video/fbdev/msm/mdss_fb.h b/drivers/video/fbdev/msm/mdss_fb.h index 83be3ccf4c1f..15f29d1cf540 100644 --- a/drivers/video/fbdev/msm/mdss_fb.h +++ b/drivers/video/fbdev/msm/mdss_fb.h @@ -132,6 +132,7 @@ struct disp_info_notify { int value; int is_suspend; int ref_count; + bool init_done; }; struct msm_sync_pt_data { diff --git a/include/uapi/linux/msm_mdp.h b/include/uapi/linux/msm_mdp.h index 92872461a733..1f131a3c1adb 100644 --- a/include/uapi/linux/msm_mdp.h +++ b/include/uapi/linux/msm_mdp.h @@ -110,6 +110,8 @@ #define MDSS_MDP_HW_REV_200 MDSS_MDP_REV(2, 0, 0) /* 8092 v1.0 */ enum { + NOTIFY_UPDATE_INIT, + NOTIFY_UPDATE_DEINIT, NOTIFY_UPDATE_START, NOTIFY_UPDATE_STOP, NOTIFY_UPDATE_POWER_OFF,