From ba55276d8c58e1992b42b554bbb31357955cde05 Mon Sep 17 00:00:00 2001 From: Vinu Deokaran Date: Thu, 13 Aug 2015 09:55:23 -0700 Subject: msm: mdss: mdp: fix to prevent early wake up if panel is off Current code request the power transition during the early wake up event even if the panel is off. This is can cause problems due ctl is not valid at this time or in some other race conditions it prevents the bandwidth requests. This fix prevents that early wake up is called during power off, fixing the null pointer dereferences and mdp busy timouts errors. Change-Id: Idc51d02aa34d794a38f6e3a82ae80d5afa3d58f4 Signed-off-by: Vinu Deokaran Signed-off-by: Ingrid Gallardo --- drivers/video/fbdev/msm/mdss_fb.c | 2 +- drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c | 12 ++++++++---- drivers/video/fbdev/msm/mdss_mdp_overlay.c | 3 ++- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/drivers/video/fbdev/msm/mdss_fb.c b/drivers/video/fbdev/msm/mdss_fb.c index ec4962b53ea0..e2c9648635d6 100644 --- a/drivers/video/fbdev/msm/mdss_fb.c +++ b/drivers/video/fbdev/msm/mdss_fb.c @@ -808,7 +808,7 @@ static void mdss_fb_input_event_handler(struct input_handle *handle, struct msm_fb_data_type *mfd = handle->handler->private; int rc; - if (type != EV_ABS) + if ((type != EV_ABS) || !mdss_fb_is_power_on(mfd)) return; if (mfd->mdp.input_event_handler) { diff --git a/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c b/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c index 14ebd4abb817..04d61ed472e3 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c +++ b/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c @@ -690,6 +690,12 @@ int mdss_mdp_resource_control(struct mdss_mdp_ctl *ctl, u32 sw_event) * 3. If the current state is POWER-OFF, Schedule a work item to * POWER-ON. */ + + /* if panels are off, do not process early wake up */ + if ((ctx && __mdss_mdp_cmd_is_panel_power_off(ctx)) || + (sctx && __mdss_mdp_cmd_is_panel_power_off(sctx))) + break; + mutex_lock(&ctl->rsrc_lock); if (mdp5_data->resources_state != MDP_RSRC_CTL_STATE_OFF) { if (cancel_work_sync(&ctx->gate_clk_work)) @@ -741,9 +747,6 @@ static inline void mdss_mdp_cmd_clk_on(struct mdss_mdp_cmd_ctx *ctx) { struct mdss_data_type *mdata = mdss_mdp_get_mdata(); - if (__mdss_mdp_cmd_is_panel_power_off(ctx)) - return; - mutex_lock(&ctx->clk_mtx); MDSS_XLOG(ctx->pp_num, atomic_read(&ctx->koff_cnt)); @@ -2005,7 +2008,8 @@ static int mdss_mdp_cmd_early_wake_up(struct mdss_mdp_ctl *ctl) * involves cancelling queued work items. So this will be * scheduled in a work item. */ - schedule_work(&ctx->early_wakeup_clk_work); + if (ctx) + schedule_work(&ctx->early_wakeup_clk_work); return 0; } diff --git a/drivers/video/fbdev/msm/mdss_mdp_overlay.c b/drivers/video/fbdev/msm/mdss_mdp_overlay.c index c39429a4a7df..4c555fd3986c 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_overlay.c +++ b/drivers/video/fbdev/msm/mdss_mdp_overlay.c @@ -4909,7 +4909,8 @@ int mdss_mdp_input_event_handler(struct msm_fb_data_type *mfd) int rc = 0; struct mdss_mdp_ctl *ctl = mfd_to_ctl(mfd); - if (ctl->ops.early_wake_up_fnc) + if (ctl && mdss_panel_is_power_on(ctl->power_state) && + ctl->ops.early_wake_up_fnc) rc = ctl->ops.early_wake_up_fnc(ctl); return rc; -- cgit v1.2.3