The thermal zone registered against the parent device is never torn down when the phy is unregistered, so it can still be dereferenced by the thermal core after the phy is freed. The thermal zone and cooling device are also left registered if a later hwmon registration step fails during init, leaking both. Unregister the thermal zone alongside the cooling device on both the regular unregister path and the init failure path. While at it, include the band index in the thermal zone registration warning to help identify which band failed on multi-band chips. Fixes: 313f1a27ebcb ("wifi: mt76: mt7915: add thermal zone device registration") Signed-off-by: Ryan Leung --- Changes in v2: - Unwind cdev/tzone registration in mt7996_thermal_init() on hwmon registration failure. - Link to v1: https://patch.msgid.link/20260810-mt7915-unregister-thermal-v1-1-c6d57b4cb368@protonmail.com --- drivers/net/wireless/mediatek/mt76/mt7915/init.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/init.c b/drivers/net/wireless/mediatek/mt76/mt7915/init.c index ca46a203aa48..5fe70dc822eb 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c @@ -200,6 +200,9 @@ static void mt7915_unregister_thermal(struct mt7915_phy *phy) { struct wiphy *wiphy = phy->mt76->hw->wiphy; + if (phy->tzone) + devm_thermal_of_zone_unregister(phy->dev->mt76.dev, phy->tzone); + if (!phy->cdev) return; @@ -213,6 +216,7 @@ static int mt7915_thermal_init(struct mt7915_phy *phy) struct thermal_cooling_device *cdev; struct device *hwmon; const char *name; + int ret; name = devm_kasprintf(&wiphy->dev, GFP_KERNEL, "mt7915_%s", wiphy_name(wiphy)); @@ -238,8 +242,8 @@ static int mt7915_thermal_init(struct mt7915_phy *phy) if (IS_ERR(phy->tzone)) { if (PTR_ERR(phy->tzone) != -ENODEV) dev_warn(phy->dev->mt76.dev, - "failed to register thermal zone: %ld\n", - PTR_ERR(phy->tzone)); + "failed to register thermal zone %d: %ld\n", + phy->mt76->band_idx, PTR_ERR(phy->tzone)); phy->tzone = NULL; } @@ -248,7 +252,11 @@ static int mt7915_thermal_init(struct mt7915_phy *phy) hwmon = devm_hwmon_device_register_with_groups(&wiphy->dev, name, phy, mt7915_hwmon_groups); - return PTR_ERR_OR_ZERO(hwmon); + ret = PTR_ERR_OR_ZERO(hwmon); + if (ret) + mt7915_unregister_thermal(phy); + + return ret; } static void mt7915_led_set_config(struct led_classdev *led_cdev, --- base-commit: ca800a9302764c445de0da0e84d2252400a770ee change-id: 20260809-mt7915-unregister-thermal-82e805c618a6 Best regards, -- Ryan Leung