[PATCH ath-next v2] wifi: ath12k: add basic hwmon temperature reporting
Maharaja Kennadyrajan
quic_mkenna at quicinc.com
Fri Feb 20 01:55:18 PST 2026
On 2/20/2026 3:14 AM, Jeff Johnson wrote:
> On 2/18/2026 11:34 PM, Maharaja Kennadyrajan wrote:
>> +int ath12k_thermal_register(struct ath12k_base *ab)
>> +{
>> + struct ath12k *ar;
>> + int i, j, ret;
>> +
>> + if (!IS_REACHABLE(CONFIG_HWMON))
>> + return 0;
>> +
>> + for (i = 0; i < ab->num_radios; i++) {
>> + ar = ab->pdevs[i].ar;
>> + if (!ar)
>> + continue;
>> +
>> + ar->thermal.hwmon_dev =
>> + hwmon_device_register_with_groups(&ar->ah->hw->wiphy->dev,
>> + "ath12k_hwmon", ar,
>> + ath12k_hwmon_groups);
> ath10k and ath11k use devm_hwmon_device_register_with_groups().
> why doesn't ath12k do the same?
> then the code below and in _unregister() that calls hwmon_device_unregister()
> would be unnecessary since the objects would be reclaimed when the dev is
> destroyed.
ath12k_thermal_register() loops all radios and devm-registers hwmon devices. If registration fails for radio N, it returns an error that bubbles up and 'ath12k_core_pdev_create()' unwinds only DP ('ath12k_dp_pdev_free()'),
while already-registered hwmon devices for earlier radios remain bound to `wiphy->dev` via devm. If bring-up aborts (pdev_create fails), those hwmon sysfs nodes may persist until the 'wiphy' device is finally destroyed,
which can be much later or never if the bring-up stops early. It will impact resource/sysfs leak window and possible user-visible stale hwmon entries in failure paths.
Given this, using hwmon_device_register_with_groups() plus explicit unregister keeps lifecycle handling predictable and aligned with ath12k’s recovery paths.
>> + if (IS_ERR(ar->thermal.hwmon_dev)) {
>> + ret = PTR_ERR(ar->thermal.hwmon_dev);
>> + ar->thermal.hwmon_dev = NULL;
>> + ath12k_err(ar->ab, "failed to register hwmon device: %d\n",
>> + ret);
>> + for (j = i - 1; j >= 0; j--) {
>> + ar = ab->pdevs[i].ar;
>> + if (!ar)
>> + continue;
>> +
>> + hwmon_device_unregister(ar->thermal.hwmon_dev);
>> + ar->thermal.hwmon_dev = NULL;
>> + }
>> + return ret;
>> + }
>> + }
>> +
>> + return 0;
>> +}
>> +
>> +void ath12k_thermal_unregister(struct ath12k_base *ab)
>> +{
>> + struct ath12k *ar;
>> + int i;
>> +
>> + if (!IS_REACHABLE(CONFIG_HWMON))
>> + return;
>> +
>> + for (i = 0; i < ab->num_radios; i++) {
>> + ar = ab->pdevs[i].ar;
>> + if (!ar)
>> + continue;
>> +
>> + if (ar->thermal.hwmon_dev) {
>> + hwmon_device_unregister(ar->thermal.hwmon_dev);
>> + ar->thermal.hwmon_dev = NULL;
>> + }
>> + }
>> +}
More information about the ath12k
mailing list