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 <b-padhi@ti.com>
This commit is contained in:
Beleswar Padhi
2025-12-24 16:28:33 +05:30
committed by Udit Kumar
parent 29913619c0
commit 76fab2f299
3 changed files with 45 additions and 1 deletions
+1 -1
View File
@@ -379,7 +379,7 @@ static int omap_mbox_resume(struct device *dev)
#endif #endif
static const struct dev_pm_ops omap_mbox_pm_ops = { 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 }; static const struct omap_mbox_match_data omap2_data = { MBOX_INTR_CFG_TYPE1, true };
+20
View File
@@ -20,6 +20,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/of_address.h> #include <linux/of_address.h>
#include <linux/of_device.h> #include <linux/of_device.h>
#include <linux/of_platform.h>
#include <linux/of_reserved_mem.h> #include <linux/of_reserved_mem.h>
#include <linux/omap-mailbox.h> #include <linux/omap-mailbox.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
@@ -230,6 +231,9 @@ int k3_rproc_request_mbox(struct rproc *rproc)
struct k3_rproc *kproc = rproc->priv; struct k3_rproc *kproc = rproc->priv;
struct mbox_client *client = &kproc->client; struct mbox_client *client = &kproc->client;
struct device *dev = kproc->dev; 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->dev = dev;
client->tx_done = NULL; 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), return dev_err_probe(dev, PTR_ERR(kproc->mbox),
"mbox_request_channel failed\n"); "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; return 0;
} }
EXPORT_SYMBOL_GPL(k3_rproc_request_mbox); EXPORT_SYMBOL_GPL(k3_rproc_request_mbox);
+24
View File
@@ -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 k3_r5_cluster *cluster = platform_get_drvdata(pdev);
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct device_node *np = dev_of_node(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 platform_device *cpdev;
struct device_node *child; struct device_node *child;
struct k3_r5_core *core; struct k3_r5_core *core;
@@ -1931,6 +1934,27 @@ static int k3_r5_cluster_of_init(struct platform_device *pdev)
goto fail; 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); ret = k3_r5_core_of_init(cpdev);
if (ret) { if (ret) {
dev_err(dev, "k3_r5_core_of_init failed, ret = %d\n", dev_err(dev, "k3_r5_core_of_init failed, ret = %d\n",