* [PATCH ath-next v2] wifi: ath12k: add basic hwmon temperature reporting
@ 2026-02-19 7:34 Maharaja Kennadyrajan
2026-02-19 9:15 ` Nicolas Escande
` (2 more replies)
0 siblings, 3 replies; 9+ messages in thread
From: Maharaja Kennadyrajan @ 2026-02-19 7:34 UTC (permalink / raw)
To: ath12k; +Cc: linux-wireless, Maharaja Kennadyrajan, Aishwarya R
Add initial thermal support by wiring up a per-radio (pdev) hwmon temperature
sensor backed by the existing WMI pdev temperature command and event.
When userspace reads the sysfs file temp1_input, the driver sends
WMI_PDEV_GET_TEMPERATURE_CMDID (tag WMI_TAG_PDEV_GET_TEMPERATURE_CMD) and waits
for the corresponding WMI_PDEV_TEMPERATURE_EVENTID
(tag WMI_TAG_PDEV_TEMPERATURE_EVENT) to get the temperature and pdev_id.
Export the reported value in millidegrees Celsius as required by hwmon.
The temperature reported is per-radio (pdev). In a multi-radio wiphy under a
single phy, a separate hwmon device is created for each radio.
Sample command and output:
$ cat /sys/devices/pci0000:00/.../ieee80211/phyX/hwmonY/temp1_input
$ 50000
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.6-01243-QCAHKSWPL_SILICONZ-1
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202602160145.YQdvbqYY-lkp@intel.com/
Co-developed-by: Aishwarya R <aishwarya.r@oss.qualcomm.com>
Signed-off-by: Aishwarya R <aishwarya.r@oss.qualcomm.com>
Signed-off-by: Maharaja Kennadyrajan <maharaja.kennadyrajan@oss.qualcomm.com>
---
v2: Fixed the kernel test robot reported build test error.
drivers/net/wireless/ath/ath12k/Makefile | 1 +
drivers/net/wireless/ath/ath12k/core.c | 13 +++
drivers/net/wireless/ath/ath12k/core.h | 3 +
drivers/net/wireless/ath/ath12k/mac.c | 5 +
drivers/net/wireless/ath/ath12k/thermal.c | 125 ++++++++++++++++++++++
drivers/net/wireless/ath/ath12k/thermal.h | 44 ++++++++
drivers/net/wireless/ath/ath12k/wmi.c | 57 +++++-----
7 files changed, 217 insertions(+), 31 deletions(-)
create mode 100644 drivers/net/wireless/ath/ath12k/thermal.c
create mode 100644 drivers/net/wireless/ath/ath12k/thermal.h
diff --git a/drivers/net/wireless/ath/ath12k/Makefile b/drivers/net/wireless/ath/ath12k/Makefile
index 3ba1236956cc..3b39b2c33307 100644
--- a/drivers/net/wireless/ath/ath12k/Makefile
+++ b/drivers/net/wireless/ath/ath12k/Makefile
@@ -32,6 +32,7 @@ ath12k-$(CONFIG_ATH12K_TRACING) += trace.o
ath12k-$(CONFIG_PM) += wow.o
ath12k-$(CONFIG_ATH12K_COREDUMP) += coredump.o
ath12k-$(CONFIG_NL80211_TESTMODE) += testmode.o
+ath12k-$(CONFIG_THERMAL) += thermal.o
# for tracing framework to find trace.h
CFLAGS_trace.o := -I$(src)
diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c
index 9d6c50a94e64..9dca1a0af73e 100644
--- a/drivers/net/wireless/ath/ath12k/core.c
+++ b/drivers/net/wireless/ath/ath12k/core.c
@@ -863,11 +863,22 @@ static int ath12k_core_pdev_create(struct ath12k_base *ab)
return ret;
}
+ ret = ath12k_thermal_register(ab);
+ if (ret) {
+ ath12k_err(ab, "could not register thermal device: %d\n", ret);
+ goto err_dp_pdev_free;
+ }
+
return 0;
+
+err_dp_pdev_free:
+ ath12k_dp_pdev_free(ab);
+ return ret;
}
static void ath12k_core_pdev_destroy(struct ath12k_base *ab)
{
+ ath12k_thermal_unregister(ab);
ath12k_dp_pdev_free(ab);
}
@@ -1361,6 +1372,7 @@ static int ath12k_core_reconfigure_on_crash(struct ath12k_base *ab)
mutex_lock(&ab->core_lock);
ath12k_link_sta_rhash_tbl_destroy(ab);
+ ath12k_thermal_unregister(ab);
ath12k_dp_pdev_free(ab);
ath12k_ce_cleanup_pipes(ab);
ath12k_wmi_detach(ab);
@@ -1502,6 +1514,7 @@ static void ath12k_core_pre_reconfigure_recovery(struct ath12k_base *ab)
complete(&ar->vdev_delete_done);
complete(&ar->bss_survey_done);
complete_all(&ar->regd_update_completed);
+ complete_all(&ar->thermal.wmi_sync);
wake_up(&ar->dp.tx_empty_waitq);
idr_for_each(&ar->txmgmt_idr,
diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h
index 990934ec92fc..760c76d6f0f4 100644
--- a/drivers/net/wireless/ath/ath12k/core.h
+++ b/drivers/net/wireless/ath/ath12k/core.h
@@ -36,6 +36,7 @@
#include "coredump.h"
#include "cmn_defs.h"
#include "dp_cmn.h"
+#include "thermal.h"
#define SM(_v, _f) (((_v) << _f##_LSB) & _f##_MASK)
@@ -757,6 +758,8 @@ struct ath12k {
s8 max_allowed_tx_power;
struct ath12k_pdev_rssi_offsets rssi_info;
+
+ struct ath12k_thermal thermal;
};
struct ath12k_hw {
diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
index 68431a0e128e..d1db1285449c 100644
--- a/drivers/net/wireless/ath/ath12k/mac.c
+++ b/drivers/net/wireless/ath/ath12k/mac.c
@@ -14792,6 +14792,11 @@ static void ath12k_mac_setup(struct ath12k *ar)
init_completion(&ar->mlo_setup_done);
init_completion(&ar->completed_11d_scan);
init_completion(&ar->regd_update_completed);
+ init_completion(&ar->thermal.wmi_sync);
+ mutex_init(&ar->thermal.read_lock);
+
+ ar->thermal.temperature = 0;
+ ar->thermal.hwmon_dev = NULL;
INIT_DELAYED_WORK(&ar->scan.timeout, ath12k_scan_timeout_work);
wiphy_work_init(&ar->scan.vdev_clean_wk, ath12k_scan_vdev_clean_work);
diff --git a/drivers/net/wireless/ath/ath12k/thermal.c b/drivers/net/wireless/ath/ath12k/thermal.c
new file mode 100644
index 000000000000..b01e03e5a357
--- /dev/null
+++ b/drivers/net/wireless/ath/ath12k/thermal.c
@@ -0,0 +1,125 @@
+// SPDX-License-Identifier: BSD-3-Clause-Clear
+/*
+ * Copyright (c) 2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#include <linux/device.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/sysfs.h>
+#include <linux/thermal.h>
+#include "core.h"
+#include "debug.h"
+
+static ssize_t ath12k_thermal_temp_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct ath12k *ar = dev_get_drvdata(dev);
+ unsigned long time_left;
+ int ret, temperature;
+
+ guard(wiphy)(ath12k_ar_to_hw(ar)->wiphy);
+ guard(mutex)(&ar->thermal.read_lock);
+
+ if (ar->ah->state != ATH12K_HW_STATE_ON)
+ return -ENETDOWN;
+
+ reinit_completion(&ar->thermal.wmi_sync);
+ ret = ath12k_wmi_send_pdev_temperature_cmd(ar);
+ if (ret) {
+ ath12k_warn(ar->ab, "failed to read temperature %d\n", ret);
+ return ret;
+ }
+
+ if (test_bit(ATH12K_FLAG_CRASH_FLUSH, &ar->ab->dev_flags))
+ return -ESHUTDOWN;
+
+ time_left = wait_for_completion_timeout(&ar->thermal.wmi_sync,
+ ATH12K_THERMAL_SYNC_TIMEOUT_HZ);
+ if (!time_left) {
+ ath12k_warn(ar->ab, "failed to synchronize thermal read\n");
+ return -ETIMEDOUT;
+ }
+
+ spin_lock_bh(&ar->data_lock);
+ temperature = ar->thermal.temperature;
+ spin_unlock_bh(&ar->data_lock);
+
+ /* display in millidegree celsius */
+ return sysfs_emit(buf, "%d\n", temperature * 1000);
+}
+
+void ath12k_thermal_event_temperature(struct ath12k *ar, int temperature)
+{
+ spin_lock_bh(&ar->data_lock);
+ ar->thermal.temperature = temperature;
+ spin_unlock_bh(&ar->data_lock);
+ complete_all(&ar->thermal.wmi_sync);
+}
+
+static SENSOR_DEVICE_ATTR_RO(temp1_input, ath12k_thermal_temp, 0);
+
+static struct attribute *ath12k_hwmon_attrs[] = {
+ &sensor_dev_attr_temp1_input.dev_attr.attr,
+ NULL,
+};
+ATTRIBUTE_GROUPS(ath12k_hwmon);
+
+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);
+ 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;
+ }
+ }
+}
diff --git a/drivers/net/wireless/ath/ath12k/thermal.h b/drivers/net/wireless/ath/ath12k/thermal.h
new file mode 100644
index 000000000000..a853af5f2441
--- /dev/null
+++ b/drivers/net/wireless/ath/ath12k/thermal.h
@@ -0,0 +1,44 @@
+/* SPDX-License-Identifier: BSD-3-Clause-Clear */
+/*
+ * Copyright (c) 2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#ifndef _ATH12K_THERMAL_
+#define _ATH12K_THERMAL_
+
+#include <linux/mutex.h>
+
+#define ATH12K_THERMAL_SYNC_TIMEOUT_HZ (5 * HZ)
+
+struct ath12k_thermal {
+ struct completion wmi_sync;
+
+ /* temperature value in Celsius degree protected by data_lock. */
+ int temperature;
+ struct device *hwmon_dev;
+ /* Serialize concurrent sysfs reads to avoid completion races */
+ struct mutex read_lock;
+};
+
+#if IS_REACHABLE(CONFIG_THERMAL)
+int ath12k_thermal_register(struct ath12k_base *ab);
+void ath12k_thermal_unregister(struct ath12k_base *ab);
+void ath12k_thermal_event_temperature(struct ath12k *ar, int temperature);
+#else
+static inline int ath12k_thermal_register(struct ath12k_base *ab)
+{
+ return 0;
+}
+
+static inline void ath12k_thermal_unregister(struct ath12k_base *ab)
+{
+}
+
+static inline void ath12k_thermal_event_temperature(struct ath12k *ar,
+ int temperature)
+{
+}
+
+#endif
+#endif /* _ATH12K_THERMAL_ */
diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c
index 7617fc3a2479..69f2dbcfca63 100644
--- a/drivers/net/wireless/ath/ath12k/wmi.c
+++ b/drivers/net/wireless/ath/ath12k/wmi.c
@@ -6778,31 +6778,6 @@ static int ath12k_pull_peer_assoc_conf_ev(struct ath12k_base *ab, struct sk_buff
return 0;
}
-static int
-ath12k_pull_pdev_temp_ev(struct ath12k_base *ab, struct sk_buff *skb,
- const struct wmi_pdev_temperature_event *ev)
-{
- const void **tb;
- int ret;
-
- tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
- if (IS_ERR(tb)) {
- ret = PTR_ERR(tb);
- ath12k_warn(ab, "failed to parse tlv: %d\n", ret);
- return ret;
- }
-
- ev = tb[WMI_TAG_PDEV_TEMPERATURE_EVENT];
- if (!ev) {
- ath12k_warn(ab, "failed to fetch pdev temp ev");
- kfree(tb);
- return -EPROTO;
- }
-
- kfree(tb);
- return 0;
-}
-
static void ath12k_wmi_op_ep_tx_credits(struct ath12k_base *ab)
{
/* try to send pending beacons first. they take priority */
@@ -8811,25 +8786,45 @@ static void
ath12k_wmi_pdev_temperature_event(struct ath12k_base *ab,
struct sk_buff *skb)
{
+ const struct wmi_pdev_temperature_event *ev;
struct ath12k *ar;
- struct wmi_pdev_temperature_event ev = {};
+ const void **tb;
+ int temp;
+ u32 pdev_id;
+
+ tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
+ if (IS_ERR(tb)) {
+ ath12k_warn(ab, "failed to parse tlv: %ld\n", PTR_ERR(tb));
+ return;
+ }
- if (ath12k_pull_pdev_temp_ev(ab, skb, &ev) != 0) {
- ath12k_warn(ab, "failed to extract pdev temperature event");
+ ev = tb[WMI_TAG_PDEV_TEMPERATURE_EVENT];
+ if (!ev) {
+ ath12k_warn(ab, "failed to fetch pdev temp ev\n");
+ kfree(tb);
return;
}
+ temp = a_sle32_to_cpu(ev->temp);
+ pdev_id = le32_to_cpu(ev->pdev_id);
+
+ kfree(tb);
+
ath12k_dbg(ab, ATH12K_DBG_WMI,
- "pdev temperature ev temp %d pdev_id %d\n", ev.temp, ev.pdev_id);
+ "pdev temperature ev temp %d pdev_id %u\n",
+ temp, pdev_id);
rcu_read_lock();
- ar = ath12k_mac_get_ar_by_pdev_id(ab, le32_to_cpu(ev.pdev_id));
+ ar = ath12k_mac_get_ar_by_pdev_id(ab, pdev_id);
if (!ar) {
- ath12k_warn(ab, "invalid pdev id in pdev temperature ev %d", ev.pdev_id);
+ ath12k_warn(ab, "invalid pdev id %u in pdev temperature ev\n",
+ pdev_id);
goto exit;
}
+ ath12k_thermal_event_temperature(ar, temp);
+
exit:
rcu_read_unlock();
}
base-commit: 37a93dd5c49b5fda807fd204edf2547c3493319c
--
2.17.1
^ permalink raw reply related [flat|nested] 9+ messages in thread* Re: [PATCH ath-next v2] wifi: ath12k: add basic hwmon temperature reporting
2026-02-19 7:34 [PATCH ath-next v2] wifi: ath12k: add basic hwmon temperature reporting Maharaja Kennadyrajan
@ 2026-02-19 9:15 ` Nicolas Escande
2026-02-19 21:37 ` Jeff Johnson
2026-02-23 11:21 ` Maharaja Kennadyrajan
2026-02-19 11:31 ` Pablo MARTIN-GOMEZ
2026-02-19 21:44 ` Jeff Johnson
2 siblings, 2 replies; 9+ messages in thread
From: Nicolas Escande @ 2026-02-19 9:15 UTC (permalink / raw)
To: Maharaja Kennadyrajan, ath12k; +Cc: linux-wireless, Aishwarya R
On Thu Feb 19, 2026 at 8:34 AM CET, Maharaja Kennadyrajan wrote:
> Add initial thermal support by wiring up a per-radio (pdev) hwmon temperature
> sensor backed by the existing WMI pdev temperature command and event.
> When userspace reads the sysfs file temp1_input, the driver sends
> WMI_PDEV_GET_TEMPERATURE_CMDID (tag WMI_TAG_PDEV_GET_TEMPERATURE_CMD) and waits
> for the corresponding WMI_PDEV_TEMPERATURE_EVENTID
> (tag WMI_TAG_PDEV_TEMPERATURE_EVENT) to get the temperature and pdev_id.
>
> Export the reported value in millidegrees Celsius as required by hwmon.
> The temperature reported is per-radio (pdev). In a multi-radio wiphy under a
> single phy, a separate hwmon device is created for each radio.
>
> Sample command and output:
> $ cat /sys/devices/pci0000:00/.../ieee80211/phyX/hwmonY/temp1_input
> $ 50000
>
Hello,
In ath10k & ath11k you guys also had the throtling feature. Do you guys plan to
add this also at some point ?
[...]
> --- a/drivers/net/wireless/ath/ath12k/Makefile
> +++ b/drivers/net/wireless/ath/ath12k/Makefile
> @@ -32,6 +32,7 @@ ath12k-$(CONFIG_ATH12K_TRACING) += trace.o
> ath12k-$(CONFIG_PM) += wow.o
> ath12k-$(CONFIG_ATH12K_COREDUMP) += coredump.o
> ath12k-$(CONFIG_NL80211_TESTMODE) += testmode.o
> +ath12k-$(CONFIG_THERMAL) += thermal.o
>
I may be wrong but I do not see Kconfig changes that allows to actually build
the new files. Is this intended ?
> # for tracing framework to find trace.h
> CFLAGS_trace.o := -I$(src)
> diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH ath-next v2] wifi: ath12k: add basic hwmon temperature reporting
2026-02-19 9:15 ` Nicolas Escande
@ 2026-02-19 21:37 ` Jeff Johnson
2026-02-20 9:26 ` Nicolas Escande
2026-02-23 11:21 ` Maharaja Kennadyrajan
1 sibling, 1 reply; 9+ messages in thread
From: Jeff Johnson @ 2026-02-19 21:37 UTC (permalink / raw)
To: Nicolas Escande, Maharaja Kennadyrajan, ath12k
Cc: linux-wireless, Aishwarya R
On 2/19/2026 1:15 AM, Nicolas Escande wrote:
> On Thu Feb 19, 2026 at 8:34 AM CET, Maharaja Kennadyrajan wrote:
>> +ath12k-$(CONFIG_THERMAL) += thermal.o
>>
>
> I may be wrong but I do not see Kconfig changes that allows to actually build
> the new files. Is this intended ?
There is no configuration specifically for the driver -- it just follows
whatever has been configured globally. So CONFIG_THERMAL would need to be
enabled to have the file compiled, and CONFIG_HWMON would need to be enabled
to have the sysfs file exposed. ath10k and ath11k have the same logic.
/jeff
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH ath-next v2] wifi: ath12k: add basic hwmon temperature reporting
2026-02-19 21:37 ` Jeff Johnson
@ 2026-02-20 9:26 ` Nicolas Escande
0 siblings, 0 replies; 9+ messages in thread
From: Nicolas Escande @ 2026-02-20 9:26 UTC (permalink / raw)
To: Jeff Johnson, Nicolas Escande, Maharaja Kennadyrajan, ath12k
Cc: linux-wireless, Aishwarya R
On Thu Feb 19, 2026 at 10:37 PM CET, Jeff Johnson wrote:
> On 2/19/2026 1:15 AM, Nicolas Escande wrote:
>> On Thu Feb 19, 2026 at 8:34 AM CET, Maharaja Kennadyrajan wrote:
>>> +ath12k-$(CONFIG_THERMAL) += thermal.o
>>>
>>
>> I may be wrong but I do not see Kconfig changes that allows to actually build
>> the new files. Is this intended ?
>
> There is no configuration specifically for the driver -- it just follows
> whatever has been configured globally. So CONFIG_THERMAL would need to be
> enabled to have the file compiled, and CONFIG_HWMON would need to be enabled
> to have the sysfs file exposed. ath10k and ath11k have the same logic.
>
> /jeff
Silly me, thanks.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH ath-next v2] wifi: ath12k: add basic hwmon temperature reporting
2026-02-19 9:15 ` Nicolas Escande
2026-02-19 21:37 ` Jeff Johnson
@ 2026-02-23 11:21 ` Maharaja Kennadyrajan
1 sibling, 0 replies; 9+ messages in thread
From: Maharaja Kennadyrajan @ 2026-02-23 11:21 UTC (permalink / raw)
To: Nicolas Escande, ath12k; +Cc: linux-wireless, Aishwarya R
On 2/19/2026 2:45 PM, Nicolas Escande wrote:
> On Thu Feb 19, 2026 at 8:34 AM CET, Maharaja Kennadyrajan wrote:
>> Add initial thermal support by wiring up a per-radio (pdev) hwmon temperature
>> sensor backed by the existing WMI pdev temperature command and event.
>> When userspace reads the sysfs file temp1_input, the driver sends
>> WMI_PDEV_GET_TEMPERATURE_CMDID (tag WMI_TAG_PDEV_GET_TEMPERATURE_CMD) and waits
>> for the corresponding WMI_PDEV_TEMPERATURE_EVENTID
>> (tag WMI_TAG_PDEV_TEMPERATURE_EVENT) to get the temperature and pdev_id.
>>
>> Export the reported value in millidegrees Celsius as required by hwmon.
>> The temperature reported is per-radio (pdev). In a multi-radio wiphy under a
>> single phy, a separate hwmon device is created for each radio.
>>
>> Sample command and output:
>> $ cat /sys/devices/pci0000:00/.../ieee80211/phyX/hwmonY/temp1_input
>> $ 50000
>>
> Hello,
>
> In ath10k & ath11k you guys also had the throtling feature. Do you guys plan to
> add this also at some point ?
Yes, we have a plan to add that throttling feature as well.
>
> [...]
>
>> --- a/drivers/net/wireless/ath/ath12k/Makefile
>> +++ b/drivers/net/wireless/ath/ath12k/Makefile
>> @@ -32,6 +32,7 @@ ath12k-$(CONFIG_ATH12K_TRACING) += trace.o
>> ath12k-$(CONFIG_PM) += wow.o
>> ath12k-$(CONFIG_ATH12K_COREDUMP) += coredump.o
>> ath12k-$(CONFIG_NL80211_TESTMODE) += testmode.o
>> +ath12k-$(CONFIG_THERMAL) += thermal.o
>>
> I may be wrong but I do not see Kconfig changes that allows to actually build
> the new files. Is this intended ?
>
>> # for tracing framework to find trace.h
>> CFLAGS_trace.o := -I$(src)
>> diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH ath-next v2] wifi: ath12k: add basic hwmon temperature reporting
2026-02-19 7:34 [PATCH ath-next v2] wifi: ath12k: add basic hwmon temperature reporting Maharaja Kennadyrajan
2026-02-19 9:15 ` Nicolas Escande
@ 2026-02-19 11:31 ` Pablo MARTIN-GOMEZ
2026-02-19 11:45 ` Maharaja Kennadyrajan
2026-02-19 21:44 ` Jeff Johnson
2 siblings, 1 reply; 9+ messages in thread
From: Pablo MARTIN-GOMEZ @ 2026-02-19 11:31 UTC (permalink / raw)
To: Maharaja Kennadyrajan, ath12k; +Cc: linux-wireless, Aishwarya R
Hello,
On 19/02/2026 08:34, Maharaja Kennadyrajan wrote:
> Add initial thermal support by wiring up a per-radio (pdev) hwmon temperature
> sensor backed by the existing WMI pdev temperature command and event.
> When userspace reads the sysfs file temp1_input, the driver sends
> WMI_PDEV_GET_TEMPERATURE_CMDID (tag WMI_TAG_PDEV_GET_TEMPERATURE_CMD) and waits
> for the corresponding WMI_PDEV_TEMPERATURE_EVENTID
> (tag WMI_TAG_PDEV_TEMPERATURE_EVENT) to get the temperature and pdev_id.
>
> Export the reported value in millidegrees Celsius as required by hwmon.
> The temperature reported is per-radio (pdev). In a multi-radio wiphy under a
> single phy, a separate hwmon device is created for each radio.
>
> Sample command and output:
> $ cat /sys/devices/pci0000:00/.../ieee80211/phyX/hwmonY/temp1_input
> $ 50000
>
> Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.6-01243-QCAHKSWPL_SILICONZ-1
> Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3
>
> Reported-by: kernel test robot <lkp@intel.com>
> Closes: https://lore.kernel.org/oe-kbuild-all/202602160145.YQdvbqYY-lkp@intel.com/
> Co-developed-by: Aishwarya R <aishwarya.r@oss.qualcomm.com>
> Signed-off-by: Aishwarya R <aishwarya.r@oss.qualcomm.com>
> Signed-off-by: Maharaja Kennadyrajan <maharaja.kennadyrajan@oss.qualcomm.com>
> ---
>
> v2: Fixed the kernel test robot reported build test error.
>
> drivers/net/wireless/ath/ath12k/Makefile | 1 +
> drivers/net/wireless/ath/ath12k/core.c | 13 +++
> drivers/net/wireless/ath/ath12k/core.h | 3 +
> drivers/net/wireless/ath/ath12k/mac.c | 5 +
> drivers/net/wireless/ath/ath12k/thermal.c | 125 ++++++++++++++++++++++
> drivers/net/wireless/ath/ath12k/thermal.h | 44 ++++++++
> drivers/net/wireless/ath/ath12k/wmi.c | 57 +++++-----
> 7 files changed, 217 insertions(+), 31 deletions(-)
> create mode 100644 drivers/net/wireless/ath/ath12k/thermal.c
> create mode 100644 drivers/net/wireless/ath/ath12k/thermal.h
>
[...]
> +
> +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);
> + 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;
Shouldn't it be `ar = ab->pdevs[j].ar;`?
> + if (!ar)
> + continue;
> +
> + hwmon_device_unregister(ar->thermal.hwmon_dev);
> + ar->thermal.hwmon_dev = NULL;
> + }
> + return ret;
> + }
> + }
> +
> + return 0;
> +}
> +
[...]
Best regards,
Pablo MG
^ permalink raw reply [flat|nested] 9+ messages in thread* Re: [PATCH ath-next v2] wifi: ath12k: add basic hwmon temperature reporting
2026-02-19 11:31 ` Pablo MARTIN-GOMEZ
@ 2026-02-19 11:45 ` Maharaja Kennadyrajan
0 siblings, 0 replies; 9+ messages in thread
From: Maharaja Kennadyrajan @ 2026-02-19 11:45 UTC (permalink / raw)
To: Pablo MARTIN-GOMEZ, Maharaja Kennadyrajan, ath12k
Cc: linux-wireless, Aishwarya R
On 2/19/2026 5:01 PM, Pablo MARTIN-GOMEZ wrote:
> Hello,
>
> On 19/02/2026 08:34, Maharaja Kennadyrajan wrote:
>> Add initial thermal support by wiring up a per-radio (pdev) hwmon
>> temperature
>> sensor backed by the existing WMI pdev temperature command and event.
>> When userspace reads the sysfs file temp1_input, the driver sends
>> WMI_PDEV_GET_TEMPERATURE_CMDID (tag WMI_TAG_PDEV_GET_TEMPERATURE_CMD)
>> and waits
>> for the corresponding WMI_PDEV_TEMPERATURE_EVENTID
>> (tag WMI_TAG_PDEV_TEMPERATURE_EVENT) to get the temperature and pdev_id.
>>
>> Export the reported value in millidegrees Celsius as required by hwmon.
>> The temperature reported is per-radio (pdev). In a multi-radio wiphy
>> under a
>> single phy, a separate hwmon device is created for each radio.
>>
>> Sample command and output:
>> $ cat /sys/devices/pci0000:00/.../ieee80211/phyX/hwmonY/temp1_input
>> $ 50000
>>
>> Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.6-01243-QCAHKSWPL_SILICONZ-1
>> Tested-on: WCN7850 hw2.0 PCI
>> WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3
>>
>> Reported-by: kernel test robot <lkp@intel.com>
>> Closes:
>> https://lore.kernel.org/oe-kbuild-all/202602160145.YQdvbqYY-lkp@intel.com/
>> Co-developed-by: Aishwarya R <aishwarya.r@oss.qualcomm.com>
>> Signed-off-by: Aishwarya R <aishwarya.r@oss.qualcomm.com>
>> Signed-off-by: Maharaja Kennadyrajan
>> <maharaja.kennadyrajan@oss.qualcomm.com>
>> ---
>>
>> v2: Fixed the kernel test robot reported build test error.
>>
>> drivers/net/wireless/ath/ath12k/Makefile | 1 +
>> drivers/net/wireless/ath/ath12k/core.c | 13 +++
>> drivers/net/wireless/ath/ath12k/core.h | 3 +
>> drivers/net/wireless/ath/ath12k/mac.c | 5 +
>> drivers/net/wireless/ath/ath12k/thermal.c | 125 ++++++++++++++++++++++
>> drivers/net/wireless/ath/ath12k/thermal.h | 44 ++++++++
>> drivers/net/wireless/ath/ath12k/wmi.c | 57 +++++-----
>> 7 files changed, 217 insertions(+), 31 deletions(-)
>> create mode 100644 drivers/net/wireless/ath/ath12k/thermal.c
>> create mode 100644 drivers/net/wireless/ath/ath12k/thermal.h
>>
> [...]
>> +
>> +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);
>> + 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;
> Shouldn't it be `ar = ab->pdevs[j].ar;`?
My bad. It should by ab->pdev[j] not ab->pdev[i]. Will be addressed in
the next version.
>> + if (!ar)
>> + continue;
>> +
>> + hwmon_device_unregister(ar->thermal.hwmon_dev);
>> + ar->thermal.hwmon_dev = NULL;
>> + }
>> + return ret;
>> + }
>> + }
>> +
>> + return 0;
>> +}
>> +
>
> [...]
>
> Best regards,
>
> Pablo MG
>
>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH ath-next v2] wifi: ath12k: add basic hwmon temperature reporting
2026-02-19 7:34 [PATCH ath-next v2] wifi: ath12k: add basic hwmon temperature reporting Maharaja Kennadyrajan
2026-02-19 9:15 ` Nicolas Escande
2026-02-19 11:31 ` Pablo MARTIN-GOMEZ
@ 2026-02-19 21:44 ` Jeff Johnson
2026-02-20 9:55 ` Maharaja Kennadyrajan
2 siblings, 1 reply; 9+ messages in thread
From: Jeff Johnson @ 2026-02-19 21:44 UTC (permalink / raw)
To: Maharaja Kennadyrajan, ath12k; +Cc: linux-wireless, Aishwarya R
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.
> + 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;
> + }
> + }
> +}
^ permalink raw reply [flat|nested] 9+ messages in thread* Re: [PATCH ath-next v2] wifi: ath12k: add basic hwmon temperature reporting
2026-02-19 21:44 ` Jeff Johnson
@ 2026-02-20 9:55 ` Maharaja Kennadyrajan
0 siblings, 0 replies; 9+ messages in thread
From: Maharaja Kennadyrajan @ 2026-02-20 9:55 UTC (permalink / raw)
To: Jeff Johnson, Maharaja Kennadyrajan, ath12k; +Cc: linux-wireless, Aishwarya R
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;
>> + }
>> + }
>> +}
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2026-02-23 11:21 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-19 7:34 [PATCH ath-next v2] wifi: ath12k: add basic hwmon temperature reporting Maharaja Kennadyrajan
2026-02-19 9:15 ` Nicolas Escande
2026-02-19 21:37 ` Jeff Johnson
2026-02-20 9:26 ` Nicolas Escande
2026-02-23 11:21 ` Maharaja Kennadyrajan
2026-02-19 11:31 ` Pablo MARTIN-GOMEZ
2026-02-19 11:45 ` Maharaja Kennadyrajan
2026-02-19 21:44 ` Jeff Johnson
2026-02-20 9:55 ` Maharaja Kennadyrajan
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox