summaryrefslogtreecommitdiff
path: root/drivers/mailbox
diff options
context:
space:
mode:
authorAnson Huang <Anson.Huang@nxp.com>2020-04-23 16:52:40 +0800
committerAnson Huang <Anson.Huang@nxp.com>2020-04-24 09:53:34 +0800
commit05d03f6ef4da50f42669904bd640dea1268290dd (patch)
tree01c704797b0cd0543a25cab7595b21b99dff85e1 /drivers/mailbox
parent972cc03234a99d42cf28ecd1dc89b281096d6ff3 (diff)
MLK-23835 mailbox: imx: Only restore MU settings when context lost
During noirq suspend/resume, if MU context is NOT lost, such as freeze mode suspend, when resume, there could be 2 CPUs calling IPC, 1 CPU is in charge of handling wakeup event, the other CPU is busy with device resume flow, the MU TIE could be set during IPC called by the CPU handling wakeup event, then the noirq resume callback in mailbox will be called by the CPU executing device resume, it could overwrite the MU settings and clear TIE by mistake, then cause the TX never finish and IPC mutex lock never released, and system will freeze, all CPUs are in idle and never wake up. To avoid this issue, we should ONLY restore the MU settings when its context is lost. Signed-off-by: Anson Huang <Anson.Huang@nxp.com> Reported-by: Clark Wang <xiaoning.wang@nxp.com> Reviewed-by: Jacky Bai <ping.bai@nxp.com>
Diffstat (limited to 'drivers/mailbox')
-rw-r--r--drivers/mailbox/imx-mailbox.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/drivers/mailbox/imx-mailbox.c b/drivers/mailbox/imx-mailbox.c
index c711165e3207..2a8c3e8aefb5 100644
--- a/drivers/mailbox/imx-mailbox.c
+++ b/drivers/mailbox/imx-mailbox.c
@@ -628,7 +628,16 @@ static int imx_mu_resume_noirq(struct device *dev)
{
struct imx_mu_priv *priv = dev_get_drvdata(dev);
- imx_mu_write(priv, priv->xcr, priv->dcfg->xCR);
+ /*
+ * ONLY restore MU when context lost, the TIE could
+ * be set during noirq resume as there is MU data
+ * communication going on, and restore the saved
+ * value will overwrite the TIE and cause MU data
+ * send failed, may lead to system freeze. This issue
+ * is observed by testing freeze mode suspend.
+ */
+ if (!imx_mu_read(priv, priv->dcfg->xCR))
+ imx_mu_write(priv, priv->xcr, priv->dcfg->xCR);
return 0;
}