From f148bbf8effec3422a79d4178503222a9d35ecb5 Mon Sep 17 00:00:00 2001 From: Ingrid Gallardo Date: Thu, 15 Oct 2015 19:00:53 -0700 Subject: msm: mdss: fix off work item scheduling during early wakeup During the early wakeup event, current code cancel any pending Gate or Off work items pending and only schedules a delayed Off work if we are transitioning from OFF state. This is a problem since resources remain enabled when multiple early wakeup calls happen and the state is different than off. Fix this problem by making sure that early wakeup schedules an Off work item if any previous work was cancel by this call. Change-Id: I3c773221b53080443c62a0e7e09ed51ec43028a4 Signed-off-by: Ingrid Gallardo [cip@codeaurora.org: Resolved merge conflict] Signed-off-by: Clarence Ip --- drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c b/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c index a0799404c55f..47ef5be3ecdb 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c +++ b/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c @@ -460,6 +460,7 @@ int mdss_mdp_resource_control(struct mdss_mdp_ctl *ctl, u32 sw_event) struct dsi_panel_clk_ctrl clk_ctrl; u32 status; int rc = 0; + bool schedule_off = false; /* Get both controllers in the correct order for dual displays */ mdss_mdp_get_split_display_ctls(&ctl, &sctl); @@ -718,18 +719,23 @@ int mdss_mdp_resource_control(struct mdss_mdp_ctl *ctl, u32 sw_event) break; /* Cancel GATE Work Item */ - if (cancel_work_sync(&ctx->gate_clk_work)) + if (cancel_work_sync(&ctx->gate_clk_work)) { pr_debug("%s: %s - gate_work cancelled\n", __func__, get_sw_event_name(sw_event)); + schedule_off = true; + } /* Cancel OFF Work Item */ if (cancel_delayed_work_sync( - &ctx->delayed_off_clk_work)) + &ctx->delayed_off_clk_work)) { pr_debug("%s: %s - off work cancelled\n", __func__, get_sw_event_name(sw_event)); + schedule_off = true; + } mutex_lock(&ctl->rsrc_lock); - MDSS_XLOG(ctl->num, mdp5_data->resources_state, sw_event, 0x44); + MDSS_XLOG(ctl->num, mdp5_data->resources_state, sw_event, + schedule_off, 0x44); if (mdp5_data->resources_state == MDP_RSRC_CTL_STATE_OFF) { u32 flags = CTL_INTF_EVENT_FLAG_SKIP_BROADCAST; @@ -754,6 +760,16 @@ int mdss_mdp_resource_control(struct mdss_mdp_ctl *ctl, u32 sw_event) mdss_mdp_cmd_clk_on(sctx); mdp5_data->resources_state = MDP_RSRC_CTL_STATE_ON; + schedule_off = true; + } + + /* + * Driver will schedule off work under three cases: + * 1. Early wakeup cancelled the gate work. + * 2. Early wakeup cancelled the off work. + * 3. Early wakeup changed the state to ON. + */ + if (schedule_off) { /* * Schedule off work after cmd mode idle timeout is * reached. This is to prevent the case where early wake @@ -761,6 +777,7 @@ int mdss_mdp_resource_control(struct mdss_mdp_ctl *ctl, u32 sw_event) */ schedule_delayed_work(&ctx->delayed_off_clk_work, CMD_MODE_IDLE_TIMEOUT); + pr_debug("off work scheduled\n"); } mutex_unlock(&ctl->rsrc_lock); break; -- cgit v1.2.3