[PATCH v2] wifi: mt76: mt7996: add thermal zone device registration
Ryan Leung <[email protected]>
| Newsgroups | org.kernel.vger.linux-wireless,org.infradead.lists.linux-arm-kernel,org.infradead.lists.linux-mediatek,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
Register the mt7996 phy as a thermal zone sensor using devm_thermal_of_zone_register() so that device tree thermal-zones nodes can reference the Wi-Fi chip as a temperature source. This allows the kernel thermal governor to control external cooling devices such as PWM fans based on Wi-Fi chip temperature. Registration is non-fatal: -ENODEV is returned when no thermal-sensors DT property references this device, which is the expected case on platforms without a thermal zone configured. Signed-off-by: Ryan Leung <[email protected]> --- Changes in v2: - Take phy->dev->mt76.mutex around mt7996_mcu_get_temperature() - Unregister phy->tzone explicitly in mt7996_unregister_thermal() before the phy is freed - Link to v1: https://patch.msgid.link/[email protected] To: Felix Fietkau <[email protected]> To: Lorenzo Bianconi <[email protected]> To: Ryder Lee <[email protected]> To: Shayne Chen <[email protected]> To: Sean Wang <[email protected]> To: Matthias Brugger <[email protected]> To: AngeloGioacchino Del Regno <[email protected]> Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] --- drivers/net/wireless/mediatek/mt76/mt7996/init.c | 33 ++++++++++++++++++++++ drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h | 1 + 2 files changed, 34 insertions(+) diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/init.c b/drivers/net/wireless/mediatek/mt76/mt7996/init.c index fb635a092584..fda9df1fa66b 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/init.c @@ -234,11 +234,33 @@ static const struct thermal_cooling_device_ops mt7996_thermal_ops = { .set_cur_state = mt7996_thermal_set_cur_throttle_state, }; +static int mt7996_thermal_get_temp(struct thermal_zone_device *tz, int *temp) +{ + struct mt7996_phy *phy = thermal_zone_device_priv(tz); + int val; + + mutex_lock(&phy->dev->mt76.mutex); + val = mt7996_mcu_get_temperature(phy); + mutex_unlock(&phy->dev->mt76.mutex); + if (val < 0) + return val; + + *temp = val * 1000; + return 0; +} + +static const struct thermal_zone_device_ops mt7996_tz_ops = { + .get_temp = mt7996_thermal_get_temp, +}; + static void mt7996_unregister_thermal(struct mt7996_phy *phy) { struct wiphy *wiphy = phy->mt76->hw->wiphy; char name[sizeof("cooling_deviceXXX")]; + if (phy->tzone) + devm_thermal_of_zone_unregister(phy->dev->mt76.dev, phy->tzone); + if (!phy->cdev) return; @@ -275,6 +297,17 @@ static int mt7996_thermal_init(struct mt7996_phy *phy) phy->throttle_temp[MT7996_CRIT_TEMP_IDX] = MT7996_CRIT_TEMP; phy->throttle_temp[MT7996_MAX_TEMP_IDX] = MT7996_MAX_TEMP; + phy->tzone = devm_thermal_of_zone_register(phy->dev->mt76.dev, + phy->mt76->band_idx, phy, + &mt7996_tz_ops); + if (IS_ERR(phy->tzone)) { + if (PTR_ERR(phy->tzone) != -ENODEV) + dev_warn(phy->dev->mt76.dev, + "failed to register thermal zone %d: %ld\n", + phy->mt76->band_idx, PTR_ERR(phy->tzone)); + phy->tzone = NULL; + } + if (!IS_REACHABLE(CONFIG_HWMON)) return 0; diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h index 2a0cdb56f822..39fa25a562e5 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h +++ b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h @@ -372,6 +372,7 @@ struct mt7996_phy { struct ieee80211_sband_iftype_data iftype[NUM_NL80211_BANDS][NUM_NL80211_IFTYPES]; + struct thermal_zone_device *tzone; struct thermal_cooling_device *cdev; u8 cdev_state; u8 throttle_state; --- base-commit: ca800a9302764c445de0da0e84d2252400a770ee change-id: 20260722-mt7996-thermal-zone-a1de7cb1d728 Best regards, -- Ryan Leung <[email protected]>