From 49d8bbc21244f0c2d2ebf5ee03fb7352ff019ecc Mon Sep 17 00:00:00 2001 From: Coia Prant Date: Fri, 23 Oct 2026 15:52:12 +0800 Subject: net: pcs: xpcs-plat: fix runtime PM initialization The driver calls pm_runtime_set_active() before runtime PM is enabled and before the CSR clock is prepared and enabled. If the device is later suspended (e.g. during unbind), the runtime suspend callback tries to disable a clock that was never enabled, producing: clk_csr already disabled clk_csr already unprepared Set the initial runtime PM status to suspended instead, and register a devm action that force-suspends the device on teardown. Without that action the CSR clock would stay enabled if the driver is removed while runtime-active, since nothing triggers a runtime suspend on unbind. pm_runtime_force_suspend() is not checked because the runtime suspend callback cannot fail. The clock is enabled on the first runtime resume (e.g. during MDIO access). No upstream platform currently enables this driver with a real CSR clock dependency, so the issue is not reachable in mainline today. It was found while using this driver as a reference for the Rockchip XPCS glue driver. Signed-off-by: Coia Prant Link: https://patch.msgid.link/20261023075214.1793922-3-coiaprant@gmail.com Signed-off-by: Jakub Kicinski --- drivers/net/pcs/pcs-xpcs-plat.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/pcs/pcs-xpcs-plat.c b/drivers/net/pcs/pcs-xpcs-plat.c index e669a7b248ac..11c4239bfd74 100644 --- a/drivers/net/pcs/pcs-xpcs-plat.c +++ b/drivers/net/pcs/pcs-xpcs-plat.c @@ -275,6 +275,14 @@ static int xpcs_plat_init_res(struct dw_xpcs_plat *pxpcs) return 0; } +static void xpcs_plat_exit_clk(void *data) +{ + struct dw_xpcs_plat *pxpcs = data; + struct device *dev = &pxpcs->pdev->dev; + + pm_runtime_force_suspend(dev); +} + static int xpcs_plat_init_clk(struct dw_xpcs_plat *pxpcs) { struct device *dev = &pxpcs->pdev->dev; @@ -285,10 +293,12 @@ static int xpcs_plat_init_clk(struct dw_xpcs_plat *pxpcs) return dev_err_probe(dev, PTR_ERR(pxpcs->cclk), "Failed to get CSR clock\n"); - pm_runtime_set_active(dev); - ret = devm_pm_runtime_enable(dev); + pm_runtime_set_suspended(dev); + pm_runtime_enable(dev); + + ret = devm_add_action_or_reset(dev, xpcs_plat_exit_clk, pxpcs); if (ret) { - dev_err(dev, "Failed to enable runtime-PM\n"); + dev_err(dev, "Failed to register devm for xpcs_plat_exit_clk: %d\n", ret); return ret; } -- cgit v1.2.3