MPSDK-172 remoteproc: imx_rproc: Re-building communication channels when a remote crashes

When the crash of a remote proc is detected, the physical communication
channels may get corrupted or reset, and it will impact the subsequent
transfers of rpmsg message. So the communication channels should be
re-built when a remote crash is detected.

Signed-off-by: Shenwei Wang <shenwei.wang@nxp.com>
Reviewed-by: Frank Li <frank.li@nxp.com>
This commit is contained in:
Shenwei Wang 2021-05-04 08:28:14 -05:00 committed by Denys Drozdov
parent b93083071e
commit fee1ade052
1 changed files with 76 additions and 0 deletions

View File

@ -365,6 +365,76 @@ bool imx_rproc_ready(struct rproc *rproc)
return true;
}
static int imx_rproc_rebuild_channels(struct rproc *rproc)
{
struct imx_rproc *priv = rproc->priv;
struct mbox_client *cl = &priv->cl;
struct device *dev = priv->dev;
int ret = 0;
if (!priv->tx_ch) {
priv->tx_ch = mbox_request_channel_byname(cl, "tx");
if (IS_ERR(priv->tx_ch)) {
ret = PTR_ERR(priv->tx_ch);
dev_err(dev, "failed to restart tx chan %d\n", ret);
priv->tx_ch = NULL;
goto err_exit;
}
}
if (!priv->rx_ch) {
priv->rx_ch = mbox_request_channel_byname(cl, "rx");
if (IS_ERR(priv->rx_ch)) {
ret = PTR_ERR(priv->rx_ch);
dev_err(dev, "failed to restart rx chan %d\n", ret);
priv->rx_ch = NULL;
goto err_exit;
}
}
if (!priv->rxdb_ch) {
priv->rxdb_ch = mbox_request_channel_byname(cl, "rxdb");
if (IS_ERR(priv->rxdb_ch)) {
ret = PTR_ERR(priv->rxdb_ch);
dev_err(dev, "failed to restart rxdb chan %d\n", ret);
priv->rxdb_ch = NULL;
goto err_exit;
}
}
/* txdb is optional */
if (!priv->txdb_ch) {
priv->txdb_ch = mbox_request_channel_byname(cl, "txdb");
if (IS_ERR(priv->txdb_ch))
priv->txdb_ch = NULL;
}
err_exit:
return ret;
}
static void imx_rproc_free_channels(struct rproc *rproc)
{
struct imx_rproc *priv = rproc->priv;
__u32 mmsg;
if (priv->txdb_ch)
mbox_send_message(priv->txdb_ch, (void *)&mmsg);
mbox_free_channel(priv->tx_ch);
mbox_free_channel(priv->rx_ch);
mbox_free_channel(priv->rxdb_ch);
mbox_free_channel(priv->txdb_ch);
priv->tx_ch = NULL;
priv->rx_ch = NULL;
priv->rxdb_ch = NULL;
priv->txdb_ch = NULL;
}
static int imx_rproc_start(struct rproc *rproc)
{
struct imx_rproc *priv = rproc->priv;
@ -376,6 +446,10 @@ static int imx_rproc_start(struct rproc *rproc)
if (priv->ipc_only) {
dev_info(dev, "%s: IPC only\n", __func__);
ret = imx_rproc_rebuild_channels(rproc);
if (ret < 0)
return -EINVAL;
/* To partition M4, we need block userspace stop/start */
if (priv->skip_fw_load_recovery) {
priv->skip_fw_load_recovery = false;
@ -451,6 +525,8 @@ static int imx_rproc_stop(struct rproc *rproc)
if (priv->ipc_only) {
dev_info(dev, "%s: IPC only\n", __func__);
imx_rproc_free_channels(rproc);
/*
* TO i.MX8 Paritioned M4, M4 reboot is handled by itself,
* so we still keep early boot and skip fw load flag