mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
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 <coiaprant@gmail.com>
Link: https://patch.msgid.link/20261023075214.1793922-3-coiaprant@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
8146be0490
commit
49d8bbc212
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user