From 76fab2f299ecc417c5dcb296e029f7465ec74af0 Mon Sep 17 00:00:00 2001 From: Beleswar Padhi Date: Wed, 24 Dec 2025 16:28:33 +0530 Subject: [PATCH] PENDING: remoteproc: k3: Ensure mailbox is suspended after remoteproc The remoteproc driver uses mailbox to communicate suspend and shutdown messages to the remote core. Upon receiving this special message from Linux, the remote core disables its mailbox RX interrupts by writing to the corresponding MAILBOX_IRQSTATUS_CLR_u registers. Therefore, we have to ensure mailbox driver is suspended after this shutdown ack has been received from remote core (mbox restores its irq registers in resume). Failing to do so, would result in restoring incorrect irq configuration in resume leading to spurious mbox interrupts to the remote core. Therefore, use device_links to add mailbox device as a supplier to the remoteproc device (consumer). This ensures that mailbox is suspended after remoteproc. Further, register the mbox pm ops in the late_suspend stage to match with that of remoteproc's stage. Before: omap-mailbox 31f82000.mailbox: PM: calling omap_mbox_suspend [omap_mailbox] @ 1168, parent: bus@100000:bus@30000000 k3_r5_rproc bus@100000:r5fss@5c00000: PM: calling k3_r5_suspend_late [ti_k3_r5_remoteproc] @ 1168, parent: bus@100000 After: k3_r5_rproc bus@100000:r5fss@5e00000: PM: k3_r5_suspend_late [ti_k3_r5_remoteproc] returned 0 after 29077 omap-mailbox 31f85000.mailbox: PM: calling omap_mbox_suspend [omap_mailbox] @ 1138, parent: Signed-off-by: Beleswar Padhi --- drivers/mailbox/omap-mailbox.c | 2 +- drivers/remoteproc/ti_k3_common.c | 20 ++++++++++++++++++++ drivers/remoteproc/ti_k3_r5_remoteproc.c | 24 ++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/drivers/mailbox/omap-mailbox.c b/drivers/mailbox/omap-mailbox.c index 17fe6545875d..105e40a5e903 100644 --- a/drivers/mailbox/omap-mailbox.c +++ b/drivers/mailbox/omap-mailbox.c @@ -379,7 +379,7 @@ static int omap_mbox_resume(struct device *dev) #endif static const struct dev_pm_ops omap_mbox_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(omap_mbox_suspend, omap_mbox_resume) + LATE_SYSTEM_SLEEP_PM_OPS(omap_mbox_suspend, omap_mbox_resume) }; static const struct omap_mbox_match_data omap2_data = { MBOX_INTR_CFG_TYPE1, true }; diff --git a/drivers/remoteproc/ti_k3_common.c b/drivers/remoteproc/ti_k3_common.c index 89969cf74c23..6102d8ed05ce 100644 --- a/drivers/remoteproc/ti_k3_common.c +++ b/drivers/remoteproc/ti_k3_common.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -230,6 +231,9 @@ int k3_rproc_request_mbox(struct rproc *rproc) struct k3_rproc *kproc = rproc->priv; struct mbox_client *client = &kproc->client; struct device *dev = kproc->dev; + struct platform_device *mbox_pdev; + struct device_node *np = dev_of_node(dev); + struct device_node *mbox_np; client->dev = dev; client->tx_done = NULL; @@ -242,6 +246,22 @@ int k3_rproc_request_mbox(struct rproc *rproc) return dev_err_probe(dev, PTR_ERR(kproc->mbox), "mbox_request_channel failed\n"); + mbox_np = of_parse_phandle(np, "mboxes", 0); + if (!mbox_np) { + dev_err(dev, "failed to get mboxes\n"); + return -ENODEV; + } + + mbox_pdev = of_find_device_by_node(mbox_np); + of_node_put(mbox_np); + if(!mbox_pdev) { + dev_err(dev, "mailbox device not yet ready\n"); + return -EPROBE_DEFER; + } + + /* Ensure mailbox is suspended after remoteproc */ + device_link_add(dev, &mbox_pdev->dev, DL_FLAG_AUTOREMOVE_SUPPLIER); + return 0; } EXPORT_SYMBOL_GPL(k3_rproc_request_mbox); diff --git a/drivers/remoteproc/ti_k3_r5_remoteproc.c b/drivers/remoteproc/ti_k3_r5_remoteproc.c index 4242e78a47f1..c8f88dd77af5 100644 --- a/drivers/remoteproc/ti_k3_r5_remoteproc.c +++ b/drivers/remoteproc/ti_k3_r5_remoteproc.c @@ -1917,6 +1917,9 @@ static int k3_r5_cluster_of_init(struct platform_device *pdev) struct k3_r5_cluster *cluster = platform_get_drvdata(pdev); struct device *dev = &pdev->dev; struct device_node *np = dev_of_node(dev); + struct device_node *child_np; + struct device_node *mbox_np; + struct platform_device *mbox_pdev; struct platform_device *cpdev; struct device_node *child; struct k3_r5_core *core; @@ -1931,6 +1934,27 @@ static int k3_r5_cluster_of_init(struct platform_device *pdev) goto fail; } + child_np = dev_of_node(&cpdev->dev); + + mbox_np = of_parse_phandle(child_np, "mboxes", 0); + if (!mbox_np) { + dev_err(dev, "failed to get mboxes\n"); + ret = -ENODEV; + goto fail; + } + + mbox_pdev = of_find_device_by_node(mbox_np); + of_node_put(mbox_np); + if (!mbox_pdev) { + dev_err(dev, "mailbox device not yet ready\n"); + ret = -EPROBE_DEFER; + goto fail; + } + + /* Ensure mailbox is suspended after remoteproc */ + device_link_add(dev, &mbox_pdev->dev, + DL_FLAG_AUTOREMOVE_SUPPLIER); + ret = k3_r5_core_of_init(cpdev); if (ret) { dev_err(dev, "k3_r5_core_of_init failed, ret = %d\n",