From c925367ef5295eaf2f77f658508e7a36ad50ab52 Mon Sep 17 00:00:00 2001 From: Benjamin Chan Date: Fri, 27 Jan 2017 11:46:50 -0500 Subject: [PATCH] msm: mdss: Skip ping pong wait when panel is reported dead When the panel is reported dead, UI framework will perform a stop and restart sequence in the FBdev driver. During the stop sequence, if there are still pending commit, driver will still wait for ping pong done. However, in the case of panel which is dead, waiting for ping pong done will lead to timeout and cause a panic. This change is to by pass the ping pong done waiting and perform cleanup to remove any pending commit status. CRs-Fixed: 1114278 Change-Id: Ia57a80379c0e33cedcbfdae011d11e4b8edf476d Signed-off-by: Benjamin Chan --- drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c | 32 ++++++++++++++------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c b/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c index b7f27b818eda..2a62ae5881b3 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c +++ b/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c @@ -2031,6 +2031,19 @@ static int __mdss_mdp_wait4pingpong(struct mdss_mdp_cmd_ctx *ctx) return rc; } +static void __clear_ping_pong_callback(struct mdss_mdp_ctl *ctl, + struct mdss_mdp_cmd_ctx *ctx) +{ + mdss_mdp_irq_disable_nosync(MDSS_MDP_IRQ_TYPE_PING_PONG_COMP, + ctx->current_pp_num); + mdss_mdp_set_intr_callback_nosync( + MDSS_MDP_IRQ_TYPE_PING_PONG_COMP, + ctx->current_pp_num, NULL, NULL); + if (atomic_add_unless(&ctx->koff_cnt, -1, 0) + && mdss_mdp_cmd_do_notifier(ctx)) + mdss_mdp_ctl_notify(ctl, MDP_NOTIFY_FRAME_TIMEOUT); +} + static int mdss_mdp_cmd_wait4pingpong(struct mdss_mdp_ctl *ctl, void *arg) { struct mdss_mdp_cmd_ctx *ctx; @@ -2047,7 +2060,7 @@ static int mdss_mdp_cmd_wait4pingpong(struct mdss_mdp_ctl *ctl, void *arg) pdata = ctl->panel_data; MDSS_XLOG(ctl->num, atomic_read(&ctx->koff_cnt), ctl->roi_bkup.w, - ctl->roi_bkup.h); + ctl->roi_bkup.h, pdata->panel_info.panel_dead); pr_debug("%s: intf_num=%d ctx=%pK koff_cnt=%d\n", __func__, ctl->intf_num, ctx, atomic_read(&ctx->koff_cnt)); @@ -2073,6 +2086,13 @@ static int mdss_mdp_cmd_wait4pingpong(struct mdss_mdp_ctl *ctl, void *arg) mdss_mdp_cmd_pingpong_done(ctl); local_irq_restore(flags); rc = 1; + } else if (pdata->panel_info.panel_dead) { + /* + * if panel is reported dead, no need to wait for + * pingpong done, and don't report timeout + */ + MDSS_XLOG(0xdead); + __clear_ping_pong_callback(ctl, ctx); } rc = atomic_read(&ctx->koff_cnt) == 0; @@ -2098,15 +2118,7 @@ static int mdss_mdp_cmd_wait4pingpong(struct mdss_mdp_ctl *ctl, void *arg) ctx->pp_timeout_report_cnt++; rc = -EPERM; - mdss_mdp_irq_disable_nosync(MDSS_MDP_IRQ_TYPE_PING_PONG_COMP, - ctx->current_pp_num); - mdss_mdp_set_intr_callback_nosync( - MDSS_MDP_IRQ_TYPE_PING_PONG_COMP, - ctx->current_pp_num, NULL, NULL); - if (atomic_add_unless(&ctx->koff_cnt, -1, 0) - && mdss_mdp_cmd_do_notifier(ctx)) - mdss_mdp_ctl_notify(ctl, MDP_NOTIFY_FRAME_TIMEOUT); - + __clear_ping_pong_callback(ctl, ctx); } else { rc = 0; ctx->pp_timeout_report_cnt = 0;