[PATCH RESEND] net: stmmac: drop the runtime PM reference on probe failure

From: Wentao Liang

Date: Tue Nov 03 2026 - 06:01:00 EST


__stmmac_dvr_probe() takes a runtime PM reference with
pm_runtime_get_noresume() and enables runtime PM before registering the
MDIO bus. The reference is only dropped on the success path, so a
failure of the MDIO, PCS, phylink, devlink or netdev registration leaves
the usage counter elevated. The device is never bound in that case, so
stmmac_dvr_remove() never runs to release it.

Drop the reference and disable runtime PM again on the common error path.
Only disable runtime PM if this driver enabled it, because PCI devices
already have it enabled by the PCI core.

Fixes: 5ec55823438e ("net: stmmac: add clocks management for gmac driver")
Cc: stable@xxxxxxxxxxxxxxx
Assisted-by: DeepSeek-V4.1-Flash and OpenAI Codex
Signed-off-by: Wentao Liang <vulab@xxxxxxxxxxx>
---
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 049d85b3e25f..eebf1975f40f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -7974,6 +7974,7 @@ static int __stmmac_dvr_probe(struct device *device,
struct net_device *ndev = NULL;
struct stmmac_priv *priv;
int i, ret = 0;
+ bool pm_enabled = false;
u8 rxq;

if (!plat_dat->dma_cfg || !plat_dat->dma_cfg->pbl) {
@@ -8223,8 +8224,10 @@ static int __stmmac_dvr_probe(struct device *device,

pm_runtime_get_noresume(device);
pm_runtime_set_active(device);
- if (!pm_runtime_enabled(device))
+ if (!pm_runtime_enabled(device)) {
pm_runtime_enable(device);
+ pm_enabled = true;
+ }

ret = stmmac_mdio_register(ndev);
if (ret < 0) {
@@ -8278,6 +8281,9 @@ static int __stmmac_dvr_probe(struct device *device,
error_pcs_setup:
stmmac_mdio_unregister(ndev);
error_mdio_register:
+ if (pm_enabled)
+ pm_runtime_disable(device);
+ pm_runtime_put_noidle(device);
stmmac_napi_del(ndev);
error_hw_init:
destroy_workqueue(priv->wq);
--
2.34.1