summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2015-07-02 19:41:30 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2015-07-02 19:41:30 -0700
commit9b803d0e4a10e1be55ac6ac98bf9ee3ed8a7eabc (patch)
tree980c1ec97915148a1f537a96203bf0f8c8998f54
parentfa97519c7b0cbab6bcc7364a01be0577632a5a81 (diff)
parent8ebc3954f33f41a1493969295893ec466efc0319 (diff)
downloadqcom-9b803d0e4a10e1be55ac6ac98bf9ee3ed8a7eabc.tar.gz
Merge "mdss: dsi: Fix potential race conditions in mdp busy wait"
-rw-r--r--drivers/video/msm/mdss/mdss_dsi_host.c30
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);
}