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;
|
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)
|
static int imx_rproc_start(struct rproc *rproc)
|
||||||
{
|
{
|
||||||
struct imx_rproc *priv = rproc->priv;
|
struct imx_rproc *priv = rproc->priv;
|
||||||
|
@ -376,6 +446,10 @@ static int imx_rproc_start(struct rproc *rproc)
|
||||||
|
|
||||||
if (priv->ipc_only) {
|
if (priv->ipc_only) {
|
||||||
dev_info(dev, "%s: IPC only\n", __func__);
|
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 */
|
/* To partition M4, we need block userspace stop/start */
|
||||||
if (priv->skip_fw_load_recovery) {
|
if (priv->skip_fw_load_recovery) {
|
||||||
priv->skip_fw_load_recovery = false;
|
priv->skip_fw_load_recovery = false;
|
||||||
|
@ -451,6 +525,8 @@ static int imx_rproc_stop(struct rproc *rproc)
|
||||||
|
|
||||||
if (priv->ipc_only) {
|
if (priv->ipc_only) {
|
||||||
dev_info(dev, "%s: IPC only\n", __func__);
|
dev_info(dev, "%s: IPC only\n", __func__);
|
||||||
|
imx_rproc_free_channels(rproc);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TO i.MX8 Paritioned M4, M4 reboot is handled by itself,
|
* TO i.MX8 Paritioned M4, M4 reboot is handled by itself,
|
||||||
* so we still keep early boot and skip fw load flag
|
* so we still keep early boot and skip fw load flag
|
||||||
|
|
Loading…
Reference in New Issue