From 1f137a2c70474b34989047d0aff165483adc81a1 Mon Sep 17 00:00:00 2001 From: Krishna Chaitanya Parimi Date: Tue, 10 Feb 2015 23:37:05 -0800 Subject: [PATCH] msm: mdss: add init and deinit calls to notify update ioctl Adding notify update init and notify update deinit calls which ought to be called when the notify update thread is being started and exited in userspace. The need for these is to ensure that during exit sequence of the notify update thread there is minimal wait due to ioctl being blocked in driver. The wait completions will not be reset if deinit has been called and will need an init call for them to start working. So when we are exiting the notify update thread, any block that might happen due to either a concurrent or a later notify update call is now handled properly so that the block is either returned early or is not allowed respectively. Change-Id: I8212bf058285f5929ebc85d41d6bb12b50e388d9 Signed-off-by: Krishna Chaitanya Parimi --- drivers/video/fbdev/msm/mdss_fb.c | 33 +++++++++++++++++++++++++++---- drivers/video/fbdev/msm/mdss_fb.h | 1 + include/uapi/linux/msm_mdp.h | 2 ++ 3 files changed, 32 insertions(+), 4 deletions(-) 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,