[PATCH] wifi: wcn36xx: drop the SMSM state references on probe error
From: Wentao Liang
Date: Tue Nov 03 2026 - 06:43:11 EST
wcn36xx_platform_get_resources() acquires two SMSM state handles with
qcom_smem_state_get(). Each successful call returns a reference that the
caller has to release with qcom_smem_state_put(), which is only done by
wcn36xx_remove() for a device that probed successfully.
Several error paths in between return without dropping the references
already taken: failing to get the "tx-rings-empty" handle leaks the
"tx-enable" one, and failing to look up the qcom,mmio phandle or to map
one of the mmio regions leaks both of them. A probe that fails after the
first successful acquisition therefore leaks the SMSM state references
for good.
Make these paths unwind through the existing label chain and put the
handles there.
Fixes: f303a9311065 ("wcn36xx: Transition driver to SMD client")
Cc: stable@xxxxxxxxxxxxxxx
Assisted-by: DeepSeek-V4.1-Flash and OpenAI Codex
Signed-off-by: Wentao Liang <vulab@xxxxxxxxxxx>
---
drivers/net/wireless/ath/wcn36xx/main.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c
index ad8a4bd910d2..0c4f5b5b8dda 100644
--- a/drivers/net/wireless/ath/wcn36xx/main.c
+++ b/drivers/net/wireless/ath/wcn36xx/main.c
@@ -1502,13 +1502,15 @@ static int wcn36xx_platform_get_resources(struct wcn36xx *wcn,
"tx-rings-empty", &wcn->tx_rings_empty_state_bit);
if (IS_ERR(wcn->tx_rings_empty_state)) {
wcn36xx_err("failed to get tx-rings-empty state\n");
- return PTR_ERR(wcn->tx_rings_empty_state);
+ ret = PTR_ERR(wcn->tx_rings_empty_state);
+ goto put_tx_enable_state;
}
mmio_node = of_parse_phandle(pdev->dev.parent->of_node, "qcom,mmio", 0);
if (!mmio_node) {
wcn36xx_err("failed to acquire qcom,mmio reference\n");
- return -EINVAL;
+ ret = -EINVAL;
+ goto put_tx_rings_empty_state;
}
wcn->is_pronto = !!of_device_is_compatible(mmio_node, "qcom,pronto");
@@ -1552,6 +1554,10 @@ static int wcn36xx_platform_get_resources(struct wcn36xx *wcn,
iounmap(wcn->ccu_base);
put_mmio_node:
of_node_put(mmio_node);
+put_tx_rings_empty_state:
+ qcom_smem_state_put(wcn->tx_rings_empty_state);
+put_tx_enable_state:
+ qcom_smem_state_put(wcn->tx_enable_state);
return ret;
}
--
2.34.1