Skip to content

Commit 35c3f72

Browse files
Tzung-Bi Shihmathieupoirier
authored andcommitted
remoteproc: mediatek: Unprepare SCP clock during system suspend
Prior to commit d935187 ("remoteproc: mediatek: Break lock dependency to prepare_lock"), `scp->clk` was prepared and enabled only when it needs to communicate with the SCP. The commit d935187 moved the prepare operation to remoteproc's prepare(), keeping the clock prepared as long as the SCP is running. The power consumption due to the prolonged clock preparation can be negligible when the system is running, as SCP is designed to be a very power efficient processor. However, the clock remains prepared even when the system enters system suspend. This prevents the underlying clock controller (and potentially the parent PLLs) from shutting down, which increases power consumption and may block the system from entering deep sleep states. Add suspend and resume callbacks. Unprepare the clock in suspend() if it was active and re-prepare it in resume() to ensure the clock is properly disabled during system suspend, while maintaining the "always prepared" semantics while the system is active. The driver doesn't implement .attach() callback, hence it only checks for RPROC_RUNNING. Fixes: d935187 ("remoteproc: mediatek: Break lock dependency to prepare_lock") Reviewed-by: AngeloGioacchino Del Regno <[email protected]> Signed-off-by: Tzung-Bi Shih <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Mathieu Poirier <[email protected]>
1 parent da994db commit 35c3f72

1 file changed

Lines changed: 39 additions & 0 deletions

File tree

drivers/remoteproc/mtk_scp.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1592,12 +1592,51 @@ static const struct of_device_id mtk_scp_of_match[] = {
15921592
};
15931593
MODULE_DEVICE_TABLE(of, mtk_scp_of_match);
15941594

1595+
static int __maybe_unused scp_suspend(struct device *dev)
1596+
{
1597+
struct mtk_scp *scp = dev_get_drvdata(dev);
1598+
struct rproc *rproc = scp->rproc;
1599+
1600+
/*
1601+
* Only unprepare if the SCP is running and holding the clock.
1602+
*
1603+
* Note: `scp_ops` doesn't implement .attach() callback, hence
1604+
* `rproc->state` can never be RPROC_ATTACHED. Otherwise, it
1605+
* should also be checked here.
1606+
*/
1607+
if (rproc->state == RPROC_RUNNING)
1608+
clk_unprepare(scp->clk);
1609+
return 0;
1610+
}
1611+
1612+
static int __maybe_unused scp_resume(struct device *dev)
1613+
{
1614+
struct mtk_scp *scp = dev_get_drvdata(dev);
1615+
struct rproc *rproc = scp->rproc;
1616+
1617+
/*
1618+
* Only prepare if the SCP was running and holding the clock.
1619+
*
1620+
* Note: `scp_ops` doesn't implement .attach() callback, hence
1621+
* `rproc->state` can never be RPROC_ATTACHED. Otherwise, it
1622+
* should also be checked here.
1623+
*/
1624+
if (rproc->state == RPROC_RUNNING)
1625+
return clk_prepare(scp->clk);
1626+
return 0;
1627+
}
1628+
1629+
static const struct dev_pm_ops scp_pm_ops = {
1630+
SET_SYSTEM_SLEEP_PM_OPS(scp_suspend, scp_resume)
1631+
};
1632+
15951633
static struct platform_driver mtk_scp_driver = {
15961634
.probe = scp_probe,
15971635
.remove = scp_remove,
15981636
.driver = {
15991637
.name = "mtk-scp",
16001638
.of_match_table = mtk_scp_of_match,
1639+
.pm = &scp_pm_ops,
16011640
},
16021641
};
16031642

0 commit comments

Comments
 (0)