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:
parent
b93083071e
commit
fee1ade052
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue