Skip to content

Commit 99b142c

Browse files
MrVanmathieupoirier
authored andcommitted
remoteproc: imx_rproc: Request mbox channel later
It is possible that when remote processor crash, the communication channel will be broken with garbage value in mailbox, such as when Linux is issuing a message through mailbox, remote processor crashes, we need free & rebuild the mailbox channels to make sure no garbage value in mailbox channels. So move the request/free to start/stop for managing remote procesosr in Linux, move to attach/detach for remote processor is out of control of Linux. Previous, we just request mbox when attach for CM4 boot early before Linux, but if mbox defer probe, remoteproc core will do resource cleanup and corrupt resource table for later probe. So move request mbox ealier and still keep mbox request when attach for self recovery case, but keep a check when request/free mbox. Signed-off-by: Peng Fan <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Mathieu Poirier <[email protected]>
1 parent fcd382b commit 99b142c

File tree

1 file changed

+46
-2
lines changed

1 file changed

+46
-2
lines changed

drivers/remoteproc/imx_rproc.c

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ struct imx_rproc_mem {
8484
#define ATT_CORE_MASK 0xffff
8585
#define ATT_CORE(I) BIT((I))
8686

87+
static int imx_rproc_xtr_mbox_init(struct rproc *rproc);
88+
static void imx_rproc_free_mbox(struct rproc *rproc);
8789
static int imx_rproc_detach_pd(struct rproc *rproc);
8890

8991
struct imx_rproc {
@@ -357,6 +359,10 @@ static int imx_rproc_start(struct rproc *rproc)
357359
struct arm_smccc_res res;
358360
int ret;
359361

362+
ret = imx_rproc_xtr_mbox_init(rproc);
363+
if (ret)
364+
return ret;
365+
360366
switch (dcfg->method) {
361367
case IMX_RPROC_MMIO:
362368
ret = regmap_update_bits(priv->regmap, dcfg->src_reg, dcfg->src_mask,
@@ -407,6 +413,8 @@ static int imx_rproc_stop(struct rproc *rproc)
407413

408414
if (ret)
409415
dev_err(dev, "Failed to stop remote core\n");
416+
else
417+
imx_rproc_free_mbox(rproc);
410418

411419
return ret;
412420
}
@@ -592,6 +600,22 @@ static void imx_rproc_kick(struct rproc *rproc, int vqid)
592600

593601
static int imx_rproc_attach(struct rproc *rproc)
594602
{
603+
return imx_rproc_xtr_mbox_init(rproc);
604+
}
605+
606+
static int imx_rproc_detach(struct rproc *rproc)
607+
{
608+
struct imx_rproc *priv = rproc->priv;
609+
const struct imx_rproc_dcfg *dcfg = priv->dcfg;
610+
611+
if (dcfg->method != IMX_RPROC_SCU_API)
612+
return -EOPNOTSUPP;
613+
614+
if (imx_sc_rm_is_resource_owned(priv->ipc_handle, priv->rsrc_id))
615+
return -EOPNOTSUPP;
616+
617+
imx_rproc_free_mbox(rproc);
618+
595619
return 0;
596620
}
597621

@@ -610,6 +634,7 @@ static struct resource_table *imx_rproc_get_loaded_rsc_table(struct rproc *rproc
610634
static const struct rproc_ops imx_rproc_ops = {
611635
.prepare = imx_rproc_prepare,
612636
.attach = imx_rproc_attach,
637+
.detach = imx_rproc_detach,
613638
.start = imx_rproc_start,
614639
.stop = imx_rproc_stop,
615640
.kick = imx_rproc_kick,
@@ -720,6 +745,18 @@ static int imx_rproc_xtr_mbox_init(struct rproc *rproc)
720745
struct device *dev = priv->dev;
721746
struct mbox_client *cl;
722747

748+
/*
749+
* stop() and detach() will free the mbox channels, so need
750+
* to request mbox channels in start() and attach().
751+
*
752+
* Because start() and attach() not able to handle mbox defer
753+
* probe, imx_rproc_xtr_mbox_init is also called in probe().
754+
* The check is to avoid request mbox again when start() or
755+
* attach() after probe() returns success.
756+
*/
757+
if (priv->tx_ch && priv->rx_ch)
758+
return 0;
759+
723760
if (!of_get_property(dev->of_node, "mbox-names", NULL))
724761
return 0;
725762

@@ -749,8 +786,15 @@ static void imx_rproc_free_mbox(struct rproc *rproc)
749786
{
750787
struct imx_rproc *priv = rproc->priv;
751788

752-
mbox_free_channel(priv->tx_ch);
753-
mbox_free_channel(priv->rx_ch);
789+
if (priv->tx_ch) {
790+
mbox_free_channel(priv->tx_ch);
791+
priv->tx_ch = NULL;
792+
}
793+
794+
if (priv->rx_ch) {
795+
mbox_free_channel(priv->rx_ch);
796+
priv->rx_ch = NULL;
797+
}
754798
}
755799

756800
static void imx_rproc_put_scu(struct rproc *rproc)

0 commit comments

Comments
 (0)