diff options
author | Linux Build Service Account <lnxbuild@localhost> | 2015-07-02 19:41:30 -0700 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2015-07-02 19:41:30 -0700 |
commit | 9b803d0e4a10e1be55ac6ac98bf9ee3ed8a7eabc (patch) | |
tree | 980c1ec97915148a1f537a96203bf0f8c8998f54 | |
parent | fa97519c7b0cbab6bcc7364a01be0577632a5a81 (diff) | |
parent | 8ebc3954f33f41a1493969295893ec466efc0319 (diff) | |
download | qcom-9b803d0e4a10e1be55ac6ac98bf9ee3ed8a7eabc.tar.gz |
Merge "mdss: dsi: Fix potential race conditions in mdp busy wait"
-rw-r--r-- | drivers/video/msm/mdss/mdss_dsi_host.c | 30 |
1 files changed, 17 insertions, 13 deletions
diff --git a/drivers/video/msm/mdss/mdss_dsi_host.c b/drivers/video/msm/mdss/mdss_dsi_host.c index 79d2cd2b088..1c78963893e 100644 --- a/drivers/video/msm/mdss/mdss_dsi_host.c +++ b/drivers/video/msm/mdss/mdss_dsi_host.c @@ -584,7 +584,7 @@ release: if (term == DSI_MDP_TERM) { spin_lock_irqsave(&ctrl->mdp_lock, flags); ctrl->mdp_busy = false; - complete(&ctrl->mdp_comp); + complete_all(&ctrl->mdp_comp); spin_unlock_irqrestore(&ctrl->mdp_lock, flags); } pr_debug("%s: ndx=%d, cnt=%d\n", __func__, @@ -1869,10 +1869,10 @@ int mdss_dsi_cmd_mdp_busy(struct mdss_dsi_ctrl_pdata *ctrl) { unsigned long flags; int need_wait = 0; - int rc = 0; + int rc = 1; - pr_debug("%s: start pid=%d\n", - __func__, current->pid); + pr_debug("%s: %d start busy=%d pid=%d\n", __func__, + ctrl->ndx, ctrl->mdp_busy, current->pid); MDSS_XLOG(ctrl->ndx, ctrl->mdp_busy, current->pid, XLOG_FUNC_ENTRY); spin_lock_irqsave(&ctrl->mdp_lock, flags); @@ -1882,19 +1882,23 @@ int mdss_dsi_cmd_mdp_busy(struct mdss_dsi_ctrl_pdata *ctrl) if (need_wait) { /* wait until DMA finishes the current job */ - pr_debug("%s: pending pid=%d\n", - __func__, current->pid); - if (!wait_for_completion_timeout(&ctrl->mdp_comp, - msecs_to_jiffies(DMA_TX_TIMEOUT))) { + rc = wait_for_completion_timeout(&ctrl->mdp_comp, + msecs_to_jiffies(DMA_TX_TIMEOUT)); + spin_lock_irqsave(&ctrl->mdp_lock, flags); + if (!ctrl->mdp_busy) + rc = 1; + spin_unlock_irqrestore(&ctrl->mdp_lock, flags); + if (!rc) { pr_err("%s: timeout error\n", __func__); MDSS_XLOG_TOUT_HANDLER("mdp", "dsi0", "dsi1", "edp", "hdmi", "panic"); - rc = -ETIMEDOUT; } } - pr_debug("%s: done pid=%d\n", __func__, current->pid); + + pr_debug("%s: %d done pid=%d\n", __func__, ctrl->ndx, current->pid); MDSS_XLOG(ctrl->ndx, ctrl->mdp_busy, current->pid, XLOG_FUNC_EXIT); - return rc; + + return !rc ? -ETIMEDOUT : 0; } int mdss_dsi_cmdlist_tx(struct mdss_dsi_ctrl_pdata *ctrl, @@ -2177,7 +2181,7 @@ static int dsi_event_thread(void *data) spin_lock_irqsave(&ctrl->mdp_lock, flag); ctrl->mdp_busy = false; mdss_dsi_disable_irq_nosync(ctrl, DSI_MDP_TERM); - complete(&ctrl->mdp_comp); + complete_all(&ctrl->mdp_comp); spin_unlock_irqrestore(&ctrl->mdp_lock, flag); /* enable dsi error interrupt */ @@ -2374,7 +2378,7 @@ irqreturn_t mdss_dsi_isr(int irq, void *ptr) DSI_MDP_TERM); } else { ctrl->mdp_busy = false; - complete(&ctrl->mdp_comp); + complete_all(&ctrl->mdp_comp); } spin_unlock(&ctrl->mdp_lock); } |