Skip to content

Commit b5ef179

Browse files
MrVanJassi Brar
authored andcommitted
mailbox: imx: fix TXDB_V2 channel race condition
Two TXDB_V2 channels are used between Linux and System Manager(SM). Channel0 for normal TX, Channel 1 for notification completion. The TXDB_V2 trigger logic is using imx_mu_xcr_rmw which uses read/modify/update logic. Note: clear MUB GSR BITs, the MUA side GCR BITs will also got cleared per hardware design. Channel0 Linux read GCR->modify GCR->write GCR->M33 SM->read GSR----->clear GSR |-(1)-| Channel1 Linux start in time slot(1) read GCR->modify GCR->write GCR->M33 SM->read GSR->clear GSR So Channel1 read GCR will read back the GCR that Channel0 wrote, because M33 has not finish clear GSR, this means Channel1 GCR writing will trigger Channel1 and Channel0 interrupt both which is wrong. Channel0 will be freed(SCMI channel status set to FREE) in M33 SM when processing the 1st Channel0 interrupt. So when 2nd interrupt trigger (channel 0/1 trigger together), SM will see a freed Channel0, and report protocol error. To address the issue, not using read/modify/update logic, just use write, because write 0 to GCR will be ignored. And after write MUA GCR, wait the SM to clear MUB GSR by looping MUA GCR value. Fixes: 5bfe406 ("mailbox: imx: support channel type tx doorbell v2") Reviewed-by: Ranjani Vaidyanathan <[email protected]> Signed-off-by: Peng Fan <[email protected]> Signed-off-by: Jassi Brar <[email protected]>
1 parent 0a02bc0 commit b5ef179

File tree

1 file changed

+9
-1
lines changed

1 file changed

+9
-1
lines changed

drivers/mailbox/imx-mailbox.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,8 @@ static int imx_mu_generic_tx(struct imx_mu_priv *priv,
225225
void *data)
226226
{
227227
u32 *arg = data;
228+
u32 val;
229+
int ret;
228230

229231
switch (cp->type) {
230232
case IMX_MU_TYPE_TX:
@@ -236,7 +238,13 @@ static int imx_mu_generic_tx(struct imx_mu_priv *priv,
236238
queue_work(system_bh_wq, &cp->txdb_work);
237239
break;
238240
case IMX_MU_TYPE_TXDB_V2:
239-
imx_mu_xcr_rmw(priv, IMX_MU_GCR, IMX_MU_xCR_GIRn(priv->dcfg->type, cp->idx), 0);
241+
imx_mu_write(priv, IMX_MU_xCR_GIRn(priv->dcfg->type, cp->idx),
242+
priv->dcfg->xCR[IMX_MU_GCR]);
243+
ret = readl_poll_timeout(priv->base + priv->dcfg->xCR[IMX_MU_GCR], val,
244+
!(val & IMX_MU_xCR_GIRn(priv->dcfg->type, cp->idx)),
245+
0, 1000);
246+
if (ret)
247+
dev_warn_ratelimited(priv->dev, "channel type: %d failure\n", cp->type);
240248
break;
241249
default:
242250
dev_warn_ratelimited(priv->dev, "Send data on wrong channel type: %d\n", cp->type);

0 commit comments

Comments
 (0)