summaryrefslogtreecommitdiff
path: root/drivers/rpmsg
diff options
context:
space:
mode:
authorRichard Zhu <hongxing.zhu@nxp.com>2019-03-18 13:10:09 +0800
committerRichard Zhu <hongxing.zhu@nxp.com>2019-03-20 16:36:48 +0800
commit6b5573a9c645b947688c171b2dbdb6b70b59356c (patch)
tree46552bfa9afb46884190c13f39e7a63f4f11cec9 /drivers/rpmsg
parent12ce2f1b43c4033b4be346f5f69d11dd7e5c78b3 (diff)
MLK-21167 rpmsg: imx: add the sync mechanism during partition reset
Remove the delay waiting, add the sync mechanism during partition reset. In order to avoid the hang at master side during the rpmsg restore procedure. Re-initialize the first_notify parameter, when rpmsg master assumes remote processor is dead. Otherwise, master side maybe hang during the rpmsg restore procedure in some corner cases. ~14ms is required by M4 to process the MU message from the cold boot. Set the max wait of MU_SendMessageTimeout to 20ms. Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com> Reviewed-by: Robin Gong <yibin.gong@nxp.com>
Diffstat (limited to 'drivers/rpmsg')
-rw-r--r--drivers/rpmsg/imx_rpmsg.c31
1 files changed, 28 insertions, 3 deletions
diff --git a/drivers/rpmsg/imx_rpmsg.c b/drivers/rpmsg/imx_rpmsg.c
index e8878967b6cc..9dfb49881a31 100644
--- a/drivers/rpmsg/imx_rpmsg.c
+++ b/drivers/rpmsg/imx_rpmsg.c
@@ -105,6 +105,14 @@ struct imx_rpmsg_vproc {
#define to_imx_virdev(vd) container_of(vd, struct imx_virdev, vdev)
+/* Flag 0 of ASR, 1 indicated that remote processor is ready */
+#define REMOTE_IS_READY BIT(0)
+/*
+ * The time consumption by remote ready is less than 1ms in the
+ * evaluation. Set the max wait timeout as 50ms here.
+ */
+#define REMOTE_READY_WAIT_MAX_RETRIES 500
+
struct imx_rpmsg_vq_info {
__u16 num; /* number of entries in the virtio_ring */
__u16 vq_id; /* a globaly unique index of this virtqueue */
@@ -149,10 +157,12 @@ static bool imx_rpmsg_notify(struct virtqueue *vq)
* is running normally or in the suspend mode. Only use
* the timeout mechanism by the first notify when the vdev is
* registered.
+ * ~14ms is required by M4 ready to process the MU message from
+ * cold boot. Set the wait time 20ms here.
*/
if (unlikely(rpvq->rpdev->first_notify > 0)) {
rpvq->rpdev->first_notify--;
- MU_SendMessageTimeout(rpvq->rpdev->mu_base, 1, mu_rpmsg, 200);
+ MU_SendMessageTimeout(rpvq->rpdev->mu_base, 1, mu_rpmsg, 2000);
} else {
MU_SendMessage(rpvq->rpdev->mu_base, 1, mu_rpmsg);
}
@@ -503,6 +513,7 @@ static int imx_rpmsg_mu_init(struct imx_rpmsg_vproc *rpdev)
void imx_rpmsg_restore(struct imx_rpmsg_vproc *rpdev)
{
int i;
+ u32 flags;
int vdev_nums = rpdev->vdev_nums;
for (i = 0; i < vdev_nums; i++) {
@@ -510,8 +521,22 @@ void imx_rpmsg_restore(struct imx_rpmsg_vproc *rpdev)
kfree(rpdev->ivdev[i]);
}
- /* Wait a while for remote bootup */
- usleep_range(10000, 20000);
+ /* Make a double check that remote processor is ready or not */
+ for (i = 0; i < REMOTE_READY_WAIT_MAX_RETRIES; i++) {
+ flags = MU_ReadStatus(rpdev->mu_base);
+ if (flags & REMOTE_IS_READY)
+ break;
+ usleep_range(100, 200);
+ }
+ if (unlikely((flags & REMOTE_IS_READY) == 0)) {
+ pr_err("Wait for remote ready timeout, assume it's dead.\n");
+ /*
+ * In order to make the codes to be robust and back compatible.
+ * When wait remote ready timeout, use the MU_SendMessageTimeout
+ * to send the first kick-off message when register the vdev.
+ */
+ rpdev->first_notify = rpdev->vdev_nums;
+ }
/* Allocate and setup ivdev again to register virtio devices */
if (set_vring_phy_buf(rpdev->pdev, rpdev, rpdev->vdev_nums))