[PATCH] wifi: ath11k: Fix rproc reference leak in ath11k_ahb_probe()
From: Wentao Liang
Date: Thu Sep 17 2026 - 08:11:00 EST
ath11k_core_get_rproc() gets the remoteproc with rproc_get_by_phandle(),
which takes a reference on the rproc device, and stores it in
ab_ahb->tgt_rproc. That reference is never released, neither when the
probe fails after the rproc was acquired nor when the driver is removed
or shut down, so the remoteproc can never go away. Drop the reference on
both paths.
Fixes: ba929d6fe31a ("ath11k: Remove rproc references from common core layer")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Wentao Liang <vulab@xxxxxxxxxxx>
---
drivers/net/wireless/ath/ath11k/ahb.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/net/wireless/ath/ath11k/ahb.c b/drivers/net/wireless/ath/ath11k/ahb.c
index 08d3a0c8f105..0f7891a286ad 100644
--- a/drivers/net/wireless/ath/ath11k/ahb.c
+++ b/drivers/net/wireless/ath/ath11k/ahb.c
@@ -1107,6 +1107,7 @@ static int ath11k_ahb_fw_resource_deinit(struct ath11k_base *ab)
static int ath11k_ahb_probe(struct platform_device *pdev)
{
struct ath11k_base *ab;
+ struct ath11k_ahb *ab_ahb;
const struct ath11k_hif_ops *hif_ops;
const struct ath11k_pci_ops *pci_ops;
enum ath11k_hw_rev hw_rev;
@@ -1147,6 +1148,7 @@ static int ath11k_ahb_probe(struct platform_device *pdev)
ab->pdev = pdev;
ab->hw_rev = hw_rev;
ab->fw_mode = ATH11K_FIRMWARE_MODE_NORMAL;
+ ab_ahb = ath11k_ahb_priv(ab);
platform_set_drvdata(pdev, ab);
ret = ath11k_pcic_register_pci_ops(ab, pci_ops);
@@ -1223,6 +1225,8 @@ static int ath11k_ahb_probe(struct platform_device *pdev)
ath11k_ahb_ce_unmap(ab);
err_core_free:
+ if (ab_ahb->tgt_rproc)
+ rproc_put(ab_ahb->tgt_rproc);
ath11k_core_free(ab);
platform_set_drvdata(pdev, NULL);
@@ -1247,6 +1251,7 @@ static void ath11k_ahb_remove_prepare(struct ath11k_base *ab)
static void ath11k_ahb_free_resources(struct ath11k_base *ab)
{
+ struct ath11k_ahb *ab_ahb = ath11k_ahb_priv(ab);
struct platform_device *pdev = ab->pdev;
ath11k_ahb_free_irq(ab);
@@ -1256,6 +1261,8 @@ static void ath11k_ahb_free_resources(struct ath11k_base *ab)
ath11k_ce_free_pipes(ab);
ath11k_ahb_ce_unmap(ab);
+ rproc_put(ab_ahb->tgt_rproc);
+
ath11k_core_free(ab);
platform_set_drvdata(pdev, NULL);
}
--
2.34.1