* [PATCH v4 00/10] Add support for Qualcomm remoteproc subsystem cooling
@ 2026-07-03 5:03 Gaurav Kohli
2026-07-03 5:03 ` [PATCH v4 01/10] dt-bindings: firmware: qcom: tmd: add TMD device type constants Gaurav Kohli
` (9 more replies)
0 siblings, 10 replies; 29+ messages in thread
From: Gaurav Kohli @ 2026-07-03 5:03 UTC (permalink / raw)
To: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Daniel Lezcano, Amit Kucheria,
Manivannan Sadhasivam, Konrad Dybcio, Gaurav Kohli, Kees Cook,
Gustavo A. R. Silva, cros-qcom-dts-watchers
Cc: linux-arm-msm, linux-remoteproc, devicetree, linux-kernel,
linux-pm, linux-hardening, Manaf Meethalavalappu Pallikunhi,
Casey Connolly, Dipa Ramesh Mantre
This series introduces Qualcomm Messaging Interface based Thermal
Mitigation Device (QMI TMD) support to control thermal mitigation
on remote subsystems such as the Modem and CDSP.
The QMI TMD is an interface that instructs a remote subsystem to adjust
the performance level of the devices it manages, reducing power consumption
in response to critically low battery charge, overcurrent alerts, or
overheating conditions.
The series is organized as follows:
- Add a shared dt-bindings header mapping TMD device indices for use
in DT cooling-maps, ensuring a consistent binding between the thermal
zone and the QMI TMD driver.
- Extend the remoteproc PAS binding with the optional #cooling-cells
property to allow remoteproc nodes to be referenced as cooling devices.
- Add QMI TMD support in the remoteproc PAS framework, hooking into
the probe/unregister lifecycle to register and unregister cooling
devices with the thermal framework.
- Enable CDSP and Modem cooling on kodiak, lemans, talos, monaco and
hamoa platforms using the new binding.
This work revives the earlier QMI cooling series by Casey Connolly [1],
with the following key differences:
- Uses an id based API for cooling-device binding
- Integrates QMI TMD directly into the remoteproc PAS framework and
hooks into the probe/unregister lifecycle.
- Removes unused code and cleans up macro names
This series depends on cooling device id support from Daniel Lezcano [2].
[1] https://lore.kernel.org/linux-devicetree/20230905-caleb-qmi_cooling-v1-0-5aa39d4164a7@linaro.org/
[2] https://lore.kernel.org/all/20260526140802.1059293-12-daniel.lezcano@oss.qualcomm.com/
---
Changes in v4:
- Drop the tmd-names DT property.
- Move TMD instance id and tmd device name into PAS platform data.
- Add a shared dt-bindings header to define numeric constant for TMD id.
- Add mutex documentation comments for get/set state callbacks.
- Link to v3: https://lore.kernel.org/r/20260609-qmi-tmd-v3-0-291a2ff4c634@oss.qualcomm.com
Changes in v3:
- Removed the remoteproc-cooling abstraction approach.
- Integerated QMI TMD with remoteproc core framework.
- Cleaned the macro names and removed unused code.
- Switched to index-based thermal_of_cooling_device_register() api.
- Link to v2: https://lore.kernel.org/linux-devicetree/20260127155722.2797783-1-gaurav.kohli@oss.qualcomm.com/
Changes in v2:
- Update Remoreproc thermal config to tristate and removed unnecessary NULL checks.
- Fixed dt binding file format and added generic name support for cdsp.
- Fixed memory leak and cleaned up qmi-cooling driver file.
- Corrected DT formatting errors and commit descriptions for all targets.
- Link to v1: https://lore.kernel.org/linux-devicetree/20251223123227.1317244-1-gaurav.kohli@oss.qualcomm.com/
---
---
Casey Connolly (1):
soc: qcom: Add QMI TMD support for remote thermal mitigation
Dipa Ramesh Mantre (1):
arm64: dts: qcom: hamoa: Enable CDSP cooling
Gaurav Kohli (8):
dt-bindings: firmware: qcom: tmd: add TMD device type constants
dt-bindings: remoteproc: qcom,pas: add #cooling-cells property
remoteproc: qcom: pas: add support for TMD thermal cooling devices
remoteproc: qcom_q6v5_pas: enable QMI TMD cooling support
arm64: dts: qcom: kodiak: Enable CDSP & Modem cooling
arm64: dts: qcom: lemans: Enable CDSP cooling
arm64: dts: qcom: talos: Enable CDSP cooling
arm64: dts: qcom: monaco: Enable CDSP cooling
.../bindings/remoteproc/qcom,pas-common.yaml | 39 ++
MAINTAINERS | 7 +
arch/arm64/boot/dts/qcom/hamoa.dtsi | 63 +++
arch/arm64/boot/dts/qcom/kodiak.dtsi | 134 ++++-
arch/arm64/boot/dts/qcom/lemans.dtsi | 125 ++++-
arch/arm64/boot/dts/qcom/monaco.dtsi | 99 ++++
.../boot/dts/qcom/qcs6490-radxa-dragon-q6a.dts | 17 +
arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts | 17 +
.../dts/qcom/qcs6490-thundercomm-minipc-g1iot.dts | 17 +
.../boot/dts/qcom/qcs6490-thundercomm-rubikpi3.dts | 17 +
.../boot/dts/qcom/sc7280-herobrine-lte-sku.dtsi | 17 +
.../boot/dts/qcom/sc7280-herobrine-wifi-sku.dtsi | 16 +
arch/arm64/boot/dts/qcom/talos.dtsi | 19 +
drivers/remoteproc/Kconfig | 1 +
drivers/remoteproc/qcom_q6v5_pas.c | 120 ++++-
drivers/soc/qcom/Kconfig | 10 +
drivers/soc/qcom/Makefile | 1 +
drivers/soc/qcom/qmi_tmd.c | 581 +++++++++++++++++++++
include/dt-bindings/firmware/qcom,qmi-tmd.h | 20 +
include/linux/soc/qcom/qmi.h | 1 +
include/linux/soc/qcom/qmi_tmd.h | 23 +
21 files changed, 1327 insertions(+), 17 deletions(-)
---
base-commit: a87737435cfa134f9cdcc696ba3080759d04cf72
change-id: 20260609-qmi-tmd-383d30e1a60a
Best regards,
--
Gaurav Kohli <gaurav.kohli@oss.qualcomm.com>
^ permalink raw reply [flat|nested] 29+ messages in thread
* [PATCH v4 01/10] dt-bindings: firmware: qcom: tmd: add TMD device type constants
2026-07-03 5:03 [PATCH v4 00/10] Add support for Qualcomm remoteproc subsystem cooling Gaurav Kohli
@ 2026-07-03 5:03 ` Gaurav Kohli
2026-07-03 7:47 ` Krzysztof Kozlowski
` (2 more replies)
2026-07-03 5:03 ` [PATCH v4 02/10] dt-bindings: remoteproc: qcom,pas: add #cooling-cells property Gaurav Kohli
` (8 subsequent siblings)
9 siblings, 3 replies; 29+ messages in thread
From: Gaurav Kohli @ 2026-07-03 5:03 UTC (permalink / raw)
To: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Daniel Lezcano, Amit Kucheria,
Manivannan Sadhasivam, Konrad Dybcio, Gaurav Kohli, Kees Cook,
Gustavo A. R. Silva, cros-qcom-dts-watchers
Cc: linux-arm-msm, linux-remoteproc, devicetree, linux-kernel,
linux-pm, linux-hardening, Manaf Meethalavalappu Pallikunhi
Add Device Tree binding constants for Qualcomm Thermal Mitigation
Device (TMD) types used by remoteproc-backed thermal cooling devices.
Qualcomm remote processors expose thermal mitigation endpoints
through QMI. These endpoints can be registered with the thermal
framework via the `#cooling-cells` property on the remoteproc node.
The QMI TMD protocol identifies devices using string names (for example,
"pa", "modem", and "cdsp_sw"), while the DT cooling-device binding with
`#cooling-cells = <3>` requires numeric device id in the form:
<&phandle device_id min_state max_state>
Define common TMD device index constants shared across currently
supported platforms. If a future target requires a different mapping,
additional target-specific constants can be introduced while preserving
existing DT ABI.
Signed-off-by: Gaurav Kohli <gaurav.kohli@oss.qualcomm.com>
---
MAINTAINERS | 1 +
include/dt-bindings/firmware/qcom,qmi-tmd.h | 20 ++++++++++++++++++++
2 files changed, 21 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index 57656ec0e9d5..ffd85fd1dd80 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3410,6 +3410,7 @@ F: drivers/firmware/qcom/
F: drivers/soc/qcom/
F: drivers/watchdog/gunyah_wdt.c
F: include/dt-bindings/arm/qcom,ids.h
+F: include/dt-bindings/firmware/qcom,qmi-tmd.h
F: include/dt-bindings/firmware/qcom,scm.h
F: include/dt-bindings/soc/qcom*
F: include/linux/firmware/qcom
diff --git a/include/dt-bindings/firmware/qcom,qmi-tmd.h b/include/dt-bindings/firmware/qcom,qmi-tmd.h
new file mode 100644
index 000000000000..73efecef0f3c
--- /dev/null
+++ b/include/dt-bindings/firmware/qcom,qmi-tmd.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */
+/*
+ * Qualcomm QMI TMD (Thermal Mitigation Device) cooling device indices
+ *
+ * These indices are used in device tree cooling-maps to reference
+ * specific TMD devices provided by remote processors via QMI.
+ *
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+#ifndef _DT_BINDINGS_FIRMWARE_QCOM_QMI_TMD_H
+#define _DT_BINDINGS_FIRMWARE_QCOM_QMI_TMD_H
+
+/* CDSP thermal mitigation device id */
+#define QCOM_CDSP_TMD_CDSP_SW 0
+
+/* Modem thermal mitigation device id */
+#define QCOM_MODEM_TMD_PA 0
+#define QCOM_MODEM_TMD_MODEM 1
+
+#endif /* _DT_BINDINGS_FIRMWARE_QCOM_QMI_TMD_H */
--
2.34.1
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH v4 02/10] dt-bindings: remoteproc: qcom,pas: add #cooling-cells property
2026-07-03 5:03 [PATCH v4 00/10] Add support for Qualcomm remoteproc subsystem cooling Gaurav Kohli
2026-07-03 5:03 ` [PATCH v4 01/10] dt-bindings: firmware: qcom: tmd: add TMD device type constants Gaurav Kohli
@ 2026-07-03 5:03 ` Gaurav Kohli
2026-07-03 5:15 ` sashiko-bot
2026-07-03 7:49 ` Krzysztof Kozlowski
2026-07-03 5:03 ` [PATCH v4 03/10] soc: qcom: Add QMI TMD support for remote thermal mitigation Gaurav Kohli
` (7 subsequent siblings)
9 siblings, 2 replies; 29+ messages in thread
From: Gaurav Kohli @ 2026-07-03 5:03 UTC (permalink / raw)
To: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Daniel Lezcano, Amit Kucheria,
Manivannan Sadhasivam, Konrad Dybcio, Gaurav Kohli, Kees Cook,
Gustavo A. R. Silva, cros-qcom-dts-watchers
Cc: linux-arm-msm, linux-remoteproc, devicetree, linux-kernel,
linux-pm, linux-hardening, Manaf Meethalavalappu Pallikunhi
Document the optional #cooling-cells property for Qualcomm PAS
remoteproc nodes so they can be used as thermal cooling devices via
the QMI Thermal Mitigation Device (TMD) interface.
Qualcomm remote processors expose TMD endpoints that support thermal
throttling through firmware. The cooling-device specifier uses 3 cells:
<&phandle device_id min_state max_state>
where device_index selects the TMD endpoint (for example PA, modem,
or CDSP software mitigation), with constants defined in:
- dt-bindings/firmware/qcom,qmi-tmd.h
Signed-off-by: Gaurav Kohli <gaurav.kohli@oss.qualcomm.com>
---
.../bindings/remoteproc/qcom,pas-common.yaml | 39 ++++++++++++++++++++++
1 file changed, 39 insertions(+)
diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,pas-common.yaml b/Documentation/devicetree/bindings/remoteproc/qcom,pas-common.yaml
index 4607b459131b..ef11371058c4 100644
--- a/Documentation/devicetree/bindings/remoteproc/qcom,pas-common.yaml
+++ b/Documentation/devicetree/bindings/remoteproc/qcom,pas-common.yaml
@@ -79,6 +79,14 @@ properties:
channels and devices related to the ADSP.
unevaluatedProperties: false
+ '#cooling-cells':
+ description: |
+ Cooling device with three cells:
+ Cell 0: Cooling device id
+ Cell 1: Minimum cooling state
+ Cell 2: Maximum cooling state
+ const: 3
+
glink-edge:
$ref: /schemas/remoteproc/qcom,glink-edge.yaml#
description:
@@ -95,3 +103,34 @@ required:
- qcom,smem-state-names
additionalProperties: true
+
+examples:
+ - |
+ #include <dt-bindings/thermal/thermal.h>
+ #include <dt-bindings/firmware/qcom,qmi-tmd.h>
+
+ remoteproc: remoteproc {
+ #cooling-cells = <3>;
+ };
+
+ thermal-zones {
+ subsystem-thermal {
+ thermal-sensors = <&tsens 0>;
+
+ trips {
+ alert: alert {
+ temperature = <95000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+ };
+
+ cooling-maps {
+ map0 {
+ trip = <&alert>;
+ cooling-device = <&remoteproc QCOM_CDSP_TMD_CDSP_SW
+ THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+ };
+ };
--
2.34.1
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH v4 03/10] soc: qcom: Add QMI TMD support for remote thermal mitigation
2026-07-03 5:03 [PATCH v4 00/10] Add support for Qualcomm remoteproc subsystem cooling Gaurav Kohli
2026-07-03 5:03 ` [PATCH v4 01/10] dt-bindings: firmware: qcom: tmd: add TMD device type constants Gaurav Kohli
2026-07-03 5:03 ` [PATCH v4 02/10] dt-bindings: remoteproc: qcom,pas: add #cooling-cells property Gaurav Kohli
@ 2026-07-03 5:03 ` Gaurav Kohli
2026-07-03 5:17 ` sashiko-bot
` (2 more replies)
2026-07-03 5:03 ` [PATCH v4 04/10] remoteproc: qcom: pas: add support for TMD thermal cooling devices Gaurav Kohli
` (6 subsequent siblings)
9 siblings, 3 replies; 29+ messages in thread
From: Gaurav Kohli @ 2026-07-03 5:03 UTC (permalink / raw)
To: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Daniel Lezcano, Amit Kucheria,
Manivannan Sadhasivam, Konrad Dybcio, Gaurav Kohli, Kees Cook,
Gustavo A. R. Silva, cros-qcom-dts-watchers
Cc: linux-arm-msm, linux-remoteproc, devicetree, linux-kernel,
linux-pm, linux-hardening, Manaf Meethalavalappu Pallikunhi,
Casey Connolly
From: Casey Connolly <casey.connolly@linaro.org>
Add support for Qualcomm Messaging Interface (QMI) based Thermal Mitigation
Device (TMD) cooling devices provided by remote subsystems.
On Qualcomm platforms where remote processors expose mitigation controls
through the TMD QMI service, client drivers need support to discover the
service, register cooling devices for available mitigation endpoints,
and forward cooling state updates to remote subsystems.
Signed-off-by: Casey Connolly <casey.connolly@linaro.org>
Co-developed-by: Daniel Lezcano <daniel.lezcano@oss.qualcomm.com>
Signed-off-by: Daniel Lezcano <daniel.lezcano@oss.qualcomm.com>
Co-developed-by: Gaurav Kohli <gaurav.kohli@oss.qualcomm.com>
Signed-off-by: Gaurav Kohli <gaurav.kohli@oss.qualcomm.com>
---
MAINTAINERS | 6 +
drivers/soc/qcom/Kconfig | 10 +
drivers/soc/qcom/Makefile | 1 +
drivers/soc/qcom/qmi_tmd.c | 581 +++++++++++++++++++++++++++++++++++++++
include/linux/soc/qcom/qmi.h | 1 +
include/linux/soc/qcom/qmi_tmd.h | 23 ++
6 files changed, 622 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index ffd85fd1dd80..251b1f583913 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -22287,6 +22287,12 @@ F: Documentation/devicetree/bindings/net/qcom,ipq9574-ppe.yaml
F: Documentation/networking/device_drivers/ethernet/qualcomm/ppe/ppe.rst
F: drivers/net/ethernet/qualcomm/ppe/
+QUALCOMM QMI (REMOTEPROC THERMAL MITIGATION) TMD
+M: Gaurav Kohli <gaurav.kohli@oss.qualcomm.com>
+L: linux-arm-msm@vger.kernel.org
+L: linux-pm@vger.kernel.org
+F: drivers/soc/qcom/qmi_tmd.c
+
QUALCOMM QSEECOM DRIVER
M: Maximilian Luz <luzmaximilian@gmail.com>
L: linux-arm-msm@vger.kernel.org
diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
index 2caadbbcf830..44c2b533b494 100644
--- a/drivers/soc/qcom/Kconfig
+++ b/drivers/soc/qcom/Kconfig
@@ -128,6 +128,16 @@ config QCOM_QMI_HELPERS
tristate
depends on NET
+config QCOM_QMI_TMD
+ bool "Qualcomm remote subsystem TMD" if COMPILE_TEST
+ depends on ARCH_QCOM
+ select QCOM_QMI_HELPERS
+ help
+ This enables Qualcomm Messaging Interface (QMI) based Thermal Mitigation
+ Device (TMD) support for Qualcomm remote subsystems. It manages
+ TMD messaging and handles QMI communication with remote processors
+ to exchange mitigation state and apply thermal mitigation requests.
+
config QCOM_RAMP_CTRL
tristate "Qualcomm Ramp Controller driver"
depends on ARCH_QCOM || COMPILE_TEST
diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile
index b7f1d2a57367..4544e61c74e7 100644
--- a/drivers/soc/qcom/Makefile
+++ b/drivers/soc/qcom/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_QCOM_PMIC_GLINK) += pmic_glink.o
obj-$(CONFIG_QCOM_PMIC_GLINK) += pmic_glink_altmode.o
obj-$(CONFIG_QCOM_PMIC_PDCHARGER_ULOG) += pmic_pdcharger_ulog.o
CFLAGS_pmic_pdcharger_ulog.o := -I$(src)
+obj-$(CONFIG_QCOM_QMI_TMD) += qmi_tmd.o
obj-$(CONFIG_QCOM_QMI_HELPERS) += qmi_helpers.o
qmi_helpers-y += qmi_encdec.o qmi_interface.o
obj-$(CONFIG_QCOM_RAMP_CTRL) += ramp_controller.o
diff --git a/drivers/soc/qcom/qmi_tmd.c b/drivers/soc/qcom/qmi_tmd.c
new file mode 100644
index 000000000000..d82500415f8e
--- /dev/null
+++ b/drivers/soc/qcom/qmi_tmd.c
@@ -0,0 +1,581 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2025, Linaro Limited
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ *
+ * QMI Thermal Mitigation Device (TMD).
+ * Provides cooling device support for remote subsystems
+ * running the TMD service via QMI.
+ */
+#include <linux/cleanup.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/net.h>
+#include <linux/of.h>
+#include <linux/slab.h>
+#include <linux/soc/qcom/qmi.h>
+#include <linux/soc/qcom/qmi_tmd.h>
+#include <linux/thermal.h>
+
+#define QMI_TMD_SERVICE_VERS_V01 0x01
+
+#define QMI_TMD_SET_LEVEL_REQ 0x0021
+#define QMI_TMD_GET_DEV_LIST_REQ 0x0020
+
+#define QMI_TMD_DEV_ID_LEN_MAX 32
+#define QMI_TMD_DEV_LIST_MAX 32
+#define QMI_TMD_RESP_TIMEOUT msecs_to_jiffies(100)
+#define TMD_GET_LEVEL_REQ_MAX_LEN 36
+#define TMD_SET_LEVEL_REQ_MAX_LEN 40
+
+#define TMD_GET_DEV_LIST_REQ_MAX_LEN 0
+#define TMD_GET_DEV_LIST_RESP_MAX_LEN 1099
+
+struct tmd_dev_id {
+ char mitigation_dev_id[QMI_TMD_DEV_ID_LEN_MAX + 1];
+};
+
+static const struct qmi_elem_info tmd_dev_id_ei[] = {
+ {
+ .data_type = QMI_STRING,
+ .elem_len = QMI_TMD_DEV_ID_LEN_MAX + 1,
+ .elem_size = sizeof(char),
+ .array_type = NO_ARRAY,
+ .tlv_type = 0,
+ .offset = offsetof(struct tmd_dev_id,
+ mitigation_dev_id),
+ },
+ {
+ .data_type = QMI_EOTI,
+ .array_type = NO_ARRAY,
+ .tlv_type = QMI_COMMON_TLV_TYPE,
+ },
+};
+
+struct tmd_dev_list {
+ struct tmd_dev_id mitigation_dev_id;
+ u8 max_mitigation_level;
+};
+
+static const struct qmi_elem_info tmd_dev_list_ei[] = {
+ {
+ .data_type = QMI_STRUCT,
+ .elem_len = 1,
+ .elem_size = sizeof(struct tmd_dev_id),
+ .array_type = NO_ARRAY,
+ .tlv_type = 0,
+ .offset = offsetof(struct tmd_dev_list,
+ mitigation_dev_id),
+ .ei_array = tmd_dev_id_ei,
+ },
+ {
+ .data_type = QMI_UNSIGNED_1_BYTE,
+ .elem_len = 1,
+ .elem_size = sizeof(uint8_t),
+ .array_type = NO_ARRAY,
+ .tlv_type = 0,
+ .offset = offsetof(struct tmd_dev_list,
+ max_mitigation_level),
+ },
+ {
+ .data_type = QMI_EOTI,
+ .array_type = NO_ARRAY,
+ .tlv_type = QMI_COMMON_TLV_TYPE,
+ },
+};
+
+struct tmd_get_dev_list_req {
+ char placeholder;
+};
+
+static const struct qmi_elem_info tmd_get_dev_list_req_ei[] = {
+ {
+ .data_type = QMI_EOTI,
+ .array_type = NO_ARRAY,
+ .tlv_type = QMI_COMMON_TLV_TYPE,
+ },
+};
+
+struct tmd_get_dev_list_resp {
+ struct qmi_response_type_v01 resp;
+ u8 mitigation_device_list_valid;
+ u32 mitigation_device_list_len;
+ struct tmd_dev_list
+ mitigation_device_list[QMI_TMD_DEV_LIST_MAX];
+};
+
+static const struct qmi_elem_info tmd_get_dev_list_resp_ei[] = {
+ {
+ .data_type = QMI_STRUCT,
+ .elem_len = 1,
+ .elem_size = sizeof(struct qmi_response_type_v01),
+ .array_type = NO_ARRAY,
+ .tlv_type = 0x02,
+ .offset = offsetof(struct tmd_get_dev_list_resp,
+ resp),
+ .ei_array = qmi_response_type_v01_ei,
+ },
+ {
+ .data_type = QMI_OPT_FLAG,
+ .elem_len = 1,
+ .elem_size = sizeof(uint8_t),
+ .array_type = NO_ARRAY,
+ .tlv_type = 0x10,
+ .offset = offsetof(struct tmd_get_dev_list_resp,
+ mitigation_device_list_valid),
+ },
+ {
+ .data_type = QMI_DATA_LEN,
+ .elem_len = 1,
+ .elem_size = sizeof(uint8_t),
+ .array_type = NO_ARRAY,
+ .tlv_type = 0x10,
+ .offset = offsetof(struct tmd_get_dev_list_resp,
+ mitigation_device_list_len),
+ },
+ {
+ .data_type = QMI_STRUCT,
+ .elem_len = QMI_TMD_DEV_LIST_MAX,
+ .elem_size = sizeof(struct tmd_dev_list),
+ .array_type = VAR_LEN_ARRAY,
+ .tlv_type = 0x10,
+ .offset = offsetof(struct tmd_get_dev_list_resp,
+ mitigation_device_list),
+ .ei_array = tmd_dev_list_ei,
+ },
+ {
+ .data_type = QMI_EOTI,
+ .array_type = NO_ARRAY,
+ .tlv_type = QMI_COMMON_TLV_TYPE,
+ },
+};
+
+struct tmd_set_level_req {
+ struct tmd_dev_id mitigation_dev_id;
+ u8 mitigation_level;
+};
+
+static const struct qmi_elem_info tmd_set_level_req_ei[] = {
+ {
+ .data_type = QMI_STRUCT,
+ .elem_len = 1,
+ .elem_size = sizeof(struct tmd_dev_id),
+ .array_type = NO_ARRAY,
+ .tlv_type = 0x01,
+ .offset = offsetof(struct tmd_set_level_req,
+ mitigation_dev_id),
+ .ei_array = tmd_dev_id_ei,
+ },
+ {
+ .data_type = QMI_UNSIGNED_1_BYTE,
+ .elem_len = 1,
+ .elem_size = sizeof(uint8_t),
+ .array_type = NO_ARRAY,
+ .tlv_type = 0x02,
+ .offset = offsetof(struct tmd_set_level_req,
+ mitigation_level),
+ },
+ {
+ .data_type = QMI_EOTI,
+ .array_type = NO_ARRAY,
+ .tlv_type = QMI_COMMON_TLV_TYPE,
+ },
+};
+
+struct tmd_set_level_resp {
+ struct qmi_response_type_v01 resp;
+};
+
+static const struct qmi_elem_info tmd_set_level_resp_ei[] = {
+ {
+ .data_type = QMI_STRUCT,
+ .elem_len = 1,
+ .elem_size = sizeof(struct qmi_response_type_v01),
+ .array_type = NO_ARRAY,
+ .tlv_type = 0x02,
+ .offset = offsetof(struct tmd_set_level_resp, resp),
+ .ei_array = qmi_response_type_v01_ei,
+ },
+ {
+ .data_type = QMI_EOTI,
+ .array_type = NO_ARRAY,
+ .tlv_type = QMI_COMMON_TLV_TYPE,
+ },
+};
+
+/**
+ * struct qmi_tmd - A TMD cooling device
+ * @name: The name of this tmd shared by the remote subsystem
+ * @cdev: Thermal cooling device handle
+ * @cur_state: The current mitigation state
+ * @max_state: The maximum state
+ * @qmi_tmd_cli: Parent QMI TMD client
+ */
+struct qmi_tmd {
+ const char *name;
+ struct thermal_cooling_device *cdev;
+ unsigned int cur_state;
+ unsigned int max_state;
+ struct qmi_tmd_client *qmi_tmd_cli;
+};
+
+/**
+ * struct qmi_tmd_client - QMI TMD client state
+ * @dev: Device associated with this instance
+ * @handle: QMI connection handle
+ * @mutex: Serializes QMI request/response sequences (qmi_txn_init,
+ * qmi_send_request) during DSP subsystem restart and
+ * protects @connection_active flag
+ * @connection_active: Whether or not we're connected to the QMI TMD service
+ * @svc_arrive_work: Work item for initialising when the TMD service starts
+ * @num_tmds: Number of tmds described in the device tree
+ * @tmds: An array of tmd structures
+ */
+struct qmi_tmd_client {
+ struct device *dev;
+ struct qmi_handle handle;
+ /* protects QMI transactions and connection_active */
+ struct mutex mutex;
+ bool connection_active;
+ struct work_struct svc_arrive_work;
+ int num_tmds;
+ struct qmi_tmd tmds[] __counted_by(num_tmds);
+};
+
+/* Notify the remote subsystem of the requested cooling state */
+static int qmi_tmd_send_state_request(struct qmi_tmd *tmd, int state)
+{
+ struct tmd_set_level_resp resp = { 0 };
+ struct tmd_set_level_req req = { 0 };
+ struct qmi_tmd_client *qmi_tmd_cli = tmd->qmi_tmd_cli;
+ struct qmi_txn txn;
+ int ret = 0;
+
+ guard(mutex)(&qmi_tmd_cli->mutex);
+
+ if (!qmi_tmd_cli->connection_active)
+ return 0;
+
+ strscpy(req.mitigation_dev_id.mitigation_dev_id, tmd->name,
+ QMI_TMD_DEV_ID_LEN_MAX + 1);
+ req.mitigation_level = state;
+
+ ret = qmi_txn_init(&qmi_tmd_cli->handle, &txn,
+ tmd_set_level_resp_ei, &resp);
+ if (ret < 0) {
+ dev_err(qmi_tmd_cli->dev, "qmi set state %d txn init failed for %s ret %d\n",
+ state, tmd->name, ret);
+ return ret;
+ }
+
+ ret = qmi_send_request(&qmi_tmd_cli->handle, NULL, &txn,
+ QMI_TMD_SET_LEVEL_REQ,
+ TMD_SET_LEVEL_REQ_MAX_LEN,
+ tmd_set_level_req_ei, &req);
+ if (ret < 0) {
+ dev_err(qmi_tmd_cli->dev, "qmi set state %d txn send failed for %s ret %d\n",
+ state, tmd->name, ret);
+ qmi_txn_cancel(&txn);
+ return ret;
+ }
+
+ ret = qmi_txn_wait(&txn, QMI_TMD_RESP_TIMEOUT);
+ if (ret < 0) {
+ dev_err(qmi_tmd_cli->dev, "qmi set state %d txn wait failed for %s ret %d\n",
+ state, tmd->name, ret);
+ return ret;
+ }
+
+ if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
+ dev_err(qmi_tmd_cli->dev,
+ "qmi set state %d failed for %s result %#x error %#x\n",
+ state, tmd->name,
+ resp.resp.result, resp.resp.error);
+ return -EREMOTEIO;
+ }
+
+ dev_dbg(qmi_tmd_cli->dev, "Requested state %d/%d for %s\n", state,
+ tmd->max_state, tmd->name);
+
+ return 0;
+}
+
+static int qmi_tmd_get_max_state(struct thermal_cooling_device *cdev,
+ unsigned long *state)
+{
+ struct qmi_tmd *tmd = cdev->devdata;
+
+ *state = tmd->max_state;
+
+ return 0;
+}
+
+static int qmi_tmd_get_cur_state(struct thermal_cooling_device *cdev,
+ unsigned long *state)
+{
+ struct qmi_tmd *tmd = cdev->devdata;
+
+ /* cur_state is protected by thermal core's cdev->lock */
+ *state = tmd->cur_state;
+
+ return 0;
+}
+
+static int qmi_tmd_set_cur_state(struct thermal_cooling_device *cdev,
+ unsigned long state)
+{
+ struct qmi_tmd *tmd = cdev->devdata;
+ int ret;
+
+ if (state > tmd->max_state)
+ return -EINVAL;
+
+ /* cur_state is protected by thermal core's cdev->lock */
+ if (tmd->cur_state == state)
+ return 0;
+
+ ret = qmi_tmd_send_state_request(tmd, state);
+ if (!ret)
+ tmd->cur_state = state;
+
+ return ret;
+}
+
+static const struct thermal_cooling_device_ops qmi_tmd_cooling_ops = {
+ .get_max_state = qmi_tmd_get_max_state,
+ .get_cur_state = qmi_tmd_get_cur_state,
+ .set_cur_state = qmi_tmd_set_cur_state,
+};
+
+static int qmi_tmd_register(struct qmi_tmd_client *qmi_tmd_cli,
+ const char *label, u8 max_state)
+{
+ struct device *dev = qmi_tmd_cli->dev;
+ struct qmi_tmd *tmd;
+ int index;
+
+ for (index = 0; index < qmi_tmd_cli->num_tmds; index++) {
+ tmd = &qmi_tmd_cli->tmds[index];
+
+ if (!strncasecmp(tmd->name, label,
+ QMI_TMD_DEV_ID_LEN_MAX + 1))
+ goto found;
+ }
+
+ dev_dbg(qmi_tmd_cli->dev,
+ "TMD '%s' available in firmware but not specified in DT\n",
+ label);
+ return 0;
+
+found:
+ tmd->max_state = max_state;
+
+ /*
+ * If the cooling device already exists then the QMI service went away and
+ * came back. So just make sure the current cooling device state is
+ * reflected on the remote side and then return.
+ */
+ if (tmd->cdev)
+ return qmi_tmd_send_state_request(tmd, tmd->cur_state);
+
+ tmd->cdev = thermal_of_cooling_device_register(dev->of_node, index,
+ label, tmd, &qmi_tmd_cooling_ops);
+ if (IS_ERR(tmd->cdev))
+ return PTR_ERR(tmd->cdev);
+
+ return 0;
+}
+
+static void qmi_tmd_unregister(struct qmi_tmd_client *qmi_tmd_cli)
+{
+ struct qmi_tmd *tmd;
+ int index;
+
+ for (index = 0; index < qmi_tmd_cli->num_tmds; index++) {
+ tmd = &qmi_tmd_cli->tmds[index];
+
+ if (!tmd->cdev)
+ continue;
+
+ thermal_cooling_device_unregister(tmd->cdev);
+ tmd->cdev = NULL;
+ }
+}
+
+static void qmi_tmd_svc_arrive(struct work_struct *work)
+{
+ struct qmi_tmd_client *qmi_tmd_cli =
+ container_of(work, struct qmi_tmd_client, svc_arrive_work);
+
+ struct tmd_get_dev_list_req req = { 0 };
+ struct tmd_get_dev_list_resp *resp __free(kfree) = NULL;
+ int ret, i;
+ struct qmi_txn txn;
+
+ resp = kzalloc_obj(*resp, GFP_KERNEL);
+ if (!resp) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ scoped_guard(mutex, &qmi_tmd_cli->mutex) {
+ ret = qmi_txn_init(&qmi_tmd_cli->handle, &txn,
+ tmd_get_dev_list_resp_ei, resp);
+ if (ret < 0)
+ goto out;
+
+ ret = qmi_send_request(&qmi_tmd_cli->handle, NULL, &txn,
+ QMI_TMD_GET_DEV_LIST_REQ,
+ TMD_GET_DEV_LIST_REQ_MAX_LEN,
+ tmd_get_dev_list_req_ei, &req);
+ if (ret < 0) {
+ qmi_txn_cancel(&txn);
+ goto out;
+ }
+
+ ret = qmi_txn_wait(&txn, QMI_TMD_RESP_TIMEOUT);
+ if (ret < 0)
+ goto out;
+
+ if (resp->resp.result != QMI_RESULT_SUCCESS_V01) {
+ ret = -EPROTO;
+ goto out;
+ }
+
+ qmi_tmd_cli->connection_active = true;
+ }
+
+ for (i = 0; i < resp->mitigation_device_list_len; i++) {
+ struct tmd_dev_list *device =
+ &resp->mitigation_device_list[i];
+
+ ret = qmi_tmd_register(qmi_tmd_cli,
+ device->mitigation_dev_id.mitigation_dev_id,
+ device->max_mitigation_level);
+ if (ret)
+ break;
+ }
+
+out:
+ if (ret)
+ dev_err(qmi_tmd_cli->dev, "Failed to initialize TMD service: %d\n", ret);
+}
+
+static void qmi_tmd_del_server(struct qmi_handle *qmi, struct qmi_service *service)
+{
+ struct qmi_tmd_client *qmi_tmd_cli =
+ container_of(qmi, struct qmi_tmd_client, handle);
+
+ scoped_guard(mutex, &qmi_tmd_cli->mutex) {
+ qmi_tmd_cli->connection_active = false;
+ }
+}
+
+static int qmi_tmd_new_server(struct qmi_handle *qmi, struct qmi_service *service)
+{
+ struct sockaddr_qrtr sq = { AF_QIPCRTR, service->node, service->port };
+ struct qmi_tmd_client *qmi_tmd_cli;
+ int ret;
+
+ qmi_tmd_cli = container_of(qmi, struct qmi_tmd_client, handle);
+
+ scoped_guard(mutex, &qmi_tmd_cli->mutex) {
+ ret = kernel_connect(qmi->sock, (struct sockaddr_unsized *)&sq,
+ sizeof(sq), 0);
+ }
+
+ if (ret < 0) {
+ dev_err(qmi_tmd_cli->dev, "QMI connect failed for node %u port %u: %d\n",
+ service->node, service->port, ret);
+ return ret;
+ }
+
+ queue_work(system_highpri_wq, &qmi_tmd_cli->svc_arrive_work);
+
+ return 0;
+}
+
+static const struct qmi_ops qmi_tmd_ops = {
+ .new_server = qmi_tmd_new_server,
+ .del_server = qmi_tmd_del_server,
+};
+
+/**
+ * qmi_tmd_init() - Initialize QMI TMD instance
+ * @dev: Device pointer
+ * @instance_id: QMI service instance ID for the remote subsystem
+ * @tmd_names: Array of TMD names
+ * @num_tmds: Number of TMD names
+ *
+ * Return: Pointer to qmi_tmd_client on success, ERR_PTR on failure
+ */
+struct qmi_tmd_client *qmi_tmd_init(struct device *dev,
+ unsigned int instance_id,
+ const char * const *tmd_names,
+ int num_tmds)
+{
+ struct qmi_tmd_client *qmi_tmd_cli;
+ int ret, i;
+
+ if (!dev || !tmd_names || num_tmds <= 0)
+ return ERR_PTR(-EINVAL);
+
+ qmi_tmd_cli = devm_kzalloc(dev, struct_size(qmi_tmd_cli, tmds, num_tmds), GFP_KERNEL);
+ if (!qmi_tmd_cli)
+ return ERR_PTR(-ENOMEM);
+
+ qmi_tmd_cli->dev = dev;
+ qmi_tmd_cli->num_tmds = num_tmds;
+ mutex_init(&qmi_tmd_cli->mutex);
+ INIT_WORK(&qmi_tmd_cli->svc_arrive_work, qmi_tmd_svc_arrive);
+
+ for (i = 0; i < num_tmds; i++) {
+ qmi_tmd_cli->tmds[i].name = tmd_names[i];
+ qmi_tmd_cli->tmds[i].qmi_tmd_cli = qmi_tmd_cli;
+ }
+
+ ret = qmi_handle_init(&qmi_tmd_cli->handle,
+ TMD_GET_DEV_LIST_RESP_MAX_LEN,
+ &qmi_tmd_ops, NULL);
+ if (ret < 0) {
+ dev_err(dev, "QMI handle init failed: %d\n", ret);
+ return ERR_PTR(ret);
+ }
+
+ ret = qmi_add_lookup(&qmi_tmd_cli->handle, QMI_SERVICE_ID_TMD,
+ QMI_TMD_SERVICE_VERS_V01, instance_id);
+ if (ret < 0) {
+ dev_err(dev, "QMI add lookup failed: %d\n", ret);
+ goto err_release_handle;
+ }
+
+ return qmi_tmd_cli;
+
+err_release_handle:
+ qmi_handle_release(&qmi_tmd_cli->handle);
+
+ return ERR_PTR(ret);
+}
+EXPORT_SYMBOL_GPL(qmi_tmd_init);
+
+/**
+ * qmi_tmd_exit() - Deinitialize QMI TMD instance
+ * @qmi_tmd_cli: QMI TMD client to deinitialize
+ */
+void qmi_tmd_exit(struct qmi_tmd_client *qmi_tmd_cli)
+{
+ if (!qmi_tmd_cli)
+ return;
+
+ cancel_work_sync(&qmi_tmd_cli->svc_arrive_work);
+ qmi_handle_release(&qmi_tmd_cli->handle);
+ qmi_tmd_unregister(qmi_tmd_cli);
+
+ scoped_guard(mutex, &qmi_tmd_cli->mutex)
+ qmi_tmd_cli->connection_active = false;
+}
+EXPORT_SYMBOL_GPL(qmi_tmd_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Qualcomm QMI Thermal Mitigation support");
diff --git a/include/linux/soc/qcom/qmi.h b/include/linux/soc/qcom/qmi.h
index b9dcb437a0be..683d27cee413 100644
--- a/include/linux/soc/qcom/qmi.h
+++ b/include/linux/soc/qcom/qmi.h
@@ -96,6 +96,7 @@ struct qmi_elem_info {
* Enumerate the IDs of the QMI services
*/
#define QMI_SERVICE_ID_TEST 0x0f /* 15 */
+#define QMI_SERVICE_ID_TMD 0x18 /* 24 */
#define QMI_SERVICE_ID_SSCTL 0x2b /* 43 */
#define QMI_SERVICE_ID_IPA 0x31 /* 49 */
#define QMI_SERVICE_ID_SERVREG_LOC 0x40 /* 64 */
diff --git a/include/linux/soc/qcom/qmi_tmd.h b/include/linux/soc/qcom/qmi_tmd.h
new file mode 100644
index 000000000000..d2a1308d831d
--- /dev/null
+++ b/include/linux/soc/qcom/qmi_tmd.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2025, Linaro Limited
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ *
+ * QMI Thermal Mitigation Device (TMD) library header.
+ */
+
+#ifndef __QMI_TMD_H__
+#define __QMI_TMD_H__
+
+struct device;
+struct qmi_tmd_client;
+
+struct qmi_tmd_client *qmi_tmd_init(struct device *dev,
+ unsigned int instance_id,
+ const char * const *tmd_names,
+ int num_tmds);
+
+void qmi_tmd_exit(struct qmi_tmd_client *tmd_cli);
+
+#endif /* __QMI_TMD_H__ */
+
--
2.34.1
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH v4 04/10] remoteproc: qcom: pas: add support for TMD thermal cooling devices
2026-07-03 5:03 [PATCH v4 00/10] Add support for Qualcomm remoteproc subsystem cooling Gaurav Kohli
` (2 preceding siblings ...)
2026-07-03 5:03 ` [PATCH v4 03/10] soc: qcom: Add QMI TMD support for remote thermal mitigation Gaurav Kohli
@ 2026-07-03 5:03 ` Gaurav Kohli
2026-07-03 5:22 ` sashiko-bot
2026-07-03 7:56 ` Krzysztof Kozlowski
2026-07-03 5:03 ` [PATCH v4 05/10] remoteproc: qcom_q6v5_pas: enable QMI TMD cooling support Gaurav Kohli
` (5 subsequent siblings)
9 siblings, 2 replies; 29+ messages in thread
From: Gaurav Kohli @ 2026-07-03 5:03 UTC (permalink / raw)
To: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Daniel Lezcano, Amit Kucheria,
Manivannan Sadhasivam, Konrad Dybcio, Gaurav Kohli, Kees Cook,
Gustavo A. R. Silva, cros-qcom-dts-watchers
Cc: linux-arm-msm, linux-remoteproc, devicetree, linux-kernel,
linux-pm, linux-hardening, Manaf Meethalavalappu Pallikunhi
Register Thermal Mitigation Devices (TMDs) for PAS-managed remote
processors to enable thermal throttling through QMI.
This allows the thermal framework to request mitigation when remote
subsystems such as modem and CDSP contribute to thermal pressure.
Signed-off-by: Gaurav Kohli <gaurav.kohli@oss.qualcomm.com>
---
drivers/remoteproc/Kconfig | 1 +
drivers/remoteproc/qcom_q6v5_pas.c | 93 +++++++++++++++++++++++++++++++++++++-
2 files changed, 93 insertions(+), 1 deletion(-)
diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
index c78e431b7b2d..cd8cc911e1be 100644
--- a/drivers/remoteproc/Kconfig
+++ b/drivers/remoteproc/Kconfig
@@ -228,6 +228,7 @@ config QCOM_Q6V5_PAS
select QCOM_PIL_INFO
select QCOM_MDT_LOADER
select QCOM_Q6V5_COMMON
+ select QCOM_QMI_TMD
select QCOM_RPROC_COMMON
select QCOM_SCM
help
diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c
index da27d1d3c9da..ab5bcccc91a6 100644
--- a/drivers/remoteproc/qcom_q6v5_pas.c
+++ b/drivers/remoteproc/qcom_q6v5_pas.c
@@ -5,6 +5,7 @@
* Copyright (C) 2016 Linaro Ltd
* Copyright (C) 2014 Sony Mobile Communications AB
* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#include <linux/clk.h>
@@ -24,8 +25,10 @@
#include <linux/regulator/consumer.h>
#include <linux/remoteproc.h>
#include <linux/soc/qcom/mdt_loader.h>
+#include <linux/soc/qcom/qmi_tmd.h>
#include <linux/soc/qcom/smem.h>
#include <linux/soc/qcom/smem_state.h>
+#include <dt-bindings/firmware/qcom,qmi-tmd.h>
#include "qcom_common.h"
#include "qcom_pil_info.h"
@@ -36,6 +39,16 @@
#define MAX_ASSIGN_COUNT 3
+/**
+ * struct tmd_name - TMD device name to cooling-device index mapping
+ * @name: TMD device name
+ * @id: Cooling-device index used as #cooling-cells cell 0 in DT
+ */
+struct tmd_name {
+ const char *name;
+ int id;
+};
+
struct qcom_pas_data {
int crash_reason_smem;
const char *firmware_name;
@@ -56,6 +69,10 @@ struct qcom_pas_data {
int ssctl_id;
unsigned int smem_host_id;
+ unsigned int tmd_instance_id;
+ const struct tmd_name *tmd_name;
+ int num_tmd;
+
int region_assign_idx;
int region_assign_count;
bool region_assign_shared;
@@ -120,6 +137,8 @@ struct qcom_pas {
struct qcom_scm_pas_context *pas_ctx;
struct qcom_scm_pas_context *dtb_pas_ctx;
+
+ struct qmi_tmd_client *tmd_inst;
};
static void qcom_pas_segment_dump(struct rproc *rproc,
@@ -733,6 +752,66 @@ static void qcom_pas_unassign_memory_region(struct qcom_pas *pas)
}
}
+static int qcom_pas_setup_tmd(struct qcom_pas *pas, const struct qcom_pas_data *desc)
+{
+ struct qmi_tmd_client *tmd_inst;
+ const struct tmd_name *tmd;
+ const char **tmd_names;
+ int i, ret;
+
+ if (!device_property_present(pas->dev, "#cooling-cells"))
+ return 0;
+
+ /* Check if TMD mappings are defined */
+ if (!desc->tmd_name || desc->num_tmd == 0)
+ return 0;
+
+ tmd_names = devm_kcalloc(pas->dev, desc->num_tmd,
+ sizeof(*tmd_names), GFP_KERNEL);
+ if (!tmd_names)
+ return -ENOMEM;
+
+ /* Build the name array from the TMD mappings */
+ for (i = 0; i < desc->num_tmd; i++) {
+ tmd = &desc->tmd_name[i];
+
+ if (tmd->id < 0 || tmd->id >= desc->num_tmd) {
+ dev_err(pas->dev, "Invalid TMD id %d for '%s'\n",
+ tmd->id, tmd->name);
+ return -EINVAL;
+ }
+
+ if (tmd_names[tmd->id]) {
+ dev_err(pas->dev, "Duplicate TMD id %d for '%s'\n",
+ tmd->id, tmd->name);
+ return -EINVAL;
+ }
+
+ tmd_names[tmd->id] = tmd->name;
+ }
+
+ for (i = 0; i < desc->num_tmd; i++) {
+ if (!tmd_names[i]) {
+ dev_err(pas->dev, "Missing TMD mapping for id %d\n", i);
+ return -EINVAL;
+ }
+ }
+
+ tmd_inst = qmi_tmd_init(pas->dev, desc->tmd_instance_id, tmd_names, desc->num_tmd);
+ if (IS_ERR(tmd_inst)) {
+ ret = PTR_ERR(tmd_inst);
+ if (ret == -ENODEV)
+ return 0;
+
+ dev_err(pas->dev, "Failed to initialize TMD: %d\n", ret);
+ return ret;
+ }
+
+ pas->tmd_inst = tmd_inst;
+
+ return 0;
+}
+
static int qcom_pas_probe(struct platform_device *pdev)
{
const struct qcom_pas_data *desc;
@@ -855,12 +934,21 @@ static int qcom_pas_probe(struct platform_device *pdev)
pas->pas_ctx->use_tzmem = rproc->has_iommu;
pas->dtb_pas_ctx->use_tzmem = rproc->has_iommu;
- ret = rproc_add(rproc);
+
+ ret = qcom_pas_setup_tmd(pas, desc);
if (ret)
goto remove_ssr_sysmon;
+ ret = rproc_add(rproc);
+ if (ret)
+ goto remove_setup_tmd;
+
return 0;
+remove_setup_tmd:
+ if (pas->tmd_inst)
+ qmi_tmd_exit(pas->tmd_inst);
+
remove_ssr_sysmon:
qcom_remove_ssr_subdev(rproc, &pas->ssr_subdev);
qcom_remove_sysmon_subdev(pas->sysmon);
@@ -883,6 +971,9 @@ static void qcom_pas_remove(struct platform_device *pdev)
{
struct qcom_pas *pas = platform_get_drvdata(pdev);
+ if (pas->tmd_inst)
+ qmi_tmd_exit(pas->tmd_inst);
+
rproc_del(pas->rproc);
qcom_q6v5_deinit(&pas->q6v5);
--
2.34.1
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH v4 05/10] remoteproc: qcom_q6v5_pas: enable QMI TMD cooling support
2026-07-03 5:03 [PATCH v4 00/10] Add support for Qualcomm remoteproc subsystem cooling Gaurav Kohli
` (3 preceding siblings ...)
2026-07-03 5:03 ` [PATCH v4 04/10] remoteproc: qcom: pas: add support for TMD thermal cooling devices Gaurav Kohli
@ 2026-07-03 5:03 ` Gaurav Kohli
2026-07-03 5:23 ` sashiko-bot
2026-07-03 5:03 ` [PATCH v4 06/10] arm64: dts: qcom: kodiak: Enable CDSP & Modem cooling Gaurav Kohli
` (4 subsequent siblings)
9 siblings, 1 reply; 29+ messages in thread
From: Gaurav Kohli @ 2026-07-03 5:03 UTC (permalink / raw)
To: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Daniel Lezcano, Amit Kucheria,
Manivannan Sadhasivam, Konrad Dybcio, Gaurav Kohli, Kees Cook,
Gustavo A. R. Silva, cros-qcom-dts-watchers
Cc: linux-arm-msm, linux-remoteproc, devicetree, linux-kernel,
linux-pm, linux-hardening, Manaf Meethalavalappu Pallikunhi
Enable Thermal Mitigation Device (TMD) support for PAS-managed CDSP and
modem remote processors on platforms that expose the QMI TMD service.
This adds per-platform TMD configuration in qcom_q6v5_pas for:
- Hamoa (X1E80100) CDSP
- Kodiak CDSP and modem
- Lemans (SA8775P) CDSP
- Talos CDSP
- Monaco CDSP
For each remoteproc, the configured TMD QMI instance ID is used to bind to
the TMD service running on that subsystem (e.g. CDSP: 0x43, modem: 0x0).
The driver then uses the corresponding TMD endpoint names ("cdsp_sw",
"pa", "modem") for cooling-device registration.
QMI TMD identifies mitigation endpoints by name, while DT thermal bindings
reference cooling devices by id. This change provides the mapping
between DT cooling indices and QMI TMD names, allowing remoteproc nodes
with #cooling-cells to act as cooling devices in the thermal framework.
With this in place, thermal policies can request mitigation from CDSP and
modem subsystems via QMI under thermal pressure.
Signed-off-by: Gaurav Kohli <gaurav.kohli@oss.qualcomm.com>
---
drivers/remoteproc/qcom_q6v5_pas.c | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c
index ab5bcccc91a6..974526195e97 100644
--- a/drivers/remoteproc/qcom_q6v5_pas.c
+++ b/drivers/remoteproc/qcom_q6v5_pas.c
@@ -987,6 +987,15 @@ static void qcom_pas_remove(struct platform_device *pdev)
device_init_wakeup(pas->dev, false);
}
+static const struct tmd_name cdsp_tmd_name[] = {
+ { .name = "cdsp_sw", .id = QCOM_CDSP_TMD_CDSP_SW },
+};
+
+static const struct tmd_name modem_tmd_name[] = {
+ { .name = "pa", .id = QCOM_MODEM_TMD_PA },
+ { .name = "modem", .id = QCOM_MODEM_TMD_MODEM },
+};
+
static const struct qcom_pas_data adsp_resource_init = {
.crash_reason_smem = 423,
.firmware_name = "adsp.mdt",
@@ -1144,6 +1153,9 @@ static const struct qcom_pas_data sa8775p_cdsp0_resource = {
.ssr_name = "cdsp",
.sysmon_name = "cdsp",
.ssctl_id = 0x17,
+ .tmd_instance_id = 0x43,
+ .tmd_name = cdsp_tmd_name,
+ .num_tmd = ARRAY_SIZE(cdsp_tmd_name),
};
static const struct qcom_pas_data sa8775p_cdsp1_resource = {
@@ -1162,6 +1174,9 @@ static const struct qcom_pas_data sa8775p_cdsp1_resource = {
.ssr_name = "cdsp1",
.sysmon_name = "cdsp1",
.ssctl_id = 0x20,
+ .tmd_instance_id = 0x44,
+ .tmd_name = cdsp_tmd_name,
+ .num_tmd = ARRAY_SIZE(cdsp_tmd_name),
};
static const struct qcom_pas_data sdm845_cdsp_resource_init = {
@@ -1189,6 +1204,9 @@ static const struct qcom_pas_data sm6350_cdsp_resource = {
.ssr_name = "cdsp",
.sysmon_name = "cdsp",
.ssctl_id = 0x17,
+ .tmd_instance_id = 0x43,
+ .tmd_name = cdsp_tmd_name,
+ .num_tmd = ARRAY_SIZE(cdsp_tmd_name),
};
static const struct qcom_pas_data sm8150_cdsp_resource = {
@@ -1204,6 +1222,9 @@ static const struct qcom_pas_data sm8150_cdsp_resource = {
.ssr_name = "cdsp",
.sysmon_name = "cdsp",
.ssctl_id = 0x17,
+ .tmd_instance_id = 0x43,
+ .tmd_name = cdsp_tmd_name,
+ .num_tmd = ARRAY_SIZE(cdsp_tmd_name),
};
static const struct qcom_pas_data sm8250_cdsp_resource = {
@@ -1288,6 +1309,9 @@ static const struct qcom_pas_data x1e80100_cdsp_resource = {
.ssr_name = "cdsp",
.sysmon_name = "cdsp",
.ssctl_id = 0x17,
+ .tmd_instance_id = 0x43,
+ .tmd_name = cdsp_tmd_name,
+ .num_tmd = ARRAY_SIZE(cdsp_tmd_name),
};
static const struct qcom_pas_data sm8350_cdsp_resource = {
@@ -1356,6 +1380,9 @@ static const struct qcom_pas_data mpss_resource_init = {
.ssr_name = "mpss",
.sysmon_name = "modem",
.ssctl_id = 0x12,
+ .tmd_instance_id = 0x0,
+ .tmd_name = modem_tmd_name,
+ .num_tmd = ARRAY_SIZE(modem_tmd_name),
};
static const struct qcom_pas_data sc8180x_mpss_resource = {
--
2.34.1
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH v4 06/10] arm64: dts: qcom: kodiak: Enable CDSP & Modem cooling
2026-07-03 5:03 [PATCH v4 00/10] Add support for Qualcomm remoteproc subsystem cooling Gaurav Kohli
` (4 preceding siblings ...)
2026-07-03 5:03 ` [PATCH v4 05/10] remoteproc: qcom_q6v5_pas: enable QMI TMD cooling support Gaurav Kohli
@ 2026-07-03 5:03 ` Gaurav Kohli
2026-07-03 7:51 ` Krzysztof Kozlowski
2026-07-03 15:48 ` Dmitry Baryshkov
2026-07-03 5:03 ` [PATCH v4 07/10] arm64: dts: qcom: lemans: Enable CDSP cooling Gaurav Kohli
` (3 subsequent siblings)
9 siblings, 2 replies; 29+ messages in thread
From: Gaurav Kohli @ 2026-07-03 5:03 UTC (permalink / raw)
To: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Daniel Lezcano, Amit Kucheria,
Manivannan Sadhasivam, Konrad Dybcio, Gaurav Kohli, Kees Cook,
Gustavo A. R. Silva, cros-qcom-dts-watchers
Cc: linux-arm-msm, linux-remoteproc, devicetree, linux-kernel,
linux-pm, linux-hardening, Manaf Meethalavalappu Pallikunhi
Unlike the CPU, the CDSP/Modem does not throttle its speed automatically
when it reaches high temperatures in kodiak.
Set up CDSP cooling by throttling the cdsp when it reaches 100°C and
for modem when it reaches to 95°C.
Since the remoteproc_mpss node doesn't exist on non modem boards, the
cooling-maps that reference it cause DT compilation errors. To fix that
remove inherited mdmss cooling-map nodes.
Signed-off-by: Gaurav Kohli <gaurav.kohli@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/kodiak.dtsi | 134 ++++++++++++++++++++-
.../boot/dts/qcom/qcs6490-radxa-dragon-q6a.dts | 17 +++
arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts | 17 +++
.../dts/qcom/qcs6490-thundercomm-minipc-g1iot.dts | 17 +++
.../boot/dts/qcom/qcs6490-thundercomm-rubikpi3.dts | 17 +++
.../boot/dts/qcom/sc7280-herobrine-lte-sku.dtsi | 17 +++
.../boot/dts/qcom/sc7280-herobrine-wifi-sku.dtsi | 16 +++
7 files changed, 231 insertions(+), 4 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/kodiak.dtsi b/arch/arm64/boot/dts/qcom/kodiak.dtsi
index fa540d8c2615..d6fbafae6d3e 100644
--- a/arch/arm64/boot/dts/qcom/kodiak.dtsi
+++ b/arch/arm64/boot/dts/qcom/kodiak.dtsi
@@ -14,6 +14,7 @@
#include <dt-bindings/clock/qcom,rpmh.h>
#include <dt-bindings/clock/qcom,videocc-sc7280.h>
#include <dt-bindings/dma/qcom-gpi.h>
+#include <dt-bindings/firmware/qcom,qmi-tmd.h>
#include <dt-bindings/firmware/qcom,scm.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interconnect/qcom,icc.h>
@@ -3427,6 +3428,8 @@ remoteproc_mpss: remoteproc@4080000 {
qcom,smem-states = <&modem_smp2p_out 0>;
qcom,smem-state-names = "stop";
+ #cooling-cells = <3>;
+
status = "disabled";
glink-edge {
@@ -4787,6 +4790,8 @@ remoteproc_cdsp: remoteproc@a300000 {
qcom,smem-states = <&cdsp_smp2p_out 0>;
qcom,smem-state-names = "stop";
+ #cooling-cells = <3>;
+
status = "disabled";
glink-edge {
@@ -4906,6 +4911,7 @@ compute-cb@14 {
};
};
};
+
};
usb_1: usb@a600000 {
@@ -7716,6 +7722,8 @@ map0 {
};
nspss0-thermal {
+ polling-delay-passive = <200>;
+
thermal-sensors = <&tsens1 3>;
trips {
@@ -7725,15 +7733,31 @@ nspss0_alert0: trip-point0 {
type = "hot";
};
+ nspss0_alert1: trip-point1 {
+ temperature = <100000>;
+ hysteresis = <5000>;
+ type = "passive";
+ };
+
nspss0_crit: nspss0-crit {
temperature = <110000>;
hysteresis = <0>;
type = "critical";
};
};
+
+ cooling-maps {
+ map0 {
+ trip = <&nspss0_alert1>;
+ cooling-device = <&remoteproc_cdsp QCOM_CDSP_TMD_CDSP_SW
+ THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
};
nspss1-thermal {
+ polling-delay-passive = <200>;
+
thermal-sensors = <&tsens1 4>;
trips {
@@ -7743,12 +7767,26 @@ nspss1_alert0: trip-point0 {
type = "hot";
};
+ nspss1_alert1: trip-point1 {
+ temperature = <100000>;
+ hysteresis = <5000>;
+ type = "passive";
+ };
+
nspss1_crit: nspss1-crit {
temperature = <110000>;
hysteresis = <0>;
type = "critical";
};
};
+
+ cooling-maps {
+ map0 {
+ trip = <&nspss1_alert1>;
+ cooling-device = <&remoteproc_cdsp QCOM_CDSP_TMD_CDSP_SW
+ THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
};
video-thermal {
@@ -7787,7 +7825,9 @@ ddr_crit: ddr-crit {
};
};
- mdmss0-thermal {
+ mdmss0_thermal: mdmss0-thermal {
+ polling-delay-passive = <200>;
+
thermal-sensors = <&tsens1 7>;
trips {
@@ -7797,15 +7837,37 @@ mdmss0_alert0: trip-point0 {
type = "hot";
};
+ mdmss0_alert1: trip-point1 {
+ temperature = <95000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
mdmss0_crit: mdmss0-crit {
temperature = <110000>;
hysteresis = <0>;
type = "critical";
};
};
+
+ cooling-maps {
+ map0 {
+ trip = <&mdmss0_alert1>;
+ cooling-device = <&remoteproc_mpss QCOM_MODEM_TMD_PA
+ THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+
+ map1 {
+ trip = <&mdmss0_alert1>;
+ cooling-device = <&remoteproc_mpss QCOM_MODEM_TMD_MODEM
+ THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
};
- mdmss1-thermal {
+ mdmss1_thermal: mdmss1-thermal {
+ polling-delay-passive = <200>;
+
thermal-sensors = <&tsens1 8>;
trips {
@@ -7815,15 +7877,37 @@ mdmss1_alert0: trip-point0 {
type = "hot";
};
+ mdmss1_alert1: trip-point1 {
+ temperature = <95000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
mdmss1_crit: mdmss1-crit {
temperature = <110000>;
hysteresis = <0>;
type = "critical";
};
};
+
+ cooling-maps {
+ map0 {
+ trip = <&mdmss1_alert1>;
+ cooling-device = <&remoteproc_mpss QCOM_MODEM_TMD_PA
+ THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+
+ map1 {
+ trip = <&mdmss1_alert1>;
+ cooling-device = <&remoteproc_mpss QCOM_MODEM_TMD_MODEM
+ THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
};
- mdmss2-thermal {
+ mdmss2_thermal: mdmss2-thermal {
+ polling-delay-passive = <200>;
+
thermal-sensors = <&tsens1 9>;
trips {
@@ -7833,15 +7917,37 @@ mdmss2_alert0: trip-point0 {
type = "hot";
};
+ mdmss2_alert1: trip-point1 {
+ temperature = <95000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
mdmss2_crit: mdmss2-crit {
temperature = <110000>;
hysteresis = <0>;
type = "critical";
};
};
+
+ cooling-maps {
+ map0 {
+ trip = <&mdmss2_alert1>;
+ cooling-device = <&remoteproc_mpss QCOM_MODEM_TMD_PA
+ THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+
+ map1 {
+ trip = <&mdmss2_alert1>;
+ cooling-device = <&remoteproc_mpss QCOM_MODEM_TMD_MODEM
+ THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
};
- mdmss3-thermal {
+ mdmss3_thermal: mdmss3-thermal {
+ polling-delay-passive = <200>;
+
thermal-sensors = <&tsens1 10>;
trips {
@@ -7851,12 +7957,32 @@ mdmss3_alert0: trip-point0 {
type = "hot";
};
+ mdmss3_alert1: trip-point1 {
+ temperature = <95000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
mdmss3_crit: mdmss3-crit {
temperature = <110000>;
hysteresis = <0>;
type = "critical";
};
};
+
+ cooling-maps {
+ map0 {
+ trip = <&mdmss3_alert1>;
+ cooling-device = <&remoteproc_mpss QCOM_MODEM_TMD_PA
+ THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+
+ map1 {
+ trip = <&mdmss3_alert1>;
+ cooling-device = <&remoteproc_mpss QCOM_MODEM_TMD_MODEM
+ THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
};
camera0-thermal {
diff --git a/arch/arm64/boot/dts/qcom/qcs6490-radxa-dragon-q6a.dts b/arch/arm64/boot/dts/qcom/qcs6490-radxa-dragon-q6a.dts
index bb5a42b038f1..400d128132fc 100644
--- a/arch/arm64/boot/dts/qcom/qcs6490-radxa-dragon-q6a.dts
+++ b/arch/arm64/boot/dts/qcom/qcs6490-radxa-dragon-q6a.dts
@@ -24,6 +24,23 @@
/delete-node/ &adsp_mem;
/delete-node/ &cdsp_mem;
/delete-node/ &ipa_fw_mem;
+
+&mdmss0_thermal {
+ /delete-node/ cooling-maps;
+};
+
+&mdmss1_thermal {
+ /delete-node/ cooling-maps;
+};
+
+&mdmss2_thermal {
+ /delete-node/ cooling-maps;
+};
+
+&mdmss3_thermal {
+ /delete-node/ cooling-maps;
+};
+
/delete-node/ &mpss_mem;
/delete-node/ &remoteproc_mpss;
/delete-node/ &remoteproc_wpss;
diff --git a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts
index 37a3b51323ce..187bc2899191 100644
--- a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts
+++ b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts
@@ -25,6 +25,23 @@
/delete-node/ &rmtfs_mem;
/delete-node/ &adsp_mem;
/delete-node/ &cdsp_mem;
+
+&mdmss0_thermal {
+ /delete-node/ cooling-maps;
+};
+
+&mdmss1_thermal {
+ /delete-node/ cooling-maps;
+};
+
+&mdmss2_thermal {
+ /delete-node/ cooling-maps;
+};
+
+&mdmss3_thermal {
+ /delete-node/ cooling-maps;
+};
+
/delete-node/ &video_mem;
/delete-node/ &wlan_ce_mem;
/delete-node/ &wpss_mem;
diff --git a/arch/arm64/boot/dts/qcom/qcs6490-thundercomm-minipc-g1iot.dts b/arch/arm64/boot/dts/qcom/qcs6490-thundercomm-minipc-g1iot.dts
index a5ad796cb65d..1e190ed18ae5 100644
--- a/arch/arm64/boot/dts/qcom/qcs6490-thundercomm-minipc-g1iot.dts
+++ b/arch/arm64/boot/dts/qcom/qcs6490-thundercomm-minipc-g1iot.dts
@@ -22,6 +22,23 @@
/delete-node/ &cdsp_mem;
/delete-node/ &ipa_fw_mem;
/delete-node/ &mpss_mem;
+
+&mdmss0_thermal {
+ /delete-node/ cooling-maps;
+};
+
+&mdmss1_thermal {
+ /delete-node/ cooling-maps;
+};
+
+&mdmss2_thermal {
+ /delete-node/ cooling-maps;
+};
+
+&mdmss3_thermal {
+ /delete-node/ cooling-maps;
+};
+
/delete-node/ &remoteproc_mpss;
/delete-node/ &remoteproc_wpss;
/delete-node/ &rmtfs_mem;
diff --git a/arch/arm64/boot/dts/qcom/qcs6490-thundercomm-rubikpi3.dts b/arch/arm64/boot/dts/qcom/qcs6490-thundercomm-rubikpi3.dts
index f47efca42d48..8e8dd4efd8c0 100644
--- a/arch/arm64/boot/dts/qcom/qcs6490-thundercomm-rubikpi3.dts
+++ b/arch/arm64/boot/dts/qcom/qcs6490-thundercomm-rubikpi3.dts
@@ -23,6 +23,23 @@
/delete-node/ &adsp_mem;
/delete-node/ &cdsp_mem;
/delete-node/ &ipa_fw_mem;
+
+&mdmss0_thermal {
+ /delete-node/ cooling-maps;
+};
+
+&mdmss1_thermal {
+ /delete-node/ cooling-maps;
+};
+
+&mdmss2_thermal {
+ /delete-node/ cooling-maps;
+};
+
+&mdmss3_thermal {
+ /delete-node/ cooling-maps;
+};
+
/delete-node/ &mpss_mem;
/delete-node/ &remoteproc_mpss;
/delete-node/ &remoteproc_wpss;
diff --git a/arch/arm64/boot/dts/qcom/sc7280-herobrine-lte-sku.dtsi b/arch/arm64/boot/dts/qcom/sc7280-herobrine-lte-sku.dtsi
index b721a8546800..1e9d7e7b5fa2 100644
--- a/arch/arm64/boot/dts/qcom/sc7280-herobrine-lte-sku.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7280-herobrine-lte-sku.dtsi
@@ -26,8 +26,25 @@ &ipa {
status = "okay";
};
+&mdmss0_thermal {
+ /delete-node/ cooling-maps;
+};
+
+&mdmss1_thermal {
+ /delete-node/ cooling-maps;
+};
+
+&mdmss2_thermal {
+ /delete-node/ cooling-maps;
+};
+
+&mdmss3_thermal {
+ /delete-node/ cooling-maps;
+};
+
&remoteproc_mpss {
compatible = "qcom,sc7280-mss-pil";
+ /delete-property/ #cooling-cells;
reg = <0 0x04080000 0 0x10000>, <0 0x04180000 0 0x48>;
reg-names = "qdsp6", "rmb";
diff --git a/arch/arm64/boot/dts/qcom/sc7280-herobrine-wifi-sku.dtsi b/arch/arm64/boot/dts/qcom/sc7280-herobrine-wifi-sku.dtsi
index 3ebc915f0dc2..6642076f62c4 100644
--- a/arch/arm64/boot/dts/qcom/sc7280-herobrine-wifi-sku.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7280-herobrine-wifi-sku.dtsi
@@ -7,6 +7,22 @@
/* WIFI SKUs save 256M by not having modem/mba/rmtfs memory regions defined. */
+&mdmss0_thermal {
+ /delete-node/ cooling-maps;
+};
+
+&mdmss1_thermal {
+ /delete-node/ cooling-maps;
+};
+
+&mdmss2_thermal {
+ /delete-node/ cooling-maps;
+};
+
+&mdmss3_thermal {
+ /delete-node/ cooling-maps;
+};
+
/delete-node/ &mpss_mem;
/delete-node/ &remoteproc_mpss;
/delete-node/ &rmtfs_mem;
--
2.34.1
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH v4 07/10] arm64: dts: qcom: lemans: Enable CDSP cooling
2026-07-03 5:03 [PATCH v4 00/10] Add support for Qualcomm remoteproc subsystem cooling Gaurav Kohli
` (5 preceding siblings ...)
2026-07-03 5:03 ` [PATCH v4 06/10] arm64: dts: qcom: kodiak: Enable CDSP & Modem cooling Gaurav Kohli
@ 2026-07-03 5:03 ` Gaurav Kohli
2026-07-03 5:18 ` sashiko-bot
2026-07-03 5:03 ` [PATCH v4 08/10] arm64: dts: qcom: talos: " Gaurav Kohli
` (2 subsequent siblings)
9 siblings, 1 reply; 29+ messages in thread
From: Gaurav Kohli @ 2026-07-03 5:03 UTC (permalink / raw)
To: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Daniel Lezcano, Amit Kucheria,
Manivannan Sadhasivam, Konrad Dybcio, Gaurav Kohli, Kees Cook,
Gustavo A. R. Silva, cros-qcom-dts-watchers
Cc: linux-arm-msm, linux-remoteproc, devicetree, linux-kernel,
linux-pm, linux-hardening, Manaf Meethalavalappu Pallikunhi
Unlike the CPU, the CDSP does not throttle its speed automatically
when it reaches high temperatures in lemans.
Set up CDSP cooling for both instances by throttling the cdsp, when
it reaches 105°C.
Signed-off-by: Gaurav Kohli <gaurav.kohli@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/lemans.dtsi | 125 +++++++++++++++++++++++++++++++----
1 file changed, 113 insertions(+), 12 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/lemans.dtsi b/arch/arm64/boot/dts/qcom/lemans.dtsi
index 353a6e6fd3ac..89fa25e9d3c6 100644
--- a/arch/arm64/boot/dts/qcom/lemans.dtsi
+++ b/arch/arm64/boot/dts/qcom/lemans.dtsi
@@ -17,6 +17,7 @@
#include <dt-bindings/interconnect/qcom,osm-l3.h>
#include <dt-bindings/interconnect/qcom,sa8775p-rpmh.h>
#include <dt-bindings/mailbox/qcom-ipcc.h>
+#include <dt-bindings/firmware/qcom,qmi-tmd.h>
#include <dt-bindings/firmware/qcom,scm.h>
#include <dt-bindings/power/qcom-rpmpd.h>
#include <dt-bindings/soc/qcom,gpr.h>
@@ -7777,6 +7778,8 @@ remoteproc_cdsp0: remoteproc@26300000 {
qcom,smem-states = <&smp2p_cdsp0_out 0>;
qcom,smem-state-names = "stop";
+ #cooling-cells = <3>;
+
status = "disabled";
glink-edge {
@@ -7916,6 +7919,8 @@ remoteproc_cdsp1: remoteproc@2a300000 {
qcom,smem-states = <&smp2p_cdsp1_out 0>;
qcom,smem-state-names = "stop";
+ #cooling-cells = <3>;
+
status = "disabled";
glink-edge {
@@ -8764,7 +8769,7 @@ nsp-0-0-0-thermal {
thermal-sensors = <&tsens2 5>;
trips {
- trip-point0 {
+ nsp_0_0_0_alert0: trip-point0 {
temperature = <105000>;
hysteresis = <5000>;
type = "passive";
@@ -8776,6 +8781,14 @@ trip-point1 {
type = "passive";
};
};
+
+ cooling-maps {
+ map0 {
+ trip = <&nsp_0_0_0_alert0>;
+ cooling-device = <&remoteproc_cdsp0 QCOM_CDSP_TMD_CDSP_SW
+ THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
};
nsp-0-1-0-thermal {
@@ -8784,7 +8797,7 @@ nsp-0-1-0-thermal {
thermal-sensors = <&tsens2 6>;
trips {
- trip-point0 {
+ nsp_0_1_0_alert0: trip-point0 {
temperature = <105000>;
hysteresis = <5000>;
type = "passive";
@@ -8796,6 +8809,14 @@ trip-point1 {
type = "passive";
};
};
+
+ cooling-maps {
+ map0 {
+ trip = <&nsp_0_1_0_alert0>;
+ cooling-device = <&remoteproc_cdsp0 QCOM_CDSP_TMD_CDSP_SW
+ THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
};
nsp-0-2-0-thermal {
@@ -8804,7 +8825,7 @@ nsp-0-2-0-thermal {
thermal-sensors = <&tsens2 7>;
trips {
- trip-point0 {
+ nsp_0_2_0_alert0: trip-point0 {
temperature = <105000>;
hysteresis = <5000>;
type = "passive";
@@ -8816,6 +8837,14 @@ trip-point1 {
type = "passive";
};
};
+
+ cooling-maps {
+ map0 {
+ trip = <&nsp_0_2_0_alert0>;
+ cooling-device = <&remoteproc_cdsp0 QCOM_CDSP_TMD_CDSP_SW
+ THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
};
nsp-1-0-0-thermal {
@@ -8824,7 +8853,7 @@ nsp-1-0-0-thermal {
thermal-sensors = <&tsens2 8>;
trips {
- trip-point0 {
+ nsp_1_0_0_alert0: trip-point0 {
temperature = <105000>;
hysteresis = <5000>;
type = "passive";
@@ -8836,6 +8865,14 @@ trip-point1 {
type = "passive";
};
};
+
+ cooling-maps {
+ map0 {
+ trip = <&nsp_1_0_0_alert0>;
+ cooling-device = <&remoteproc_cdsp1 QCOM_CDSP_TMD_CDSP_SW
+ THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
};
nsp-1-1-0-thermal {
@@ -8844,7 +8881,7 @@ nsp-1-1-0-thermal {
thermal-sensors = <&tsens2 9>;
trips {
- trip-point0 {
+ nsp_1_1_0_alert0: trip-point0 {
temperature = <105000>;
hysteresis = <5000>;
type = "passive";
@@ -8856,6 +8893,14 @@ trip-point1 {
type = "passive";
};
};
+
+ cooling-maps {
+ map0 {
+ trip = <&nsp_1_1_0_alert0>;
+ cooling-device = <&remoteproc_cdsp1 QCOM_CDSP_TMD_CDSP_SW
+ THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
};
nsp-1-2-0-thermal {
@@ -8864,7 +8909,7 @@ nsp-1-2-0-thermal {
thermal-sensors = <&tsens2 10>;
trips {
- trip-point0 {
+ nsp_1_2_0_alert0: trip-point0 {
temperature = <105000>;
hysteresis = <5000>;
type = "passive";
@@ -8876,6 +8921,14 @@ trip-point1 {
type = "passive";
};
};
+
+ cooling-maps {
+ map0 {
+ trip = <&nsp_1_2_0_alert0>;
+ cooling-device = <&remoteproc_cdsp1 QCOM_CDSP_TMD_CDSP_SW
+ THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
};
ddrss-0-thermal {
@@ -9018,7 +9071,7 @@ nsp-0-0-1-thermal {
thermal-sensors = <&tsens3 5>;
trips {
- trip-point0 {
+ nsp_0_0_1_alert0: trip-point0 {
temperature = <105000>;
hysteresis = <5000>;
type = "passive";
@@ -9030,6 +9083,14 @@ trip-point1 {
type = "passive";
};
};
+
+ cooling-maps {
+ map0 {
+ trip = <&nsp_0_0_1_alert0>;
+ cooling-device = <&remoteproc_cdsp0 QCOM_CDSP_TMD_CDSP_SW
+ THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
};
nsp-0-1-1-thermal {
@@ -9038,7 +9099,7 @@ nsp-0-1-1-thermal {
thermal-sensors = <&tsens3 6>;
trips {
- trip-point0 {
+ nsp_0_1_1_alert0: trip-point0 {
temperature = <105000>;
hysteresis = <5000>;
type = "passive";
@@ -9050,6 +9111,14 @@ trip-point1 {
type = "passive";
};
};
+
+ cooling-maps {
+ map0 {
+ trip = <&nsp_0_1_1_alert0>;
+ cooling-device = <&remoteproc_cdsp0 QCOM_CDSP_TMD_CDSP_SW
+ THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
};
nsp-0-2-1-thermal {
@@ -9058,7 +9127,7 @@ nsp-0-2-1-thermal {
thermal-sensors = <&tsens3 7>;
trips {
- trip-point0 {
+ nsp_0_2_1_alert0: trip-point0 {
temperature = <105000>;
hysteresis = <5000>;
type = "passive";
@@ -9070,6 +9139,14 @@ trip-point1 {
type = "passive";
};
};
+
+ cooling-maps {
+ map0 {
+ trip = <&nsp_0_2_1_alert0>;
+ cooling-device = <&remoteproc_cdsp0 QCOM_CDSP_TMD_CDSP_SW
+ THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
};
nsp-1-0-1-thermal {
@@ -9078,7 +9155,7 @@ nsp-1-0-1-thermal {
thermal-sensors = <&tsens3 8>;
trips {
- trip-point0 {
+ nsp_1_0_1_alert0: trip-point0 {
temperature = <105000>;
hysteresis = <5000>;
type = "passive";
@@ -9090,6 +9167,14 @@ trip-point1 {
type = "passive";
};
};
+
+ cooling-maps {
+ map0 {
+ trip = <&nsp_1_0_1_alert0>;
+ cooling-device = <&remoteproc_cdsp1 QCOM_CDSP_TMD_CDSP_SW
+ THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
};
nsp-1-1-1-thermal {
@@ -9098,7 +9183,7 @@ nsp-1-1-1-thermal {
thermal-sensors = <&tsens3 9>;
trips {
- trip-point0 {
+ nsp_1_1_1_alert0: trip-point0 {
temperature = <105000>;
hysteresis = <5000>;
type = "passive";
@@ -9110,6 +9195,14 @@ trip-point1 {
type = "passive";
};
};
+
+ cooling-maps {
+ map0 {
+ trip = <&nsp_1_1_1_alert0>;
+ cooling-device = <&remoteproc_cdsp1 QCOM_CDSP_TMD_CDSP_SW
+ THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
};
nsp-1-2-1-thermal {
@@ -9118,7 +9211,7 @@ nsp-1-2-1-thermal {
thermal-sensors = <&tsens3 10>;
trips {
- trip-point0 {
+ nsp_1_2_1_alert0: trip-point0 {
temperature = <105000>;
hysteresis = <5000>;
type = "passive";
@@ -9130,6 +9223,14 @@ trip-point1 {
type = "passive";
};
};
+
+ cooling-maps {
+ map0 {
+ trip = <&nsp_1_2_1_alert0>;
+ cooling-device = <&remoteproc_cdsp1 QCOM_CDSP_TMD_CDSP_SW
+ THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
};
ddrss-1-thermal {
--
2.34.1
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH v4 08/10] arm64: dts: qcom: talos: Enable CDSP cooling
2026-07-03 5:03 [PATCH v4 00/10] Add support for Qualcomm remoteproc subsystem cooling Gaurav Kohli
` (6 preceding siblings ...)
2026-07-03 5:03 ` [PATCH v4 07/10] arm64: dts: qcom: lemans: Enable CDSP cooling Gaurav Kohli
@ 2026-07-03 5:03 ` Gaurav Kohli
2026-07-03 5:03 ` [PATCH v4 09/10] arm64: dts: qcom: monaco: " Gaurav Kohli
2026-07-03 5:03 ` [PATCH v4 10/10] arm64: dts: qcom: hamoa: " Gaurav Kohli
9 siblings, 0 replies; 29+ messages in thread
From: Gaurav Kohli @ 2026-07-03 5:03 UTC (permalink / raw)
To: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Daniel Lezcano, Amit Kucheria,
Manivannan Sadhasivam, Konrad Dybcio, Gaurav Kohli, Kees Cook,
Gustavo A. R. Silva, cros-qcom-dts-watchers
Cc: linux-arm-msm, linux-remoteproc, devicetree, linux-kernel,
linux-pm, linux-hardening, Manaf Meethalavalappu Pallikunhi
Unlike the CPU, the CDSP does not throttle its speed automatically
when it reaches high temperatures in talos.
Set up CDSP cooling by throttling the cdsp, when it reaches 105°C.
Signed-off-by: Gaurav Kohli <gaurav.kohli@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/talos.dtsi | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/talos.dtsi b/arch/arm64/boot/dts/qcom/talos.dtsi
index fb1bbc51bb8a..2c394fa65228 100644
--- a/arch/arm64/boot/dts/qcom/talos.dtsi
+++ b/arch/arm64/boot/dts/qcom/talos.dtsi
@@ -11,6 +11,7 @@
#include <dt-bindings/clock/qcom,qcs615-videocc.h>
#include <dt-bindings/clock/qcom,rpmh.h>
#include <dt-bindings/dma/qcom-gpi.h>
+#include <dt-bindings/firmware/qcom,qmi-tmd.h>
#include <dt-bindings/interconnect/qcom,icc.h>
#include <dt-bindings/interconnect/qcom,osm-l3.h>
#include <dt-bindings/interconnect/qcom,qcs615-rpmh.h>
@@ -3772,6 +3773,8 @@ remoteproc_cdsp: remoteproc@8300000 {
qcom,smem-states = <&cdsp_smp2p_out 0>;
qcom,smem-state-names = "stop";
+ #cooling-cells = <3>;
+
status = "disabled";
glink-edge {
@@ -5425,15 +5428,31 @@ map0 {
};
q6-hvx-thermal {
+ polling-delay-passive = <200>;
+
thermal-sensors = <&tsens0 10>;
trips {
+ q6_hvx_alert0: trip-point0 {
+ temperature = <105000>;
+ hysteresis = <5000>;
+ type = "passive";
+ };
+
q6-hvx-critical {
temperature = <115000>;
hysteresis = <1000>;
type = "critical";
};
};
+
+ cooling-maps {
+ map0 {
+ trip = <&q6_hvx_alert0>;
+ cooling-device = <&remoteproc_cdsp QCOM_CDSP_TMD_CDSP_SW
+ THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
};
mdm-core-thermal {
--
2.34.1
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH v4 09/10] arm64: dts: qcom: monaco: Enable CDSP cooling
2026-07-03 5:03 [PATCH v4 00/10] Add support for Qualcomm remoteproc subsystem cooling Gaurav Kohli
` (7 preceding siblings ...)
2026-07-03 5:03 ` [PATCH v4 08/10] arm64: dts: qcom: talos: " Gaurav Kohli
@ 2026-07-03 5:03 ` Gaurav Kohli
2026-07-03 5:03 ` [PATCH v4 10/10] arm64: dts: qcom: hamoa: " Gaurav Kohli
9 siblings, 0 replies; 29+ messages in thread
From: Gaurav Kohli @ 2026-07-03 5:03 UTC (permalink / raw)
To: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Daniel Lezcano, Amit Kucheria,
Manivannan Sadhasivam, Konrad Dybcio, Gaurav Kohli, Kees Cook,
Gustavo A. R. Silva, cros-qcom-dts-watchers
Cc: linux-arm-msm, linux-remoteproc, devicetree, linux-kernel,
linux-pm, linux-hardening, Manaf Meethalavalappu Pallikunhi
Unlike the CPU, the CDSP does not throttle its speed automatically
when it reaches high temperatures in monaco.
Set up CDSP cooling for both instances by throttling the cdsp, when
it reaches 115°C.
Signed-off-by: Gaurav Kohli <gaurav.kohli@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/monaco.dtsi | 99 ++++++++++++++++++++++++++++++++++++
1 file changed, 99 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/monaco.dtsi b/arch/arm64/boot/dts/qcom/monaco.dtsi
index e4c8466f941b..4576f9670962 100644
--- a/arch/arm64/boot/dts/qcom/monaco.dtsi
+++ b/arch/arm64/boot/dts/qcom/monaco.dtsi
@@ -11,6 +11,7 @@
#include <dt-bindings/clock/qcom,sa8775p-gpucc.h>
#include <dt-bindings/clock/qcom,sa8775p-videocc.h>
#include <dt-bindings/dma/qcom-gpi.h>
+#include <dt-bindings/firmware/qcom,qmi-tmd.h>
#include <dt-bindings/firmware/qcom,scm.h>
#include <dt-bindings/interconnect/qcom,icc.h>
#include <dt-bindings/interconnect/qcom,osm-l3.h>
@@ -7728,6 +7729,8 @@ remoteproc_cdsp: remoteproc@26300000 {
qcom,smem-states = <&smp2p_cdsp_out 0>;
qcom,smem-state-names = "stop";
+ #cooling-cells = <3>;
+
status = "disabled";
glink-edge {
@@ -8160,39 +8163,87 @@ cpu-critical {
};
nsp-0-0-0-thermal {
+ polling-delay-passive = <200>;
+
thermal-sensors = <&tsens2 5>;
trips {
+ nsp_0_0_0_alert0: trip-point0 {
+ temperature = <115000>;
+ hysteresis = <5000>;
+ type = "passive";
+ };
+
nsp-critical {
temperature = <125000>;
hysteresis = <1000>;
type = "critical";
};
};
+
+ cooling-maps {
+ map0 {
+ trip = <&nsp_0_0_0_alert0>;
+ cooling-device = <&remoteproc_cdsp QCOM_CDSP_TMD_CDSP_SW
+ THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
};
nsp-0-1-0-thermal {
+ polling-delay-passive = <200>;
+
thermal-sensors = <&tsens2 6>;
trips {
+ nsp_0_1_0_alert0: trip-point0 {
+ temperature = <115000>;
+ hysteresis = <5000>;
+ type = "passive";
+ };
+
nsp-critical {
temperature = <125000>;
hysteresis = <1000>;
type = "critical";
};
};
+
+ cooling-maps {
+ map0 {
+ trip = <&nsp_0_1_0_alert0>;
+ cooling-device = <&remoteproc_cdsp QCOM_CDSP_TMD_CDSP_SW
+ THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
};
nsp-0-2-0-thermal {
+ polling-delay-passive = <200>;
+
thermal-sensors = <&tsens2 7>;
trips {
+ nsp_0_2_0_alert0: trip-point0 {
+ temperature = <115000>;
+ hysteresis = <5000>;
+ type = "passive";
+ };
+
nsp-critical {
temperature = <125000>;
hysteresis = <1000>;
type = "critical";
};
};
+
+ cooling-maps {
+ map0 {
+ trip = <&nsp_0_2_0_alert0>;
+ cooling-device = <&remoteproc_cdsp QCOM_CDSP_TMD_CDSP_SW
+ THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
};
ddrss-0-thermal {
@@ -8280,39 +8331,87 @@ cpu-critical {
};
nsp-0-0-1-thermal {
+ polling-delay-passive = <200>;
+
thermal-sensors = <&tsens3 5>;
trips {
+ nsp_0_0_1_alert0: trip-point0 {
+ temperature = <115000>;
+ hysteresis = <5000>;
+ type = "passive";
+ };
+
nsp-critical {
temperature = <125000>;
hysteresis = <1000>;
type = "critical";
};
};
+
+ cooling-maps {
+ map0 {
+ trip = <&nsp_0_0_1_alert0>;
+ cooling-device = <&remoteproc_cdsp QCOM_CDSP_TMD_CDSP_SW
+ THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
};
nsp-0-1-1-thermal {
+ polling-delay-passive = <200>;
+
thermal-sensors = <&tsens3 6>;
trips {
+ nsp_0_1_1_alert0: trip-point0 {
+ temperature = <115000>;
+ hysteresis = <5000>;
+ type = "passive";
+ };
+
nsp-critical {
temperature = <125000>;
hysteresis = <1000>;
type = "critical";
};
};
+
+ cooling-maps {
+ map0 {
+ trip = <&nsp_0_1_1_alert0>;
+ cooling-device = <&remoteproc_cdsp QCOM_CDSP_TMD_CDSP_SW
+ THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
};
nsp-0-2-1-thermal {
+ polling-delay-passive = <200>;
+
thermal-sensors = <&tsens3 7>;
trips {
+ nsp_0_2_1_alert0: trip-point0 {
+ temperature = <115000>;
+ hysteresis = <5000>;
+ type = "passive";
+ };
+
nsp-critical {
temperature = <125000>;
hysteresis = <1000>;
type = "critical";
};
};
+
+ cooling-maps {
+ map0 {
+ trip = <&nsp_0_2_1_alert0>;
+ cooling-device = <&remoteproc_cdsp QCOM_CDSP_TMD_CDSP_SW
+ THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
};
ddrss-1-thermal {
--
2.34.1
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH v4 10/10] arm64: dts: qcom: hamoa: Enable CDSP cooling
2026-07-03 5:03 [PATCH v4 00/10] Add support for Qualcomm remoteproc subsystem cooling Gaurav Kohli
` (8 preceding siblings ...)
2026-07-03 5:03 ` [PATCH v4 09/10] arm64: dts: qcom: monaco: " Gaurav Kohli
@ 2026-07-03 5:03 ` Gaurav Kohli
9 siblings, 0 replies; 29+ messages in thread
From: Gaurav Kohli @ 2026-07-03 5:03 UTC (permalink / raw)
To: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Daniel Lezcano, Amit Kucheria,
Manivannan Sadhasivam, Konrad Dybcio, Gaurav Kohli, Kees Cook,
Gustavo A. R. Silva, cros-qcom-dts-watchers
Cc: linux-arm-msm, linux-remoteproc, devicetree, linux-kernel,
linux-pm, linux-hardening, Manaf Meethalavalappu Pallikunhi,
Dipa Ramesh Mantre
From: Dipa Ramesh Mantre <dipa.mantre@oss.qualcomm.com>
Unlike the CPU, the CDSP does not throttle its speed automatically
when it reaches high temperatures in hamoa.
Set up CDSP cooling for both instances by throttling the cdsp, when
it reaches 95°C.
Signed-off-by: Dipa Ramesh Mantre <dipa.mantre@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/hamoa.dtsi | 63 +++++++++++++++++++++++++++++++++++++
1 file changed, 63 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/hamoa.dtsi b/arch/arm64/boot/dts/qcom/hamoa.dtsi
index 4ba751a65142..397049d2d238 100644
--- a/arch/arm64/boot/dts/qcom/hamoa.dtsi
+++ b/arch/arm64/boot/dts/qcom/hamoa.dtsi
@@ -11,6 +11,7 @@
#include <dt-bindings/clock/qcom,x1e80100-gpucc.h>
#include <dt-bindings/clock/qcom,x1e80100-tcsr.h>
#include <dt-bindings/dma/qcom-gpi.h>
+#include <dt-bindings/firmware/qcom,qmi-tmd.h>
#include <dt-bindings/interconnect/qcom,icc.h>
#include <dt-bindings/interconnect/qcom,x1e80100-rpmh.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
@@ -8815,6 +8816,8 @@ remoteproc_cdsp: remoteproc@32300000 {
status = "disabled";
+ #cooling-cells = <3>;
+
glink-edge {
interrupts-extended = <&ipcc IPCC_CLIENT_CDSP
IPCC_MPROC_SIGNAL_GLINK_QMP
@@ -9402,6 +9405,7 @@ aoss0-critical {
};
thermal_nsp0: nsp0-thermal {
+ polling-delay-passive = <200>;
thermal-sensors = <&tsens3 1>;
trips {
@@ -9411,15 +9415,30 @@ trip-point0 {
type = "hot";
};
+ nsp0_alert0: trip-point1 {
+ temperature = <95000>;
+ hysteresis = <5000>;
+ type = "passive";
+ };
+
nsp0-critical {
temperature = <115000>;
hysteresis = <1000>;
type = "critical";
};
};
+
+ cooling-maps {
+ map0 {
+ trip = <&nsp0_alert0>;
+ cooling-device = <&remoteproc_cdsp QCOM_CDSP_TMD_CDSP_SW
+ THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
};
thermal_nsp1: nsp1-thermal {
+ polling-delay-passive = <200>;
thermal-sensors = <&tsens3 2>;
trips {
@@ -9429,15 +9448,30 @@ trip-point0 {
type = "hot";
};
+ nsp1_alert0: trip-point1 {
+ temperature = <95000>;
+ hysteresis = <5000>;
+ type = "passive";
+ };
+
nsp1-critical {
temperature = <115000>;
hysteresis = <1000>;
type = "critical";
};
};
+
+ cooling-maps {
+ map0 {
+ trip = <&nsp1_alert0>;
+ cooling-device = <&remoteproc_cdsp QCOM_CDSP_TMD_CDSP_SW
+ THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
};
thermal_nsp2: nsp2-thermal {
+ polling-delay-passive = <200>;
thermal-sensors = <&tsens3 3>;
trips {
@@ -9447,15 +9481,30 @@ trip-point0 {
type = "hot";
};
+ nsp2_alert0: trip-point1 {
+ temperature = <95000>;
+ hysteresis = <5000>;
+ type = "passive";
+ };
+
nsp2-critical {
temperature = <115000>;
hysteresis = <1000>;
type = "critical";
};
};
+
+ cooling-maps {
+ map0 {
+ trip = <&nsp2_alert0>;
+ cooling-device = <&remoteproc_cdsp QCOM_CDSP_TMD_CDSP_SW
+ THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
};
thermal_nsp3: nsp3-thermal {
+ polling-delay-passive = <200>;
thermal-sensors = <&tsens3 4>;
trips {
@@ -9465,12 +9514,26 @@ trip-point0 {
type = "hot";
};
+ nsp3_alert0: trip-point1 {
+ temperature = <95000>;
+ hysteresis = <5000>;
+ type = "passive";
+ };
+
nsp3-critical {
temperature = <115000>;
hysteresis = <1000>;
type = "critical";
};
};
+
+ cooling-maps {
+ map0 {
+ trip = <&nsp3_alert0>;
+ cooling-device = <&remoteproc_cdsp QCOM_CDSP_TMD_CDSP_SW
+ THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
};
thermal_gpuss_0: gpuss-0-thermal {
--
2.34.1
^ permalink raw reply related [flat|nested] 29+ messages in thread
* Re: [PATCH v4 02/10] dt-bindings: remoteproc: qcom,pas: add #cooling-cells property
2026-07-03 5:03 ` [PATCH v4 02/10] dt-bindings: remoteproc: qcom,pas: add #cooling-cells property Gaurav Kohli
@ 2026-07-03 5:15 ` sashiko-bot
2026-07-03 7:49 ` Krzysztof Kozlowski
1 sibling, 0 replies; 29+ messages in thread
From: sashiko-bot @ 2026-07-03 5:15 UTC (permalink / raw)
To: Gaurav Kohli; +Cc: conor+dt, devicetree, robh
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] The newly added example fails `dt_binding_check` due to missing required properties.
--
commit d6d7b5d5f32286193dde6ee3686dfbc725c49024
Author: Gaurav Kohli <gaurav.kohli@oss.qualcomm.com>
dt-bindings: remoteproc: qcom,pas: add #cooling-cells property
This commit documents the optional #cooling-cells property for Qualcomm PAS
remoteproc nodes. It allows them to be used as thermal cooling devices via
the QMI Thermal Mitigation Device interface, and adds an example configuration.
> diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,pas-common.yaml b/Documentation/devicetree/bindings/remoteproc/qcom,pas-common.yaml
> index 4607b459131b4..ef11371058c4f 100644
> --- a/Documentation/devicetree/bindings/remoteproc/qcom,pas-common.yaml
> +++ b/Documentation/devicetree/bindings/remoteproc/qcom,pas-common.yaml
[ ... ]
> @@ -95,3 +103,34 @@ required:
> - qcom,smem-state-names
>
> additionalProperties: true
> +
> +examples:
> + - |
> + #include <dt-bindings/thermal/thermal.h>
> + #include <dt-bindings/firmware/qcom,qmi-tmd.h>
> +
> + remoteproc: remoteproc {
> + #cooling-cells = <3>;
> + };
[Severity: Low]
Will this new example fail dt_binding_check?
Looking at the required list for this schema document, properties like clocks,
clock-names, interrupts, interrupt-names, qcom,smem-states, and
qcom,smem-state-names are mandatory. Because they are omitted from this
remoteproc example node, schema validation will likely fail when the build
system validates the examples.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260703-qmi-tmd-v4-0-3882189c1f83@oss.qualcomm.com?part=2
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v4 03/10] soc: qcom: Add QMI TMD support for remote thermal mitigation
2026-07-03 5:03 ` [PATCH v4 03/10] soc: qcom: Add QMI TMD support for remote thermal mitigation Gaurav Kohli
@ 2026-07-03 5:17 ` sashiko-bot
2026-07-03 8:03 ` Krzysztof Kozlowski
2026-07-03 18:09 ` Julian Braha
2 siblings, 0 replies; 29+ messages in thread
From: sashiko-bot @ 2026-07-03 5:17 UTC (permalink / raw)
To: Gaurav Kohli; +Cc: robh, devicetree, conor+dt
Thank you for your contribution! Sashiko AI review found 6 potential issue(s) to consider:
- [High] Improper teardown sequence in qmi_tmd_exit() creates multiple Use-After-Free vulnerabilities.
- [High] Failure to clear tmd->cdev on registration error causes a kernel panic during unregistration.
- [Medium] Time-Of-Check to Time-Of-Use race in qmi_tmd_register() silently drops requested thermal mitigation state.
- [Medium] Size mismatch between mitigation_device_list_len field and QMI element descriptor causes incorrect decoding on big-endian systems.
- [Low] Missing NET dependency inheritance in Kconfig causes unmet dependency warnings and potential build failures.
- [Low] Mixing goto-based error handling with __free() and scoped_guard() cleanup helpers violates strict cleanup rules.
--
commit f78be8814546ffe0023b5b8c2d56a90a684efe2d
Author: Casey Connolly <casey.connolly@linaro.org>
soc: qcom: Add QMI TMD support for remote thermal mitigation
Add support for Qualcomm Messaging Interface (QMI) based Thermal Mitigation
Device (TMD) cooling devices provided by remote subsystems.
> diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
> index 2caadbbcf8307..44c2b533b494f 100644
> --- a/drivers/soc/qcom/Kconfig
> +++ b/drivers/soc/qcom/Kconfig
[ ... ]
> @@ -128,6 +128,16 @@ config QCOM_QMI_HELPERS
> tristate
> depends on NET
>
> +config QCOM_QMI_TMD
> + bool "Qualcomm remote subsystem TMD" if COMPILE_TEST
> + depends on ARCH_QCOM
> + select QCOM_QMI_HELPERS
[Severity: Low]
Does this config need to inherit the NET dependency?
QCOM_QMI_HELPERS depends on NET, so selecting it without a NET dependency can
cause unmet dependency warnings and build failures if COMPILE_TEST is set and
NET is disabled.
> + help
> + This enables Qualcomm Messaging Interface (QMI) based Thermal Mitigation
> + Device (TMD) support for Qualcomm remote subsystems. It manages
> diff --git a/drivers/soc/qcom/qmi_tmd.c b/drivers/soc/qcom/qmi_tmd.c
> new file mode 100644
> --- /dev/null
> +++ b/drivers/soc/qcom/qmi_tmd.c
[ ... ]
> +struct tmd_get_dev_list_resp {
> + struct qmi_response_type_v01 resp;
> + u8 mitigation_device_list_valid;
> + u32 mitigation_device_list_len;
> + struct tmd_dev_list
> + mitigation_device_list[QMI_TMD_DEV_LIST_MAX];
> +};
> +
> +static const struct qmi_elem_info tmd_get_dev_list_resp_ei[] = {
[ ... ]
> + {
> + .data_type = QMI_DATA_LEN,
> + .elem_len = 1,
> + .elem_size = sizeof(uint8_t),
> + .array_type = NO_ARRAY,
> + .tlv_type = 0x10,
> + .offset = offsetof(struct tmd_get_dev_list_resp,
> + mitigation_device_list_len),
> + },
[Severity: Medium]
Is this element size correct for the target field?
The struct defines mitigation_device_list_len as a u32, but the QMI definition
specifies sizeof(uint8_t).
On big-endian systems, writing 1 byte to the start of a u32 field populates
the most significant byte, resulting in a massively inflated length value. The
loop in qmi_tmd_svc_arrive() would then read out of bounds.
[ ... ]
> +static int qmi_tmd_register(struct qmi_tmd_client *qmi_tmd_cli,
> + const char *label, u8 max_state)
> +{
[ ... ]
> +found:
> + tmd->max_state = max_state;
> +
> + /*
> + * If the cooling device already exists then the QMI service went away and
> + * came back. So just make sure the current cooling device state is
> + * reflected on the remote side and then return.
> + */
> + if (tmd->cdev)
> + return qmi_tmd_send_state_request(tmd, tmd->cur_state);
[Severity: Medium]
Can this race with qmi_tmd_set_cur_state() and send a stale state to the DSP?
qmi_tmd_register() locklessly reads tmd->cur_state here. If a thermal
governor concurrently calls qmi_tmd_set_cur_state() which updates the
requested state, qmi_tmd_register() might read the old state before acquiring
the mutex in qmi_tmd_send_state_request().
This could result in sending the stale state to the DSP, overriding the
active mitigation.
> +
> + tmd->cdev = thermal_of_cooling_device_register(dev->of_node, index,
> + label, tmd, &qmi_tmd_cooling_ops);
> + if (IS_ERR(tmd->cdev))
> + return PTR_ERR(tmd->cdev);
[Severity: High]
Should tmd->cdev be set to NULL here on failure?
If thermal_of_cooling_device_register() fails, it returns an ERR_PTR.
Leaving the error pointer in tmd->cdev causes issues during teardown.
> +
> + return 0;
> +}
> +
> +static void qmi_tmd_unregister(struct qmi_tmd_client *qmi_tmd_cli)
> +{
> + struct qmi_tmd *tmd;
> + int index;
> +
> + for (index = 0; index < qmi_tmd_cli->num_tmds; index++) {
> + tmd = &qmi_tmd_cli->tmds[index];
> +
> + if (!tmd->cdev)
> + continue;
> +
> + thermal_cooling_device_unregister(tmd->cdev);
[Severity: High]
Can this dereference an error pointer and crash?
Because qmi_tmd_register() leaves an ERR_PTR in tmd->cdev on failure, the
if (!tmd->cdev) check evaluates to false. thermal_cooling_device_unregister()
will then attempt to dereference the error pointer.
> + tmd->cdev = NULL;
> + }
> +}
> +
> +static void qmi_tmd_svc_arrive(struct work_struct *work)
> +{
> + struct qmi_tmd_client *qmi_tmd_cli =
> + container_of(work, struct qmi_tmd_client, svc_arrive_work);
> +
> + struct tmd_get_dev_list_req req = { 0 };
> + struct tmd_get_dev_list_resp *resp __free(kfree) = NULL;
> + int ret, i;
> + struct qmi_txn txn;
> +
> + resp = kzalloc_obj(*resp, GFP_KERNEL);
> + if (!resp) {
> + ret = -ENOMEM;
> + goto out;
> + }
> +
> + scoped_guard(mutex, &qmi_tmd_cli->mutex) {
> + ret = qmi_txn_init(&qmi_tmd_cli->handle, &txn,
> + tmd_get_dev_list_resp_ei, resp);
> + if (ret < 0)
> + goto out;
[Severity: Low]
This isn't a bug, but does this function mix goto-based error handling with
__free() and scoped_guard() cleanup helpers?
According to the cleanup guidelines in include/linux/cleanup.h, mixing goto
and cleanup helpers in the same function can create confusing ownership
semantics. It is recommended to convert all resources to scope-based
cleanup, or convert none of them.
[ ... ]
> +void qmi_tmd_exit(struct qmi_tmd_client *qmi_tmd_cli)
> +{
> + if (!qmi_tmd_cli)
> + return;
> +
> + cancel_work_sync(&qmi_tmd_cli->svc_arrive_work);
> + qmi_handle_release(&qmi_tmd_cli->handle);
> + qmi_tmd_unregister(qmi_tmd_cli);
> +
> + scoped_guard(mutex, &qmi_tmd_cli->mutex)
> + qmi_tmd_cli->connection_active = false;
> +}
[Severity: High]
Does this teardown sequence create multiple use-after-free conditions?
First, if svc_arrive_work is cancelled before qmi_handle_release() is called,
an incoming server event can immediately re-queue the work via
qmi_tmd_new_server() since the QMI socket is still active. When the device
unbinds, qmi_tmd_cli is freed, and the workqueue will execute on the freed
structure.
Second, qmi_handle_release() destroys the QMI handle (including the txns IDR)
before the thermal cooling devices are unregistered and before
connection_active is set to false. During this window, a concurrent sysfs
write could invoke qmi_tmd_send_state_request(), see
connection_active == true, and attempt to use the destroyed IDR:
Sysfs thread:
qmi_tmd_send_state_request()
if (!qmi_tmd_cli->connection_active) // Still true!
ret = qmi_txn_init(&qmi_tmd_cli->handle, ...) // UAF on txns IDR
Should this sequence clear connection_active and unregister the thermal
devices first, then release the QMI handle, and finally cancel the workqueue?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260703-qmi-tmd-v4-0-3882189c1f83@oss.qualcomm.com?part=3
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v4 07/10] arm64: dts: qcom: lemans: Enable CDSP cooling
2026-07-03 5:03 ` [PATCH v4 07/10] arm64: dts: qcom: lemans: Enable CDSP cooling Gaurav Kohli
@ 2026-07-03 5:18 ` sashiko-bot
0 siblings, 0 replies; 29+ messages in thread
From: sashiko-bot @ 2026-07-03 5:18 UTC (permalink / raw)
To: Gaurav Kohli; +Cc: devicetree, conor+dt, robh
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] Missing NULL reset of tmd->cdev on registration failure causes invalid pointer dereference during unregistration and breaks subsequent registrations.
- [High] Destroying the QMI handle before unregistering the thermal cooling devices introduces a race condition with userspace resulting in a Use-After-Free.
--
commit 68055a14c90dc23e8743fc49a13b0805f601355b
Author: Gaurav Kohli <gaurav.kohli@oss.qualcomm.com>
Subject: arm64: dts: qcom: lemans: Enable CDSP cooling
This commit sets up CDSP cooling for both instances in the lemans device tree.
It configures the cooling maps and cooling devices to throttle the CDSP when it
reaches 105°C.
> diff --git a/arch/arm64/boot/dts/qcom/lemans.dtsi b/arch/arm64/boot/dts/qcom/lemans.dtsi
> index 353a6e6fd3acb..89fa25e9d3c6d 100644
> --- a/arch/arm64/boot/dts/qcom/lemans.dtsi
> +++ b/arch/arm64/boot/dts/qcom/lemans.dtsi
[ ... ]
> @@ -8764,7 +8769,7 @@ nsp-0-0-0-thermal {
> thermal-sensors = <&tsens2 5>;
>
> trips {
> - trip-point0 {
> + nsp_0_0_0_alert0: trip-point0 {
> temperature = <105000>;
> hysteresis = <5000>;
> type = "passive";
> @@ -8776,6 +8781,14 @@ trip-point1 {
> type = "passive";
> };
> };
> +
> + cooling-maps {
> + map0 {
> + trip = <&nsp_0_0_0_alert0>;
> + cooling-device = <&remoteproc_cdsp0 QCOM_CDSP_TMD_CDSP_SW
> + THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
> + };
> + };
> };
[Severity: High]
Does enabling this cooling device expose a regression involving an invalid
pointer dereference in qmi_tmd_register()?
If thermal_of_cooling_device_register() fails, tmd->cdev holds an ERR_PTR:
drivers/soc/qcom/qmi_tmd.c:qmi_tmd_register() {
...
tmd->cdev = thermal_of_cooling_device_register(dev->of_node, index,
label, tmd, &qmi_tmd_cooling_ops);
if (IS_ERR(tmd->cdev))
return PTR_ERR(tmd->cdev);
...
}
Because tmd->cdev is not reset to NULL, qmi_tmd_unregister() will pass this
ERR_PTR to thermal_cooling_device_unregister(), which expects a valid
pointer or NULL:
drivers/soc/qcom/qmi_tmd.c:qmi_tmd_unregister() {
...
if (!tmd->cdev)
continue;
thermal_cooling_device_unregister(tmd->cdev);
...
}
Will this cause a kernel panic when the thermal core dereferences the
invalid pointer?
Additionally, if the QMI service restarts, would a stale error pointer
silently skip registration entirely?
[ ... ]
> @@ -8784,7 +8797,7 @@ nsp-0-1-0-thermal {
> thermal-sensors = <&tsens2 6>;
>
> trips {
> - trip-point0 {
> + nsp_0_1_0_alert0: trip-point0 {
> temperature = <105000>;
> hysteresis = <5000>;
> type = "passive";
> @@ -8796,6 +8809,14 @@ trip-point1 {
> type = "passive";
> };
> };
> +
> + cooling-maps {
> + map0 {
> + trip = <&nsp_0_1_0_alert0>;
> + cooling-device = <&remoteproc_cdsp0 QCOM_CDSP_TMD_CDSP_SW
> + THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
> + };
> + };
> };
[Severity: High]
Could exposing these cooling devices to userspace trigger a use-after-free
regression during teardown?
In qmi_tmd_exit(), the QMI handle is released before the cooling devices
are unregistered:
drivers/soc/qcom/qmi_tmd.c:qmi_tmd_exit() {
...
qmi_handle_release(&qmi_tmd_cli->handle);
qmi_tmd_unregister(qmi_tmd_cli);
scoped_guard(mutex, &qmi_tmd_cli->mutex)
qmi_tmd_cli->connection_active = false;
...
}
If a concurrent write to the thermal sysfs node invokes
qmi_tmd_set_cur_state() -> qmi_tmd_send_state_request() before the cooling
device is unregistered, the connection_active flag is still true.
Would this cause qmi_txn_init() and qmi_send_request() to operate on the
already destroyed qmi_tmd_cli->handle?
Should qmi_tmd_unregister() be called before releasing the QMI handle to
ensure pending sysfs operations are safely quiesced?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260703-qmi-tmd-v4-0-3882189c1f83@oss.qualcomm.com?part=7
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v4 04/10] remoteproc: qcom: pas: add support for TMD thermal cooling devices
2026-07-03 5:03 ` [PATCH v4 04/10] remoteproc: qcom: pas: add support for TMD thermal cooling devices Gaurav Kohli
@ 2026-07-03 5:22 ` sashiko-bot
2026-07-03 7:56 ` Krzysztof Kozlowski
1 sibling, 0 replies; 29+ messages in thread
From: sashiko-bot @ 2026-07-03 5:22 UTC (permalink / raw)
To: Gaurav Kohli; +Cc: devicetree, robh, conor+dt
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [High] A race condition between `qmi_tmd_exit` and `qmi_tmd_new_server` can lead to a use-after-free of `qmi_tmd_cli`.
- [High] TMD sysfs cooling device callbacks can race with teardown, leading to use-after-free on the QMI transaction IDR.
- [High] Data race on `tmd->cur_state` during QMI server reconnect can result in the remote processor receiving an outdated cooling state.
- [Medium] QCOM_Q6V5_PAS unconditionally selects QCOM_QMI_TMD, which lacks a COMPILE_TEST dependency and indirectly depends on NET, leading to Kconfig unmet dependency warnings and potential build failures.
--
commit 770900471517951fb204f7c5cc18bd57f37681a8
Author: Gaurav Kohli <gaurav.kohli@oss.qualcomm.com>
remoteproc: qcom: pas: add support for TMD thermal cooling devices
This commit registers Thermal Mitigation Devices (TMDs) for PAS-managed
remote processors to enable thermal throttling through QMI. It allows
the thermal framework to request mitigation when remote subsystems
contribute to thermal pressure.
> diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
> index c521c744e7dbe..4fb2163c06556 100644
> --- a/drivers/remoteproc/Kconfig
> +++ b/drivers/remoteproc/Kconfig
> @@ -228,6 +228,7 @@ config QCOM_Q6V5_PAS
> select QCOM_PIL_INFO
> select QCOM_MDT_LOADER
> select QCOM_Q6V5_COMMON
> + select QCOM_QMI_TMD
[Severity: Medium]
Does this unconditionally select QCOM_QMI_TMD without fulfilling its
underlying ARCH_QCOM and NET dependencies?
According to Kconfig subsystem guidelines, selecting a config symbol without
inheriting its dependencies can cause Kconfig unmet dependency warnings and
potential build failures on architectures missing networking infrastructure
or ARCH_QCOM.
> select QCOM_RPROC_COMMON
> select QCOM_SCM
> help
> diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c
> index 808e9609988d3..a4756a449e64b 100644
> --- a/drivers/remoteproc/qcom_q6v5_pas.c
> +++ b/drivers/remoteproc/qcom_q6v5_pas.c
[ ... ]
> @@ -730,6 +749,66 @@ static void qcom_pas_unassign_memory_region(struct qcom_pas *pas)
[ ... ]
> +static int qcom_pas_setup_tmd(struct qcom_pas *pas, const struct qcom_pas_data *desc)
> +{
[ ... ]
> + tmd_inst = qmi_tmd_init(pas->dev, desc->tmd_instance_id, tmd_names, desc->num_tmd);
[Severity: High]
Can a data race on tmd->cur_state during a QMI server reconnect result in the
remote processor receiving an outdated cooling state?
Looking at qmi_tmd_register() in drivers/soc/qcom/qmi_tmd.c:
if (tmd->cdev)
return qmi_tmd_send_state_request(tmd, tmd->cur_state);
The current state is read locklessly without holding cdev->lock. This
introduces a data race with concurrent sysfs updates to the cooling device's
state, which could result in sending an outdated mitigation state over QMI.
> + if (IS_ERR(tmd_inst)) {
> + ret = PTR_ERR(tmd_inst);
[ ... ]
> @@ -852,12 +931,21 @@ static int qcom_pas_probe(struct platform_device *pdev)
[ ... ]
> +remove_setup_tmd:
> + if (pas->tmd_inst)
> + qmi_tmd_exit(pas->tmd_inst);
[Severity: High]
Could a race condition between qmi_tmd_exit() and qmi_tmd_new_server() lead
to a use-after-free of qmi_tmd_cli?
Looking at qmi_tmd_exit() in drivers/soc/qcom/qmi_tmd.c:
cancel_work_sync(&qmi_tmd_cli->svc_arrive_work);
qmi_handle_release(&qmi_tmd_cli->handle);
The work queue is canceled before shutting down incoming QMI notifications via
qmi_handle_release(). If qmi_tmd_new_server() is invoked concurrently, it
could re-queue svc_arrive_work on the global system_highpri_wq, which then
executes after qmi_tmd_cli has been freed.
[Severity: High]
Can TMD sysfs cooling device callbacks race with teardown, leading to a
use-after-free on the QMI transaction IDR?
In qmi_tmd_exit():
qmi_handle_release(&qmi_tmd_cli->handle);
qmi_tmd_unregister(qmi_tmd_cli);
The QMI handle (and its IDR) is released before qmi_tmd_unregister() removes
the thermal cooling devices from sysfs. Meanwhile, connection_active is still
left as true. A concurrent sysfs write to the cur_state file exactly when the
driver is being removed would attempt to call idr_alloc_cyclic() on the
destroyed IDR.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260703-qmi-tmd-v4-0-3882189c1f83@oss.qualcomm.com?part=4
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v4 05/10] remoteproc: qcom_q6v5_pas: enable QMI TMD cooling support
2026-07-03 5:03 ` [PATCH v4 05/10] remoteproc: qcom_q6v5_pas: enable QMI TMD cooling support Gaurav Kohli
@ 2026-07-03 5:23 ` sashiko-bot
0 siblings, 0 replies; 29+ messages in thread
From: sashiko-bot @ 2026-07-03 5:23 UTC (permalink / raw)
To: Gaurav Kohli; +Cc: robh, devicetree, conor+dt
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Critical] Incorrect teardown order in `qmi_tmd_exit()` can lead to a Use-After-Free if `svc_arrive_work` is queued concurrently.
- [High] Failure in `thermal_of_cooling_device_register()` leaves an `ERR_PTR` in `tmd->cdev`, leading to a kernel panic during cleanup in `qmi_tmd_unregister()`.
--
commit 117e89cf6f52e4949e2dfdf865b41f6db55c4ceb
Author: Gaurav Kohli <gaurav.kohli@oss.qualcomm.com>
remoteproc: qcom_q6v5_pas: enable QMI TMD cooling support
Enable Thermal Mitigation Device (TMD) support for PAS-managed CDSP and
modem remote processors on platforms that expose the QMI TMD service.
This provides the mapping between DT cooling indices and QMI TMD names,
allowing remoteproc nodes to act as cooling devices in the thermal
framework.
> diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c
> index a4756a449e64b..e2cce4efec253 100644
> --- a/drivers/remoteproc/qcom_q6v5_pas.c
> +++ b/drivers/remoteproc/qcom_q6v5_pas.c
[ ... ]
> @@ -1141,6 +1150,9 @@ static const struct qcom_pas_data sa8775p_cdsp0_resource = {
> .ssr_name = "cdsp",
> .sysmon_name = "cdsp",
> .ssctl_id = 0x17,
> + .tmd_instance_id = 0x43,
> + .tmd_name = cdsp_tmd_name,
> + .num_tmd = ARRAY_SIZE(cdsp_tmd_name),
[Severity: High]
Could enabling TMD here expose a kernel panic during cleanup?
In drivers/soc/qcom/qmi_tmd.c:qmi_tmd_register(), if
thermal_of_cooling_device_register() fails, it returns an ERR_PTR which is
stored in tmd->cdev without being cleared:
qmi_tmd_register()
tmd->cdev = thermal_of_cooling_device_register(dev->of_node, index,
label, tmd, &qmi_tmd_cooling_ops);
if (IS_ERR(tmd->cdev))
return PTR_ERR(tmd->cdev);
Later during error rollback or driver unbind, qmi_tmd_unregister() bypasses the
NULL check and unconditionally dereferences the error pointer:
qmi_tmd_unregister()
if (!tmd->cdev)
continue;
thermal_cooling_device_unregister(tmd->cdev);
Can passing this ERR_PTR to thermal_cooling_device_unregister() lead to a
panic?
[Severity: Critical]
Is there a use-after-free regression introduced when enabling this feature?
In drivers/soc/qcom/qmi_tmd.c:qmi_tmd_exit(), the teardown order cancels
the work before releasing the QMI handle:
qmi_tmd_exit()
cancel_work_sync(&qmi_tmd_cli->svc_arrive_work);
qmi_handle_release(&qmi_tmd_cli->handle);
Since the QMI RX worker thread is not stopped until qmi_handle_release()
executes, a NEW_SERVER message arriving in this window can trigger
qmi_tmd_new_server() and re-queue the work:
qmi_tmd_new_server()
queue_work(system_highpri_wq, &qmi_tmd_cli->svc_arrive_work);
Once qmi_tmd_exit() returns, the qmi_tmd_cli structure is freed, but the
pending work may execute later. Can this concurrent queueing cause a
use-after-free on qmi_tmd_cli?
> };
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260703-qmi-tmd-v4-0-3882189c1f83@oss.qualcomm.com?part=5
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v4 01/10] dt-bindings: firmware: qcom: tmd: add TMD device type constants
2026-07-03 5:03 ` [PATCH v4 01/10] dt-bindings: firmware: qcom: tmd: add TMD device type constants Gaurav Kohli
@ 2026-07-03 7:47 ` Krzysztof Kozlowski
2026-07-03 10:14 ` Gaurav Kohli
2026-07-03 7:52 ` Krzysztof Kozlowski
2026-07-03 7:53 ` Konrad Dybcio
2 siblings, 1 reply; 29+ messages in thread
From: Krzysztof Kozlowski @ 2026-07-03 7:47 UTC (permalink / raw)
To: Gaurav Kohli
Cc: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Daniel Lezcano, Amit Kucheria,
Manivannan Sadhasivam, Konrad Dybcio, Kees Cook,
Gustavo A. R. Silva, cros-qcom-dts-watchers, linux-arm-msm,
linux-remoteproc, devicetree, linux-kernel, linux-pm,
linux-hardening, Manaf Meethalavalappu Pallikunhi
On Fri, Jul 03, 2026 at 10:33:04AM +0530, Gaurav Kohli wrote:
> Add Device Tree binding constants for Qualcomm Thermal Mitigation
> Device (TMD) types used by remoteproc-backed thermal cooling devices.
>
> Qualcomm remote processors expose thermal mitigation endpoints
> through QMI. These endpoints can be registered with the thermal
> framework via the `#cooling-cells` property on the remoteproc node.
>
> The QMI TMD protocol identifies devices using string names (for example,
> "pa", "modem", and "cdsp_sw"), while the DT cooling-device binding with
> `#cooling-cells = <3>` requires numeric device id in the form:
>
> <&phandle device_id min_state max_state>
>
> Define common TMD device index constants shared across currently
> supported platforms. If a future target requires a different mapping,
> additional target-specific constants can be introduced while preserving
> existing DT ABI.
>
> Signed-off-by: Gaurav Kohli <gaurav.kohli@oss.qualcomm.com>
> ---
> MAINTAINERS | 1 +
> include/dt-bindings/firmware/qcom,qmi-tmd.h | 20 ++++++++++++++++++++
As explained many times: Header file is not a separate commit. You need
binding using this.
> 2 files changed, 21 insertions(+)
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 57656ec0e9d5..ffd85fd1dd80 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -3410,6 +3410,7 @@ F: drivers/firmware/qcom/
> F: drivers/soc/qcom/
> F: drivers/watchdog/gunyah_wdt.c
> F: include/dt-bindings/arm/qcom,ids.h
> +F: include/dt-bindings/firmware/qcom,qmi-tmd.h
> F: include/dt-bindings/firmware/qcom,scm.h
> F: include/dt-bindings/soc/qcom*
> F: include/linux/firmware/qcom
> diff --git a/include/dt-bindings/firmware/qcom,qmi-tmd.h b/include/dt-bindings/firmware/qcom,qmi-tmd.h
> new file mode 100644
> index 000000000000..73efecef0f3c
> --- /dev/null
> +++ b/include/dt-bindings/firmware/qcom,qmi-tmd.h
> @@ -0,0 +1,20 @@
> +/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */
> +/*
> + * Qualcomm QMI TMD (Thermal Mitigation Device) cooling device indices
> + *
> + * These indices are used in device tree cooling-maps to reference
> + * specific TMD devices provided by remote processors via QMI.
> + *
> + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
> + */
> +#ifndef _DT_BINDINGS_FIRMWARE_QCOM_QMI_TMD_H
> +#define _DT_BINDINGS_FIRMWARE_QCOM_QMI_TMD_H
> +
> +/* CDSP thermal mitigation device id */
> +#define QCOM_CDSP_TMD_CDSP_SW 0
QCOM_TMD_CDSP
> +
> +/* Modem thermal mitigation device id */
> +#define QCOM_MODEM_TMD_PA 0
QCOM_TMD_MODEM_PA
> +#define QCOM_MODEM_TMD_MODEM 1
QCOM_TMD_MODEM
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v4 02/10] dt-bindings: remoteproc: qcom,pas: add #cooling-cells property
2026-07-03 5:03 ` [PATCH v4 02/10] dt-bindings: remoteproc: qcom,pas: add #cooling-cells property Gaurav Kohli
2026-07-03 5:15 ` sashiko-bot
@ 2026-07-03 7:49 ` Krzysztof Kozlowski
1 sibling, 0 replies; 29+ messages in thread
From: Krzysztof Kozlowski @ 2026-07-03 7:49 UTC (permalink / raw)
To: Gaurav Kohli
Cc: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Daniel Lezcano, Amit Kucheria,
Manivannan Sadhasivam, Konrad Dybcio, Kees Cook,
Gustavo A. R. Silva, cros-qcom-dts-watchers, linux-arm-msm,
linux-remoteproc, devicetree, linux-kernel, linux-pm,
linux-hardening, Manaf Meethalavalappu Pallikunhi
On Fri, Jul 03, 2026 at 10:33:05AM +0530, Gaurav Kohli wrote:
> Document the optional #cooling-cells property for Qualcomm PAS
> remoteproc nodes so they can be used as thermal cooling devices via
> the QMI Thermal Mitigation Device (TMD) interface.
>
> Qualcomm remote processors expose TMD endpoints that support thermal
> throttling through firmware. The cooling-device specifier uses 3 cells:
>
> <&phandle device_id min_state max_state>
>
> where device_index selects the TMD endpoint (for example PA, modem,
> or CDSP software mitigation), with constants defined in:
> - dt-bindings/firmware/qcom,qmi-tmd.h
Full path.
>
> Signed-off-by: Gaurav Kohli <gaurav.kohli@oss.qualcomm.com>
> ---
> .../bindings/remoteproc/qcom,pas-common.yaml | 39 ++++++++++++++++++++++
> 1 file changed, 39 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,pas-common.yaml b/Documentation/devicetree/bindings/remoteproc/qcom,pas-common.yaml
> index 4607b459131b..ef11371058c4 100644
> --- a/Documentation/devicetree/bindings/remoteproc/qcom,pas-common.yaml
> +++ b/Documentation/devicetree/bindings/remoteproc/qcom,pas-common.yaml
> @@ -79,6 +79,14 @@ properties:
> channels and devices related to the ADSP.
> unevaluatedProperties: false
>
> + '#cooling-cells':
> + description: |
> + Cooling device with three cells:
> + Cell 0: Cooling device id
And here you provide full path with device IDs.
> + Cell 1: Minimum cooling state
> + Cell 2: Maximum cooling state
> + const: 3
> +
> glink-edge:
> $ref: /schemas/remoteproc/qcom,glink-edge.yaml#
> description:
> @@ -95,3 +103,34 @@ required:
> - qcom,smem-state-names
>
> additionalProperties: true
> +
> +examples:
> + - |
> + #include <dt-bindings/thermal/thermal.h>
> + #include <dt-bindings/firmware/qcom,qmi-tmd.h>
> +
> + remoteproc: remoteproc {
> + #cooling-cells = <3>;
> + };
Drop, empty node.
> +
> + thermal-zones {
> + subsystem-thermal {
> + thermal-sensors = <&tsens 0>;
> +
> + trips {
> + alert: alert {
> + temperature = <95000>;
> + hysteresis = <2000>;
> + type = "passive";
> + };
> + };
> +
> + cooling-maps {
> + map0 {
> + trip = <&alert>;
> + cooling-device = <&remoteproc QCOM_CDSP_TMD_CDSP_SW
> + THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
> + };
> + };
> + };
> + };
thermal-zones are not relevant to remoteproc.
Entire example feels pointless - how is schema even applied/matched
against it?
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v4 06/10] arm64: dts: qcom: kodiak: Enable CDSP & Modem cooling
2026-07-03 5:03 ` [PATCH v4 06/10] arm64: dts: qcom: kodiak: Enable CDSP & Modem cooling Gaurav Kohli
@ 2026-07-03 7:51 ` Krzysztof Kozlowski
2026-07-03 15:48 ` Dmitry Baryshkov
1 sibling, 0 replies; 29+ messages in thread
From: Krzysztof Kozlowski @ 2026-07-03 7:51 UTC (permalink / raw)
To: Gaurav Kohli
Cc: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Daniel Lezcano, Amit Kucheria,
Manivannan Sadhasivam, Konrad Dybcio, Kees Cook,
Gustavo A. R. Silva, cros-qcom-dts-watchers, linux-arm-msm,
linux-remoteproc, devicetree, linux-kernel, linux-pm,
linux-hardening, Manaf Meethalavalappu Pallikunhi
On Fri, Jul 03, 2026 at 10:33:09AM +0530, Gaurav Kohli wrote:
> Unlike the CPU, the CDSP/Modem does not throttle its speed automatically
> when it reaches high temperatures in kodiak.
>
> Set up CDSP cooling by throttling the cdsp when it reaches 100°C and
> for modem when it reaches to 95°C.
>
> Since the remoteproc_mpss node doesn't exist on non modem boards, the
> cooling-maps that reference it cause DT compilation errors. To fix that
> remove inherited mdmss cooling-map nodes.
>
> Signed-off-by: Gaurav Kohli <gaurav.kohli@oss.qualcomm.com>
> ---
> arch/arm64/boot/dts/qcom/kodiak.dtsi | 134 ++++++++++++++++++++-
> .../boot/dts/qcom/qcs6490-radxa-dragon-q6a.dts | 17 +++
> arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts | 17 +++
> .../dts/qcom/qcs6490-thundercomm-minipc-g1iot.dts | 17 +++
> .../boot/dts/qcom/qcs6490-thundercomm-rubikpi3.dts | 17 +++
> .../boot/dts/qcom/sc7280-herobrine-lte-sku.dtsi | 17 +++
> .../boot/dts/qcom/sc7280-herobrine-wifi-sku.dtsi | 16 +++
> 7 files changed, 231 insertions(+), 4 deletions(-)
>
> diff --git a/arch/arm64/boot/dts/qcom/kodiak.dtsi b/arch/arm64/boot/dts/qcom/kodiak.dtsi
> index fa540d8c2615..d6fbafae6d3e 100644
> --- a/arch/arm64/boot/dts/qcom/kodiak.dtsi
> +++ b/arch/arm64/boot/dts/qcom/kodiak.dtsi
> @@ -14,6 +14,7 @@
> #include <dt-bindings/clock/qcom,rpmh.h>
> #include <dt-bindings/clock/qcom,videocc-sc7280.h>
> #include <dt-bindings/dma/qcom-gpi.h>
> +#include <dt-bindings/firmware/qcom,qmi-tmd.h>
> #include <dt-bindings/firmware/qcom,scm.h>
> #include <dt-bindings/gpio/gpio.h>
> #include <dt-bindings/interconnect/qcom,icc.h>
> @@ -3427,6 +3428,8 @@ remoteproc_mpss: remoteproc@4080000 {
> qcom,smem-states = <&modem_smp2p_out 0>;
> qcom,smem-state-names = "stop";
>
> + #cooling-cells = <3>;
> +
> status = "disabled";
>
> glink-edge {
> @@ -4787,6 +4790,8 @@ remoteproc_cdsp: remoteproc@a300000 {
> qcom,smem-states = <&cdsp_smp2p_out 0>;
> qcom,smem-state-names = "stop";
>
> + #cooling-cells = <3>;
> +
> status = "disabled";
>
> glink-edge {
> @@ -4906,6 +4911,7 @@ compute-cb@14 {
> };
> };
> };
> +
Please cleanup the patch from irrelevant changes.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v4 01/10] dt-bindings: firmware: qcom: tmd: add TMD device type constants
2026-07-03 5:03 ` [PATCH v4 01/10] dt-bindings: firmware: qcom: tmd: add TMD device type constants Gaurav Kohli
2026-07-03 7:47 ` Krzysztof Kozlowski
@ 2026-07-03 7:52 ` Krzysztof Kozlowski
2026-07-03 10:31 ` Gaurav Kohli
2026-07-03 7:53 ` Konrad Dybcio
2 siblings, 1 reply; 29+ messages in thread
From: Krzysztof Kozlowski @ 2026-07-03 7:52 UTC (permalink / raw)
To: Gaurav Kohli
Cc: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Daniel Lezcano, Amit Kucheria,
Manivannan Sadhasivam, Konrad Dybcio, Kees Cook,
Gustavo A. R. Silva, cros-qcom-dts-watchers, linux-arm-msm,
linux-remoteproc, devicetree, linux-kernel, linux-pm,
linux-hardening, Manaf Meethalavalappu Pallikunhi
On Fri, Jul 03, 2026 at 10:33:04AM +0530, Gaurav Kohli wrote:
> Add Device Tree binding constants for Qualcomm Thermal Mitigation
> Device (TMD) types used by remoteproc-backed thermal cooling devices.
>
> Qualcomm remote processors expose thermal mitigation endpoints
> through QMI. These endpoints can be registered with the thermal
> framework via the `#cooling-cells` property on the remoteproc node.
>
> The QMI TMD protocol identifies devices using string names (for example,
> "pa", "modem", and "cdsp_sw"), while the DT cooling-device binding with
> `#cooling-cells = <3>` requires numeric device id in the form:
>
> <&phandle device_id min_state max_state>
>
> Define common TMD device index constants shared across currently
> supported platforms. If a future target requires a different mapping,
> additional target-specific constants can be introduced while preserving
> existing DT ABI.
>
> Signed-off-by: Gaurav Kohli <gaurav.kohli@oss.qualcomm.com>
> ---
> MAINTAINERS | 1 +
> include/dt-bindings/firmware/qcom,qmi-tmd.h | 20 ++++++++++++++++++++
Why is it put into firmware? What part of firmware are you describing?
To me it looks like thermal thing and even you wrote: Thermal Mitigation Device
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v4 01/10] dt-bindings: firmware: qcom: tmd: add TMD device type constants
2026-07-03 5:03 ` [PATCH v4 01/10] dt-bindings: firmware: qcom: tmd: add TMD device type constants Gaurav Kohli
2026-07-03 7:47 ` Krzysztof Kozlowski
2026-07-03 7:52 ` Krzysztof Kozlowski
@ 2026-07-03 7:53 ` Konrad Dybcio
2026-07-03 14:13 ` Gaurav Kohli
2 siblings, 1 reply; 29+ messages in thread
From: Konrad Dybcio @ 2026-07-03 7:53 UTC (permalink / raw)
To: Gaurav Kohli, Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Daniel Lezcano, Amit Kucheria,
Manivannan Sadhasivam, Konrad Dybcio, Kees Cook,
Gustavo A. R. Silva, cros-qcom-dts-watchers
Cc: linux-arm-msm, linux-remoteproc, devicetree, linux-kernel,
linux-pm, linux-hardening, Manaf Meethalavalappu Pallikunhi
On 7/3/26 7:03 AM, Gaurav Kohli wrote:
> Add Device Tree binding constants for Qualcomm Thermal Mitigation
> Device (TMD) types used by remoteproc-backed thermal cooling devices.
>
> Qualcomm remote processors expose thermal mitigation endpoints
> through QMI. These endpoints can be registered with the thermal
> framework via the `#cooling-cells` property on the remoteproc node.
>
> The QMI TMD protocol identifies devices using string names (for example,
> "pa", "modem", and "cdsp_sw"), while the DT cooling-device binding with
> `#cooling-cells = <3>` requires numeric device id in the form:
>
> <&phandle device_id min_state max_state>
>
> Define common TMD device index constants shared across currently
> supported platforms. If a future target requires a different mapping,
> additional target-specific constants can be introduced while preserving
> existing DT ABI.
>
> Signed-off-by: Gaurav Kohli <gaurav.kohli@oss.qualcomm.com>
> ---
> MAINTAINERS | 1 +
> include/dt-bindings/firmware/qcom,qmi-tmd.h | 20 ++++++++++++++++++++
> 2 files changed, 21 insertions(+)
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 57656ec0e9d5..ffd85fd1dd80 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -3410,6 +3410,7 @@ F: drivers/firmware/qcom/
> F: drivers/soc/qcom/
> F: drivers/watchdog/gunyah_wdt.c
> F: include/dt-bindings/arm/qcom,ids.h
> +F: include/dt-bindings/firmware/qcom,qmi-tmd.h
> F: include/dt-bindings/firmware/qcom,scm.h
> F: include/dt-bindings/soc/qcom*
> F: include/linux/firmware/qcom
> diff --git a/include/dt-bindings/firmware/qcom,qmi-tmd.h b/include/dt-bindings/firmware/qcom,qmi-tmd.h
> new file mode 100644
> index 000000000000..73efecef0f3c
> --- /dev/null
> +++ b/include/dt-bindings/firmware/qcom,qmi-tmd.h
> @@ -0,0 +1,20 @@
> +/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */
> +/*
> + * Qualcomm QMI TMD (Thermal Mitigation Device) cooling device indices
> + *
> + * These indices are used in device tree cooling-maps to reference
> + * specific TMD devices provided by remote processors via QMI.
> + *
> + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
> + */
> +#ifndef _DT_BINDINGS_FIRMWARE_QCOM_QMI_TMD_H
> +#define _DT_BINDINGS_FIRMWARE_QCOM_QMI_TMD_H
> +
> +/* CDSP thermal mitigation device id */
> +#define QCOM_CDSP_TMD_CDSP_SW 0
> +
> +/* Modem thermal mitigation device id */
> +#define QCOM_MODEM_TMD_PA 0
> +#define QCOM_MODEM_TMD_MODEM 1
What about the dozens other ones that Dmitry's laptop reports?
https://lore.kernel.org/linux-arm-msm/4gs664zboaqgpok33x7bgorfmhh3f2fahjkt4jjl6fbzpwixnm@hxzz2xeogd4k/
Konrad
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v4 04/10] remoteproc: qcom: pas: add support for TMD thermal cooling devices
2026-07-03 5:03 ` [PATCH v4 04/10] remoteproc: qcom: pas: add support for TMD thermal cooling devices Gaurav Kohli
2026-07-03 5:22 ` sashiko-bot
@ 2026-07-03 7:56 ` Krzysztof Kozlowski
1 sibling, 0 replies; 29+ messages in thread
From: Krzysztof Kozlowski @ 2026-07-03 7:56 UTC (permalink / raw)
To: Gaurav Kohli
Cc: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Daniel Lezcano, Amit Kucheria,
Manivannan Sadhasivam, Konrad Dybcio, Kees Cook,
Gustavo A. R. Silva, cros-qcom-dts-watchers, linux-arm-msm,
linux-remoteproc, devicetree, linux-kernel, linux-pm,
linux-hardening, Manaf Meethalavalappu Pallikunhi
On Fri, Jul 03, 2026 at 10:33:07AM +0530, Gaurav Kohli wrote:
> + tmd_inst = qmi_tmd_init(pas->dev, desc->tmd_instance_id, tmd_names, desc->num_tmd);
> + if (IS_ERR(tmd_inst)) {
> + ret = PTR_ERR(tmd_inst);
> + if (ret == -ENODEV)
> + return 0;
> +
> + dev_err(pas->dev, "Failed to initialize TMD: %d\n", ret);
You already print error msg in qmi_tmd_init(), no?
Is this probe path (looks like)? If so, why aren't you using
dev_err_probe()?
> + return ret;
> + }
> +
> + pas->tmd_inst = tmd_inst;
> +
> + return 0;
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v4 03/10] soc: qcom: Add QMI TMD support for remote thermal mitigation
2026-07-03 5:03 ` [PATCH v4 03/10] soc: qcom: Add QMI TMD support for remote thermal mitigation Gaurav Kohli
2026-07-03 5:17 ` sashiko-bot
@ 2026-07-03 8:03 ` Krzysztof Kozlowski
2026-07-03 18:09 ` Julian Braha
2 siblings, 0 replies; 29+ messages in thread
From: Krzysztof Kozlowski @ 2026-07-03 8:03 UTC (permalink / raw)
To: Gaurav Kohli
Cc: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Daniel Lezcano, Amit Kucheria,
Manivannan Sadhasivam, Konrad Dybcio, Kees Cook,
Gustavo A. R. Silva, cros-qcom-dts-watchers, linux-arm-msm,
linux-remoteproc, devicetree, linux-kernel, linux-pm,
linux-hardening, Manaf Meethalavalappu Pallikunhi, Casey Connolly
On Fri, Jul 03, 2026 at 10:33:06AM +0530, Gaurav Kohli wrote:
> From: Casey Connolly <casey.connolly@linaro.org>
>
> Add support for Qualcomm Messaging Interface (QMI) based Thermal Mitigation
> Device (TMD) cooling devices provided by remote subsystems.
>
> On Qualcomm platforms where remote processors expose mitigation controls
> through the TMD QMI service, client drivers need support to discover the
> service, register cooling devices for available mitigation endpoints,
> and forward cooling state updates to remote subsystems.
>
> Signed-off-by: Casey Connolly <casey.connolly@linaro.org>
> Co-developed-by: Daniel Lezcano <daniel.lezcano@oss.qualcomm.com>
> Signed-off-by: Daniel Lezcano <daniel.lezcano@oss.qualcomm.com>
> Co-developed-by: Gaurav Kohli <gaurav.kohli@oss.qualcomm.com>
> Signed-off-by: Gaurav Kohli <gaurav.kohli@oss.qualcomm.com>
> ---
> MAINTAINERS | 6 +
> drivers/soc/qcom/Kconfig | 10 +
> drivers/soc/qcom/Makefile | 1 +
> drivers/soc/qcom/qmi_tmd.c | 581 +++++++++++++++++++++++++++++++++++++++
> include/linux/soc/qcom/qmi.h | 1 +
> include/linux/soc/qcom/qmi_tmd.h | 23 ++
> 6 files changed, 622 insertions(+)
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index ffd85fd1dd80..251b1f583913 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -22287,6 +22287,12 @@ F: Documentation/devicetree/bindings/net/qcom,ipq9574-ppe.yaml
> F: Documentation/networking/device_drivers/ethernet/qualcomm/ppe/ppe.rst
> F: drivers/net/ethernet/qualcomm/ppe/
>
> +QUALCOMM QMI (REMOTEPROC THERMAL MITIGATION) TMD
> +M: Gaurav Kohli <gaurav.kohli@oss.qualcomm.com>
> +L: linux-arm-msm@vger.kernel.org
> +L: linux-pm@vger.kernel.org
> +F: drivers/soc/qcom/qmi_tmd.c
> +
> QUALCOMM QSEECOM DRIVER
> M: Maximilian Luz <luzmaximilian@gmail.com>
> L: linux-arm-msm@vger.kernel.org
> diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
> index 2caadbbcf830..44c2b533b494 100644
> --- a/drivers/soc/qcom/Kconfig
> +++ b/drivers/soc/qcom/Kconfig
> @@ -128,6 +128,16 @@ config QCOM_QMI_HELPERS
> tristate
> depends on NET
>
> +config QCOM_QMI_TMD
> + bool "Qualcomm remote subsystem TMD" if COMPILE_TEST
> + depends on ARCH_QCOM
> + select QCOM_QMI_HELPERS
> + help
> + This enables Qualcomm Messaging Interface (QMI) based Thermal Mitigation
> + Device (TMD) support for Qualcomm remote subsystems. It manages
> + TMD messaging and handles QMI communication with remote processors
> + to exchange mitigation state and apply thermal mitigation requests.
> +
> config QCOM_RAMP_CTRL
> tristate "Qualcomm Ramp Controller driver"
> depends on ARCH_QCOM || COMPILE_TEST
> diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile
> index b7f1d2a57367..4544e61c74e7 100644
> --- a/drivers/soc/qcom/Makefile
> +++ b/drivers/soc/qcom/Makefile
> @@ -14,6 +14,7 @@ obj-$(CONFIG_QCOM_PMIC_GLINK) += pmic_glink.o
> obj-$(CONFIG_QCOM_PMIC_GLINK) += pmic_glink_altmode.o
> obj-$(CONFIG_QCOM_PMIC_PDCHARGER_ULOG) += pmic_pdcharger_ulog.o
> CFLAGS_pmic_pdcharger_ulog.o := -I$(src)
> +obj-$(CONFIG_QCOM_QMI_TMD) += qmi_tmd.o
> obj-$(CONFIG_QCOM_QMI_HELPERS) += qmi_helpers.o
> qmi_helpers-y += qmi_encdec.o qmi_interface.o
> obj-$(CONFIG_QCOM_RAMP_CTRL) += ramp_controller.o
> diff --git a/drivers/soc/qcom/qmi_tmd.c b/drivers/soc/qcom/qmi_tmd.c
> new file mode 100644
> index 000000000000..d82500415f8e
> --- /dev/null
> +++ b/drivers/soc/qcom/qmi_tmd.c
> @@ -0,0 +1,581 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2025, Linaro Limited
> + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
> + *
> + * QMI Thermal Mitigation Device (TMD).
> + * Provides cooling device support for remote subsystems
> + * running the TMD service via QMI.
> + */
> +#include <linux/cleanup.h>
> +#include <linux/device.h>
> +#include <linux/err.h>
> +#include <linux/module.h>
> +#include <linux/net.h>
> +#include <linux/of.h>
> +#include <linux/slab.h>
> +#include <linux/soc/qcom/qmi.h>
> +#include <linux/soc/qcom/qmi_tmd.h>
> +#include <linux/thermal.h>
> +
> +#define QMI_TMD_SERVICE_VERS_V01 0x01
> +
> +#define QMI_TMD_SET_LEVEL_REQ 0x0021
> +#define QMI_TMD_GET_DEV_LIST_REQ 0x0020
> +
> +#define QMI_TMD_DEV_ID_LEN_MAX 32
> +#define QMI_TMD_DEV_LIST_MAX 32
> +#define QMI_TMD_RESP_TIMEOUT msecs_to_jiffies(100)
> +#define TMD_GET_LEVEL_REQ_MAX_LEN 36
> +#define TMD_SET_LEVEL_REQ_MAX_LEN 40
> +
> +#define TMD_GET_DEV_LIST_REQ_MAX_LEN 0
> +#define TMD_GET_DEV_LIST_RESP_MAX_LEN 1099
> +
> +struct tmd_dev_id {
> + char mitigation_dev_id[QMI_TMD_DEV_ID_LEN_MAX + 1];
> +};
> +
> +static const struct qmi_elem_info tmd_dev_id_ei[] = {
> + {
> + .data_type = QMI_STRING,
> + .elem_len = QMI_TMD_DEV_ID_LEN_MAX + 1,
> + .elem_size = sizeof(char),
> + .array_type = NO_ARRAY,
> + .tlv_type = 0,
> + .offset = offsetof(struct tmd_dev_id,
> + mitigation_dev_id),
> + },
> + {
> + .data_type = QMI_EOTI,
> + .array_type = NO_ARRAY,
> + .tlv_type = QMI_COMMON_TLV_TYPE,
> + },
> +};
> +
> +struct tmd_dev_list {
> + struct tmd_dev_id mitigation_dev_id;
> + u8 max_mitigation_level;
> +};
> +
> +static const struct qmi_elem_info tmd_dev_list_ei[] = {
> + {
> + .data_type = QMI_STRUCT,
> + .elem_len = 1,
> + .elem_size = sizeof(struct tmd_dev_id),
> + .array_type = NO_ARRAY,
> + .tlv_type = 0,
> + .offset = offsetof(struct tmd_dev_list,
> + mitigation_dev_id),
> + .ei_array = tmd_dev_id_ei,
> + },
> + {
> + .data_type = QMI_UNSIGNED_1_BYTE,
> + .elem_len = 1,
> + .elem_size = sizeof(uint8_t),
> + .array_type = NO_ARRAY,
> + .tlv_type = 0,
> + .offset = offsetof(struct tmd_dev_list,
> + max_mitigation_level),
> + },
> + {
> + .data_type = QMI_EOTI,
> + .array_type = NO_ARRAY,
> + .tlv_type = QMI_COMMON_TLV_TYPE,
> + },
> +};
> +
> +struct tmd_get_dev_list_req {
> + char placeholder;
> +};
> +
> +static const struct qmi_elem_info tmd_get_dev_list_req_ei[] = {
> + {
> + .data_type = QMI_EOTI,
> + .array_type = NO_ARRAY,
> + .tlv_type = QMI_COMMON_TLV_TYPE,
> + },
> +};
> +
> +struct tmd_get_dev_list_resp {
> + struct qmi_response_type_v01 resp;
> + u8 mitigation_device_list_valid;
> + u32 mitigation_device_list_len;
> + struct tmd_dev_list
> + mitigation_device_list[QMI_TMD_DEV_LIST_MAX];
> +};
> +
> +static const struct qmi_elem_info tmd_get_dev_list_resp_ei[] = {
> + {
> + .data_type = QMI_STRUCT,
> + .elem_len = 1,
> + .elem_size = sizeof(struct qmi_response_type_v01),
> + .array_type = NO_ARRAY,
> + .tlv_type = 0x02,
> + .offset = offsetof(struct tmd_get_dev_list_resp,
> + resp),
> + .ei_array = qmi_response_type_v01_ei,
> + },
> + {
> + .data_type = QMI_OPT_FLAG,
> + .elem_len = 1,
> + .elem_size = sizeof(uint8_t),
> + .array_type = NO_ARRAY,
> + .tlv_type = 0x10,
> + .offset = offsetof(struct tmd_get_dev_list_resp,
> + mitigation_device_list_valid),
> + },
> + {
> + .data_type = QMI_DATA_LEN,
> + .elem_len = 1,
> + .elem_size = sizeof(uint8_t),
> + .array_type = NO_ARRAY,
> + .tlv_type = 0x10,
> + .offset = offsetof(struct tmd_get_dev_list_resp,
> + mitigation_device_list_len),
> + },
> + {
> + .data_type = QMI_STRUCT,
> + .elem_len = QMI_TMD_DEV_LIST_MAX,
> + .elem_size = sizeof(struct tmd_dev_list),
> + .array_type = VAR_LEN_ARRAY,
> + .tlv_type = 0x10,
> + .offset = offsetof(struct tmd_get_dev_list_resp,
> + mitigation_device_list),
> + .ei_array = tmd_dev_list_ei,
> + },
> + {
> + .data_type = QMI_EOTI,
> + .array_type = NO_ARRAY,
> + .tlv_type = QMI_COMMON_TLV_TYPE,
> + },
> +};
> +
> +struct tmd_set_level_req {
> + struct tmd_dev_id mitigation_dev_id;
> + u8 mitigation_level;
> +};
> +
> +static const struct qmi_elem_info tmd_set_level_req_ei[] = {
> + {
> + .data_type = QMI_STRUCT,
> + .elem_len = 1,
> + .elem_size = sizeof(struct tmd_dev_id),
> + .array_type = NO_ARRAY,
> + .tlv_type = 0x01,
> + .offset = offsetof(struct tmd_set_level_req,
> + mitigation_dev_id),
> + .ei_array = tmd_dev_id_ei,
> + },
> + {
> + .data_type = QMI_UNSIGNED_1_BYTE,
> + .elem_len = 1,
> + .elem_size = sizeof(uint8_t),
> + .array_type = NO_ARRAY,
> + .tlv_type = 0x02,
> + .offset = offsetof(struct tmd_set_level_req,
> + mitigation_level),
> + },
> + {
> + .data_type = QMI_EOTI,
> + .array_type = NO_ARRAY,
> + .tlv_type = QMI_COMMON_TLV_TYPE,
> + },
> +};
> +
> +struct tmd_set_level_resp {
> + struct qmi_response_type_v01 resp;
> +};
> +
> +static const struct qmi_elem_info tmd_set_level_resp_ei[] = {
> + {
> + .data_type = QMI_STRUCT,
> + .elem_len = 1,
> + .elem_size = sizeof(struct qmi_response_type_v01),
> + .array_type = NO_ARRAY,
> + .tlv_type = 0x02,
> + .offset = offsetof(struct tmd_set_level_resp, resp),
> + .ei_array = qmi_response_type_v01_ei,
> + },
> + {
> + .data_type = QMI_EOTI,
> + .array_type = NO_ARRAY,
> + .tlv_type = QMI_COMMON_TLV_TYPE,
> + },
> +};
> +
> +/**
> + * struct qmi_tmd - A TMD cooling device
> + * @name: The name of this tmd shared by the remote subsystem
> + * @cdev: Thermal cooling device handle
> + * @cur_state: The current mitigation state
> + * @max_state: The maximum state
> + * @qmi_tmd_cli: Parent QMI TMD client
> + */
> +struct qmi_tmd {
> + const char *name;
> + struct thermal_cooling_device *cdev;
> + unsigned int cur_state;
> + unsigned int max_state;
> + struct qmi_tmd_client *qmi_tmd_cli;
> +};
> +
> +/**
> + * struct qmi_tmd_client - QMI TMD client state
> + * @dev: Device associated with this instance
> + * @handle: QMI connection handle
> + * @mutex: Serializes QMI request/response sequences (qmi_txn_init,
> + * qmi_send_request) during DSP subsystem restart and
> + * protects @connection_active flag
> + * @connection_active: Whether or not we're connected to the QMI TMD service
> + * @svc_arrive_work: Work item for initialising when the TMD service starts
> + * @num_tmds: Number of tmds described in the device tree
> + * @tmds: An array of tmd structures
> + */
> +struct qmi_tmd_client {
> + struct device *dev;
> + struct qmi_handle handle;
> + /* protects QMI transactions and connection_active */
> + struct mutex mutex;
> + bool connection_active;
> + struct work_struct svc_arrive_work;
> + int num_tmds;
> + struct qmi_tmd tmds[] __counted_by(num_tmds);
> +};
> +
> +/* Notify the remote subsystem of the requested cooling state */
> +static int qmi_tmd_send_state_request(struct qmi_tmd *tmd, int state)
> +{
> + struct tmd_set_level_resp resp = { 0 };
> + struct tmd_set_level_req req = { 0 };
> + struct qmi_tmd_client *qmi_tmd_cli = tmd->qmi_tmd_cli;
> + struct qmi_txn txn;
> + int ret = 0;
> +
> + guard(mutex)(&qmi_tmd_cli->mutex);
> +
> + if (!qmi_tmd_cli->connection_active)
> + return 0;
> +
> + strscpy(req.mitigation_dev_id.mitigation_dev_id, tmd->name,
> + QMI_TMD_DEV_ID_LEN_MAX + 1);
> + req.mitigation_level = state;
> +
> + ret = qmi_txn_init(&qmi_tmd_cli->handle, &txn,
> + tmd_set_level_resp_ei, &resp);
> + if (ret < 0) {
> + dev_err(qmi_tmd_cli->dev, "qmi set state %d txn init failed for %s ret %d\n",
> + state, tmd->name, ret);
> + return ret;
> + }
> +
> + ret = qmi_send_request(&qmi_tmd_cli->handle, NULL, &txn,
> + QMI_TMD_SET_LEVEL_REQ,
> + TMD_SET_LEVEL_REQ_MAX_LEN,
> + tmd_set_level_req_ei, &req);
> + if (ret < 0) {
> + dev_err(qmi_tmd_cli->dev, "qmi set state %d txn send failed for %s ret %d\n",
> + state, tmd->name, ret);
> + qmi_txn_cancel(&txn);
> + return ret;
> + }
> +
> + ret = qmi_txn_wait(&txn, QMI_TMD_RESP_TIMEOUT);
> + if (ret < 0) {
> + dev_err(qmi_tmd_cli->dev, "qmi set state %d txn wait failed for %s ret %d\n",
> + state, tmd->name, ret);
> + return ret;
> + }
> +
> + if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
> + dev_err(qmi_tmd_cli->dev,
> + "qmi set state %d failed for %s result %#x error %#x\n",
> + state, tmd->name,
> + resp.resp.result, resp.resp.error);
> + return -EREMOTEIO;
> + }
> +
> + dev_dbg(qmi_tmd_cli->dev, "Requested state %d/%d for %s\n", state,
> + tmd->max_state, tmd->name);
> +
> + return 0;
> +}
> +
> +static int qmi_tmd_get_max_state(struct thermal_cooling_device *cdev,
> + unsigned long *state)
> +{
> + struct qmi_tmd *tmd = cdev->devdata;
> +
> + *state = tmd->max_state;
> +
> + return 0;
> +}
> +
> +static int qmi_tmd_get_cur_state(struct thermal_cooling_device *cdev,
> + unsigned long *state)
> +{
> + struct qmi_tmd *tmd = cdev->devdata;
> +
> + /* cur_state is protected by thermal core's cdev->lock */
> + *state = tmd->cur_state;
> +
> + return 0;
> +}
> +
> +static int qmi_tmd_set_cur_state(struct thermal_cooling_device *cdev,
> + unsigned long state)
> +{
> + struct qmi_tmd *tmd = cdev->devdata;
> + int ret;
> +
> + if (state > tmd->max_state)
> + return -EINVAL;
> +
> + /* cur_state is protected by thermal core's cdev->lock */
> + if (tmd->cur_state == state)
> + return 0;
> +
> + ret = qmi_tmd_send_state_request(tmd, state);
> + if (!ret)
> + tmd->cur_state = state;
> +
> + return ret;
> +}
> +
> +static const struct thermal_cooling_device_ops qmi_tmd_cooling_ops = {
> + .get_max_state = qmi_tmd_get_max_state,
> + .get_cur_state = qmi_tmd_get_cur_state,
> + .set_cur_state = qmi_tmd_set_cur_state,
> +};
> +
> +static int qmi_tmd_register(struct qmi_tmd_client *qmi_tmd_cli,
> + const char *label, u8 max_state)
> +{
> + struct device *dev = qmi_tmd_cli->dev;
> + struct qmi_tmd *tmd;
> + int index;
> +
> + for (index = 0; index < qmi_tmd_cli->num_tmds; index++) {
> + tmd = &qmi_tmd_cli->tmds[index];
> +
> + if (!strncasecmp(tmd->name, label,
> + QMI_TMD_DEV_ID_LEN_MAX + 1))
> + goto found;
> + }
> +
> + dev_dbg(qmi_tmd_cli->dev,
> + "TMD '%s' available in firmware but not specified in DT\n",
> + label);
> + return 0;
> +
> +found:
> + tmd->max_state = max_state;
> +
> + /*
> + * If the cooling device already exists then the QMI service went away and
> + * came back. So just make sure the current cooling device state is
> + * reflected on the remote side and then return.
> + */
> + if (tmd->cdev)
> + return qmi_tmd_send_state_request(tmd, tmd->cur_state);
> +
> + tmd->cdev = thermal_of_cooling_device_register(dev->of_node, index,
> + label, tmd, &qmi_tmd_cooling_ops);
> + if (IS_ERR(tmd->cdev))
> + return PTR_ERR(tmd->cdev);
> +
> + return 0;
> +}
> +
> +static void qmi_tmd_unregister(struct qmi_tmd_client *qmi_tmd_cli)
> +{
> + struct qmi_tmd *tmd;
> + int index;
> +
> + for (index = 0; index < qmi_tmd_cli->num_tmds; index++) {
> + tmd = &qmi_tmd_cli->tmds[index];
> +
> + if (!tmd->cdev)
> + continue;
> +
> + thermal_cooling_device_unregister(tmd->cdev);
> + tmd->cdev = NULL;
> + }
> +}
> +
> +static void qmi_tmd_svc_arrive(struct work_struct *work)
> +{
> + struct qmi_tmd_client *qmi_tmd_cli =
> + container_of(work, struct qmi_tmd_client, svc_arrive_work);
> +
> + struct tmd_get_dev_list_req req = { 0 };
> + struct tmd_get_dev_list_resp *resp __free(kfree) = NULL;
> + int ret, i;
> + struct qmi_txn txn;
> +
> + resp = kzalloc_obj(*resp, GFP_KERNEL);
> + if (!resp) {
> + ret = -ENOMEM;
> + goto out;
> + }
> +
> + scoped_guard(mutex, &qmi_tmd_cli->mutex) {
> + ret = qmi_txn_init(&qmi_tmd_cli->handle, &txn,
> + tmd_get_dev_list_resp_ei, resp);
> + if (ret < 0)
> + goto out;
> +
> + ret = qmi_send_request(&qmi_tmd_cli->handle, NULL, &txn,
> + QMI_TMD_GET_DEV_LIST_REQ,
> + TMD_GET_DEV_LIST_REQ_MAX_LEN,
> + tmd_get_dev_list_req_ei, &req);
> + if (ret < 0) {
> + qmi_txn_cancel(&txn);
> + goto out;
> + }
> +
> + ret = qmi_txn_wait(&txn, QMI_TMD_RESP_TIMEOUT);
> + if (ret < 0)
> + goto out;
> +
> + if (resp->resp.result != QMI_RESULT_SUCCESS_V01) {
> + ret = -EPROTO;
> + goto out;
> + }
> +
> + qmi_tmd_cli->connection_active = true;
> + }
> +
> + for (i = 0; i < resp->mitigation_device_list_len; i++) {
> + struct tmd_dev_list *device =
> + &resp->mitigation_device_list[i];
> +
> + ret = qmi_tmd_register(qmi_tmd_cli,
> + device->mitigation_dev_id.mitigation_dev_id,
> + device->max_mitigation_level);
> + if (ret)
> + break;
> + }
> +
> +out:
> + if (ret)
> + dev_err(qmi_tmd_cli->dev, "Failed to initialize TMD service: %d\n", ret);
> +}
> +
> +static void qmi_tmd_del_server(struct qmi_handle *qmi, struct qmi_service *service)
> +{
> + struct qmi_tmd_client *qmi_tmd_cli =
> + container_of(qmi, struct qmi_tmd_client, handle);
> +
> + scoped_guard(mutex, &qmi_tmd_cli->mutex) {
> + qmi_tmd_cli->connection_active = false;
> + }
> +}
> +
> +static int qmi_tmd_new_server(struct qmi_handle *qmi, struct qmi_service *service)
> +{
> + struct sockaddr_qrtr sq = { AF_QIPCRTR, service->node, service->port };
> + struct qmi_tmd_client *qmi_tmd_cli;
> + int ret;
> +
> + qmi_tmd_cli = container_of(qmi, struct qmi_tmd_client, handle);
> +
> + scoped_guard(mutex, &qmi_tmd_cli->mutex) {
> + ret = kernel_connect(qmi->sock, (struct sockaddr_unsized *)&sq,
> + sizeof(sq), 0);
> + }
> +
> + if (ret < 0) {
> + dev_err(qmi_tmd_cli->dev, "QMI connect failed for node %u port %u: %d\n",
> + service->node, service->port, ret);
> + return ret;
> + }
> +
> + queue_work(system_highpri_wq, &qmi_tmd_cli->svc_arrive_work);
> +
> + return 0;
> +}
> +
> +static const struct qmi_ops qmi_tmd_ops = {
> + .new_server = qmi_tmd_new_server,
> + .del_server = qmi_tmd_del_server,
> +};
> +
> +/**
> + * qmi_tmd_init() - Initialize QMI TMD instance
> + * @dev: Device pointer
> + * @instance_id: QMI service instance ID for the remote subsystem
> + * @tmd_names: Array of TMD names
> + * @num_tmds: Number of TMD names
> + *
> + * Return: Pointer to qmi_tmd_client on success, ERR_PTR on failure
> + */
> +struct qmi_tmd_client *qmi_tmd_init(struct device *dev,
> + unsigned int instance_id,
> + const char * const *tmd_names,
> + int num_tmds)
> +{
> + struct qmi_tmd_client *qmi_tmd_cli;
> + int ret, i;
> +
> + if (!dev || !tmd_names || num_tmds <= 0)
> + return ERR_PTR(-EINVAL);
> +
> + qmi_tmd_cli = devm_kzalloc(dev, struct_size(qmi_tmd_cli, tmds, num_tmds), GFP_KERNEL);
Either this is dedicated to probe path or can be called from any context
(probe or not probe). If the first, above is correct, but then:
1. kerneldoc is incomplete or function should be renamed to have _probe suffix,
2. why aren't you using dev_err_probe()?
If the latter, then above code is not correct because you do not have
cleanup in qmi_tmd_exit() part, which leads to unspecific/unorganized
way of cleaning devm resources during cleanup calls. Plus actual cleanup
does not happen when consumer/user calls exit() but when remove() is
called, leading to possible huge memory usage (not leak technically but
same effect).
> + if (!qmi_tmd_cli)
> + return ERR_PTR(-ENOMEM);
> +
> + qmi_tmd_cli->dev = dev;
> + qmi_tmd_cli->num_tmds = num_tmds;
> + mutex_init(&qmi_tmd_cli->mutex);
> + INIT_WORK(&qmi_tmd_cli->svc_arrive_work, qmi_tmd_svc_arrive);
> +
> + for (i = 0; i < num_tmds; i++) {
> + qmi_tmd_cli->tmds[i].name = tmd_names[i];
> + qmi_tmd_cli->tmds[i].qmi_tmd_cli = qmi_tmd_cli;
> + }
> +
> + ret = qmi_handle_init(&qmi_tmd_cli->handle,
> + TMD_GET_DEV_LIST_RESP_MAX_LEN,
> + &qmi_tmd_ops, NULL);
> + if (ret < 0) {
> + dev_err(dev, "QMI handle init failed: %d\n", ret);
> + return ERR_PTR(ret);
> + }
> +
> + ret = qmi_add_lookup(&qmi_tmd_cli->handle, QMI_SERVICE_ID_TMD,
> + QMI_TMD_SERVICE_VERS_V01, instance_id);
> + if (ret < 0) {
> + dev_err(dev, "QMI add lookup failed: %d\n", ret);
> + goto err_release_handle;
> + }
> +
> + return qmi_tmd_cli;
> +
> +err_release_handle:
> + qmi_handle_release(&qmi_tmd_cli->handle);
> +
> + return ERR_PTR(ret);
> +}
> +EXPORT_SYMBOL_GPL(qmi_tmd_init);
> +
> +/**
> + * qmi_tmd_exit() - Deinitialize QMI TMD instance
> + * @qmi_tmd_cli: QMI TMD client to deinitialize
> + */
> +void qmi_tmd_exit(struct qmi_tmd_client *qmi_tmd_cli)
> +{
> + if (!qmi_tmd_cli)
> + return;
> +
> + cancel_work_sync(&qmi_tmd_cli->svc_arrive_work);
And what if work is re-queued now?
> + qmi_handle_release(&qmi_tmd_cli->handle);
> + qmi_tmd_unregister(qmi_tmd_cli);
> +
> + scoped_guard(mutex, &qmi_tmd_cli->mutex)
> + qmi_tmd_cli->connection_active = false;
> +}
> +EXPORT_SYMBOL_GPL(qmi_tmd_exit);
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v4 01/10] dt-bindings: firmware: qcom: tmd: add TMD device type constants
2026-07-03 7:47 ` Krzysztof Kozlowski
@ 2026-07-03 10:14 ` Gaurav Kohli
0 siblings, 0 replies; 29+ messages in thread
From: Gaurav Kohli @ 2026-07-03 10:14 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Daniel Lezcano, Amit Kucheria,
Manivannan Sadhasivam, Konrad Dybcio, Kees Cook,
Gustavo A. R. Silva, cros-qcom-dts-watchers, linux-arm-msm,
linux-remoteproc, devicetree, linux-kernel, linux-pm,
linux-hardening, Manaf Meethalavalappu Pallikunhi
On 7/3/2026 1:17 PM, Krzysztof Kozlowski wrote:
> On Fri, Jul 03, 2026 at 10:33:04AM +0530, Gaurav Kohli wrote:
>> Add Device Tree binding constants for Qualcomm Thermal Mitigation
>> Device (TMD) types used by remoteproc-backed thermal cooling devices.
>>
>> Qualcomm remote processors expose thermal mitigation endpoints
>> through QMI. These endpoints can be registered with the thermal
>> framework via the `#cooling-cells` property on the remoteproc node.
>>
>> The QMI TMD protocol identifies devices using string names (for example,
>> "pa", "modem", and "cdsp_sw"), while the DT cooling-device binding with
>> `#cooling-cells = <3>` requires numeric device id in the form:
>>
>> <&phandle device_id min_state max_state>
>>
>> Define common TMD device index constants shared across currently
>> supported platforms. If a future target requires a different mapping,
>> additional target-specific constants can be introduced while preserving
>> existing DT ABI.
>>
>> Signed-off-by: Gaurav Kohli <gaurav.kohli@oss.qualcomm.com>
>> ---
>> MAINTAINERS | 1 +
>> include/dt-bindings/firmware/qcom,qmi-tmd.h | 20 ++++++++++++++++++++
>
> As explained many times: Header file is not a separate commit. You need
> binding using this.
thanks for review, will club this with binding patch.
>
>> 2 files changed, 21 insertions(+)
>>
>> diff --git a/MAINTAINERS b/MAINTAINERS
>> index 57656ec0e9d5..ffd85fd1dd80 100644
>> --- a/MAINTAINERS
>> +++ b/MAINTAINERS
>> @@ -3410,6 +3410,7 @@ F: drivers/firmware/qcom/
>> F: drivers/soc/qcom/
>> F: drivers/watchdog/gunyah_wdt.c
>> F: include/dt-bindings/arm/qcom,ids.h
>> +F: include/dt-bindings/firmware/qcom,qmi-tmd.h
>> F: include/dt-bindings/firmware/qcom,scm.h
>> F: include/dt-bindings/soc/qcom*
>> F: include/linux/firmware/qcom
>> diff --git a/include/dt-bindings/firmware/qcom,qmi-tmd.h b/include/dt-bindings/firmware/qcom,qmi-tmd.h
>> new file mode 100644
>> index 000000000000..73efecef0f3c
>> --- /dev/null
>> +++ b/include/dt-bindings/firmware/qcom,qmi-tmd.h
>> @@ -0,0 +1,20 @@
>> +/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */
>> +/*
>> + * Qualcomm QMI TMD (Thermal Mitigation Device) cooling device indices
>> + *
>> + * These indices are used in device tree cooling-maps to reference
>> + * specific TMD devices provided by remote processors via QMI.
>> + *
>> + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
>> + */
>> +#ifndef _DT_BINDINGS_FIRMWARE_QCOM_QMI_TMD_H
>> +#define _DT_BINDINGS_FIRMWARE_QCOM_QMI_TMD_H
>> +
>> +/* CDSP thermal mitigation device id */
>> +#define QCOM_CDSP_TMD_CDSP_SW 0
>
> QCOM_TMD_CDSP
>
>> +
>> +/* Modem thermal mitigation device id */
>> +#define QCOM_MODEM_TMD_PA 0
>
> QCOM_TMD_MODEM_PA
>
>> +#define QCOM_MODEM_TMD_MODEM 1
>
> QCOM_TMD_MODEM
Ack, will update like this QMI_TMD_<name>.
>
> Best regards,
> Krzysztof
>
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v4 01/10] dt-bindings: firmware: qcom: tmd: add TMD device type constants
2026-07-03 7:52 ` Krzysztof Kozlowski
@ 2026-07-03 10:31 ` Gaurav Kohli
0 siblings, 0 replies; 29+ messages in thread
From: Gaurav Kohli @ 2026-07-03 10:31 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Daniel Lezcano, Amit Kucheria,
Manivannan Sadhasivam, Konrad Dybcio, Kees Cook,
Gustavo A. R. Silva, cros-qcom-dts-watchers, linux-arm-msm,
linux-remoteproc, devicetree, linux-kernel, linux-pm,
linux-hardening, Manaf Meethalavalappu Pallikunhi
On 7/3/2026 1:22 PM, Krzysztof Kozlowski wrote:
> On Fri, Jul 03, 2026 at 10:33:04AM +0530, Gaurav Kohli wrote:
>> Add Device Tree binding constants for Qualcomm Thermal Mitigation
>> Device (TMD) types used by remoteproc-backed thermal cooling devices.
>>
>> Qualcomm remote processors expose thermal mitigation endpoints
>> through QMI. These endpoints can be registered with the thermal
>> framework via the `#cooling-cells` property on the remoteproc node.
>>
>> The QMI TMD protocol identifies devices using string names (for example,
>> "pa", "modem", and "cdsp_sw"), while the DT cooling-device binding with
>> `#cooling-cells = <3>` requires numeric device id in the form:
>>
>> <&phandle device_id min_state max_state>
>>
>> Define common TMD device index constants shared across currently
>> supported platforms. If a future target requires a different mapping,
>> additional target-specific constants can be introduced while preserving
>> existing DT ABI.
>>
>> Signed-off-by: Gaurav Kohli <gaurav.kohli@oss.qualcomm.com>
>> ---
>> MAINTAINERS | 1 +
>> include/dt-bindings/firmware/qcom,qmi-tmd.h | 20 ++++++++++++++++++++
>
> Why is it put into firmware? What part of firmware are you describing?
> To me it looks like thermal thing and even you wrote: Thermal Mitigation Device
Ack, it looks better under thermal. Will move to
include/dt-bindings/thermal/qcom,qmi-tmd.h in the next version.
>
> Best regards,
> Krzysztof
>
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v4 01/10] dt-bindings: firmware: qcom: tmd: add TMD device type constants
2026-07-03 7:53 ` Konrad Dybcio
@ 2026-07-03 14:13 ` Gaurav Kohli
2026-07-03 15:42 ` Dmitry Baryshkov
0 siblings, 1 reply; 29+ messages in thread
From: Gaurav Kohli @ 2026-07-03 14:13 UTC (permalink / raw)
To: Konrad Dybcio, Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Daniel Lezcano, Amit Kucheria,
Manivannan Sadhasivam, Konrad Dybcio, Kees Cook,
Gustavo A. R. Silva, cros-qcom-dts-watchers
Cc: linux-arm-msm, linux-remoteproc, devicetree, linux-kernel,
linux-pm, linux-hardening, Manaf Meethalavalappu Pallikunhi
On 7/3/2026 1:23 PM, Konrad Dybcio wrote:
> On 7/3/26 7:03 AM, Gaurav Kohli wrote:
>> Add Device Tree binding constants for Qualcomm Thermal Mitigation
>> Device (TMD) types used by remoteproc-backed thermal cooling devices.
>>
>> Qualcomm remote processors expose thermal mitigation endpoints
>> through QMI. These endpoints can be registered with the thermal
>> framework via the `#cooling-cells` property on the remoteproc node.
>>
>> The QMI TMD protocol identifies devices using string names (for example,
>> "pa", "modem", and "cdsp_sw"), while the DT cooling-device binding with
>> `#cooling-cells = <3>` requires numeric device id in the form:
>>
>> <&phandle device_id min_state max_state>
>>
>> Define common TMD device index constants shared across currently
>> supported platforms. If a future target requires a different mapping,
>> additional target-specific constants can be introduced while preserving
>> existing DT ABI.
>>
>> Signed-off-by: Gaurav Kohli <gaurav.kohli@oss.qualcomm.com>
>> ---
>> MAINTAINERS | 1 +
>> include/dt-bindings/firmware/qcom,qmi-tmd.h | 20 ++++++++++++++++++++
>> 2 files changed, 21 insertions(+)
>>
>> diff --git a/MAINTAINERS b/MAINTAINERS
>> index 57656ec0e9d5..ffd85fd1dd80 100644
>> --- a/MAINTAINERS
>> +++ b/MAINTAINERS
>> @@ -3410,6 +3410,7 @@ F: drivers/firmware/qcom/
>> F: drivers/soc/qcom/
>> F: drivers/watchdog/gunyah_wdt.c
>> F: include/dt-bindings/arm/qcom,ids.h
>> +F: include/dt-bindings/firmware/qcom,qmi-tmd.h
>> F: include/dt-bindings/firmware/qcom,scm.h
>> F: include/dt-bindings/soc/qcom*
>> F: include/linux/firmware/qcom
>> diff --git a/include/dt-bindings/firmware/qcom,qmi-tmd.h b/include/dt-bindings/firmware/qcom,qmi-tmd.h
>> new file mode 100644
>> index 000000000000..73efecef0f3c
>> --- /dev/null
>> +++ b/include/dt-bindings/firmware/qcom,qmi-tmd.h
>> @@ -0,0 +1,20 @@
>> +/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */
>> +/*
>> + * Qualcomm QMI TMD (Thermal Mitigation Device) cooling device indices
>> + *
>> + * These indices are used in device tree cooling-maps to reference
>> + * specific TMD devices provided by remote processors via QMI.
>> + *
>> + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
>> + */
>> +#ifndef _DT_BINDINGS_FIRMWARE_QCOM_QMI_TMD_H
>> +#define _DT_BINDINGS_FIRMWARE_QCOM_QMI_TMD_H
>> +
>> +/* CDSP thermal mitigation device id */
>> +#define QCOM_CDSP_TMD_CDSP_SW 0
>> +
>> +/* Modem thermal mitigation device id */
>> +#define QCOM_MODEM_TMD_PA 0
>> +#define QCOM_MODEM_TMD_MODEM 1
>
> What about the dozens other ones that Dmitry's laptop reports?Ri
>
Thanks for the review, Konrad.
We are only defining constants for the TMD devices that are actually
used for thermal mitigation on the platforms supported by this series.
More constants can be added as needed.
> https://lore.kernel.org/linux-arm-msm/4gs664zboaqgpok33x7bgorfmhh3f2fahjkt4jjl6fbzpwixnm@hxzz2xeogd4k/
>
> Konrad
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v4 01/10] dt-bindings: firmware: qcom: tmd: add TMD device type constants
2026-07-03 14:13 ` Gaurav Kohli
@ 2026-07-03 15:42 ` Dmitry Baryshkov
0 siblings, 0 replies; 29+ messages in thread
From: Dmitry Baryshkov @ 2026-07-03 15:42 UTC (permalink / raw)
To: Gaurav Kohli
Cc: Konrad Dybcio, Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Daniel Lezcano, Amit Kucheria,
Manivannan Sadhasivam, Konrad Dybcio, Kees Cook,
Gustavo A. R. Silva, cros-qcom-dts-watchers, linux-arm-msm,
linux-remoteproc, devicetree, linux-kernel, linux-pm,
linux-hardening, Manaf Meethalavalappu Pallikunhi
On Fri, Jul 03, 2026 at 07:43:39PM +0530, Gaurav Kohli wrote:
>
>
> On 7/3/2026 1:23 PM, Konrad Dybcio wrote:
> > On 7/3/26 7:03 AM, Gaurav Kohli wrote:
> > > Add Device Tree binding constants for Qualcomm Thermal Mitigation
> > > Device (TMD) types used by remoteproc-backed thermal cooling devices.
> > >
> > > Qualcomm remote processors expose thermal mitigation endpoints
> > > through QMI. These endpoints can be registered with the thermal
> > > framework via the `#cooling-cells` property on the remoteproc node.
> > >
> > > The QMI TMD protocol identifies devices using string names (for example,
> > > "pa", "modem", and "cdsp_sw"), while the DT cooling-device binding with
> > > `#cooling-cells = <3>` requires numeric device id in the form:
> > >
> > > <&phandle device_id min_state max_state>
> > >
> > > Define common TMD device index constants shared across currently
> > > supported platforms. If a future target requires a different mapping,
> > > additional target-specific constants can be introduced while preserving
> > > existing DT ABI.
> > >
> > > Signed-off-by: Gaurav Kohli <gaurav.kohli@oss.qualcomm.com>
> > > ---
> > > MAINTAINERS | 1 +
> > > include/dt-bindings/firmware/qcom,qmi-tmd.h | 20 ++++++++++++++++++++
> > > 2 files changed, 21 insertions(+)
> > >
> > > diff --git a/MAINTAINERS b/MAINTAINERS
> > > index 57656ec0e9d5..ffd85fd1dd80 100644
> > > --- a/MAINTAINERS
> > > +++ b/MAINTAINERS
> > > @@ -3410,6 +3410,7 @@ F: drivers/firmware/qcom/
> > > F: drivers/soc/qcom/
> > > F: drivers/watchdog/gunyah_wdt.c
> > > F: include/dt-bindings/arm/qcom,ids.h
> > > +F: include/dt-bindings/firmware/qcom,qmi-tmd.h
> > > F: include/dt-bindings/firmware/qcom,scm.h
> > > F: include/dt-bindings/soc/qcom*
> > > F: include/linux/firmware/qcom
> > > diff --git a/include/dt-bindings/firmware/qcom,qmi-tmd.h b/include/dt-bindings/firmware/qcom,qmi-tmd.h
> > > new file mode 100644
> > > index 000000000000..73efecef0f3c
> > > --- /dev/null
> > > +++ b/include/dt-bindings/firmware/qcom,qmi-tmd.h
> > > @@ -0,0 +1,20 @@
> > > +/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */
> > > +/*
> > > + * Qualcomm QMI TMD (Thermal Mitigation Device) cooling device indices
> > > + *
> > > + * These indices are used in device tree cooling-maps to reference
> > > + * specific TMD devices provided by remote processors via QMI.
> > > + *
> > > + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
> > > + */
> > > +#ifndef _DT_BINDINGS_FIRMWARE_QCOM_QMI_TMD_H
> > > +#define _DT_BINDINGS_FIRMWARE_QCOM_QMI_TMD_H
> > > +
> > > +/* CDSP thermal mitigation device id */
> > > +#define QCOM_CDSP_TMD_CDSP_SW 0
> > > +
> > > +/* Modem thermal mitigation device id */
> > > +#define QCOM_MODEM_TMD_PA 0
> > > +#define QCOM_MODEM_TMD_MODEM 1
> >
> > What about the dozens other ones that Dmitry's laptop reports?Ri
> >
>
> Thanks for the review, Konrad.
>
> We are only defining constants for the TMD devices that are actually used
> for thermal mitigation on the platforms supported by this series.
Why are you using only those TMD devices?
> More constants can be added as needed.
Kodiak is one of the supported platforms.
Running the same tool produces:
TMD service: instance=0x00 (modem) node=0 port=20
29 mitigation device(s):
[ 0] pa max_mitigation_level=3
[ 1] pa_fr1 max_mitigation_level=3
[ 2] modem max_mitigation_level=3
[ 3] cpuv_restriction_cold max_mitigation_level=1
[ 4] modem_current max_mitigation_level=3
[ 5] vbatt_low max_mitigation_level=3
[ 6] charge_state max_mitigation_level=3
[ 7] modem_skin max_mitigation_level=3
[ 8] modem_bw max_mitigation_level=5
[ 9] mmw0 max_mitigation_level=3
[10] mmw1 max_mitigation_level=3
[11] mmw2 max_mitigation_level=3
[12] mmw3 max_mitigation_level=3
[13] mmw_skin0 max_mitigation_level=3
[14] mmw_skin1 max_mitigation_level=3
[15] mmw_skin2 max_mitigation_level=3
[16] mmw_skin3 max_mitigation_level=3
[17] mmw_skin0_dsc max_mitigation_level=15
[18] mmw_skin1_dsc max_mitigation_level=15
[19] mmw_skin2_dsc max_mitigation_level=15
[20] mmw_skin3_dsc max_mitigation_level=15
[21] wlan max_mitigation_level=4
[22] wlan_bw max_mitigation_level=1
[23] modem_skin_lte_dsc max_mitigation_level=255
[24] modem_skin_nr_dsc max_mitigation_level=255
[25] pa_dsc max_mitigation_level=255
[26] pa_fr1_dsc max_mitigation_level=255
[27] modem_bw_backoff max_mitigation_level=255
[28] cpr_cold max_mitigation_level=3
TMD service: instance=0x01 (adsp) node=5 port=8
1 mitigation device(s):
[ 0] cpuv_restriction_cold max_mitigation_level=1
TMD service: instance=0x43 (cdsp) node=10 port=9
3 mitigation device(s):
[ 0] cpuv_restriction_cold max_mitigation_level=1
[ 1] cdsp_hw max_mitigation_level=1
[ 2] cdsp_sw max_mitigation_level=7
>
> > https://lore.kernel.org/linux-arm-msm/4gs664zboaqgpok33x7bgorfmhh3f2fahjkt4jjl6fbzpwixnm@hxzz2xeogd4k/
> >
> > Konrad
>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v4 06/10] arm64: dts: qcom: kodiak: Enable CDSP & Modem cooling
2026-07-03 5:03 ` [PATCH v4 06/10] arm64: dts: qcom: kodiak: Enable CDSP & Modem cooling Gaurav Kohli
2026-07-03 7:51 ` Krzysztof Kozlowski
@ 2026-07-03 15:48 ` Dmitry Baryshkov
1 sibling, 0 replies; 29+ messages in thread
From: Dmitry Baryshkov @ 2026-07-03 15:48 UTC (permalink / raw)
To: Gaurav Kohli
Cc: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Daniel Lezcano, Amit Kucheria,
Manivannan Sadhasivam, Konrad Dybcio, Kees Cook,
Gustavo A. R. Silva, cros-qcom-dts-watchers, linux-arm-msm,
linux-remoteproc, devicetree, linux-kernel, linux-pm,
linux-hardening, Manaf Meethalavalappu Pallikunhi
On Fri, Jul 03, 2026 at 10:33:09AM +0530, Gaurav Kohli wrote:
> Unlike the CPU, the CDSP/Modem does not throttle its speed automatically
> when it reaches high temperatures in kodiak.
>
> Set up CDSP cooling by throttling the cdsp when it reaches 100°C and
> for modem when it reaches to 95°C.
>
> Since the remoteproc_mpss node doesn't exist on non modem boards, the
> cooling-maps that reference it cause DT compilation errors. To fix that
> remove inherited mdmss cooling-map nodes.
>
> Signed-off-by: Gaurav Kohli <gaurav.kohli@oss.qualcomm.com>
> ---
> arch/arm64/boot/dts/qcom/kodiak.dtsi | 134 ++++++++++++++++++++-
> .../boot/dts/qcom/qcs6490-radxa-dragon-q6a.dts | 17 +++
> arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts | 17 +++
> .../dts/qcom/qcs6490-thundercomm-minipc-g1iot.dts | 17 +++
> .../boot/dts/qcom/qcs6490-thundercomm-rubikpi3.dts | 17 +++
> .../boot/dts/qcom/sc7280-herobrine-lte-sku.dtsi | 17 +++
> .../boot/dts/qcom/sc7280-herobrine-wifi-sku.dtsi | 16 +++
> 7 files changed, 231 insertions(+), 4 deletions(-)
>
> @@ -7716,6 +7722,8 @@ map0 {
> };
>
> nspss0-thermal {
> + polling-delay-passive = <200>;
Why? This applies to all added polling delays.
> +
> thermal-sensors = <&tsens1 3>;
>
> trips {
> diff --git a/arch/arm64/boot/dts/qcom/qcs6490-radxa-dragon-q6a.dts b/arch/arm64/boot/dts/qcom/qcs6490-radxa-dragon-q6a.dts
> index bb5a42b038f1..400d128132fc 100644
> --- a/arch/arm64/boot/dts/qcom/qcs6490-radxa-dragon-q6a.dts
> +++ b/arch/arm64/boot/dts/qcom/qcs6490-radxa-dragon-q6a.dts
> @@ -24,6 +24,23 @@
> /delete-node/ &adsp_mem;
> /delete-node/ &cdsp_mem;
> /delete-node/ &ipa_fw_mem;
> +
> +&mdmss0_thermal {
> + /delete-node/ cooling-maps;
Don't kill what is unnecessary to be killed. Remove only MPSS maps.
> +};
> +
> +&mdmss1_thermal {
> + /delete-node/ cooling-maps;
> +};
> +
> +&mdmss2_thermal {
> + /delete-node/ cooling-maps;
> +};
> +
> +&mdmss3_thermal {
> + /delete-node/ cooling-maps;
> +};
> +
> /delete-node/ &mpss_mem;
> /delete-node/ &remoteproc_mpss;
> /delete-node/ &remoteproc_wpss;
> diff --git a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts
> index 37a3b51323ce..187bc2899191 100644
> --- a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts
> +++ b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts
> @@ -25,6 +25,23 @@
> /delete-node/ &rmtfs_mem;
> /delete-node/ &adsp_mem;
> /delete-node/ &cdsp_mem;
> +
> +&mdmss0_thermal {
> + /delete-node/ cooling-maps;
But MPSS is there. Why are you removing it?
> +};
> +
> +&mdmss1_thermal {
> + /delete-node/ cooling-maps;
> +};
> +
> +&mdmss2_thermal {
> + /delete-node/ cooling-maps;
> +};
> +
> +&mdmss3_thermal {
> + /delete-node/ cooling-maps;
> +};
> +
> /delete-node/ &video_mem;
> /delete-node/ &wlan_ce_mem;
> /delete-node/ &wpss_mem;
> diff --git a/arch/arm64/boot/dts/qcom/qcs6490-thundercomm-minipc-g1iot.dts b/arch/arm64/boot/dts/qcom/qcs6490-thundercomm-minipc-g1iot.dts
> index a5ad796cb65d..1e190ed18ae5 100644
> --- a/arch/arm64/boot/dts/qcom/qcs6490-thundercomm-minipc-g1iot.dts
> +++ b/arch/arm64/boot/dts/qcom/qcs6490-thundercomm-minipc-g1iot.dts
> @@ -22,6 +22,23 @@
> /delete-node/ &cdsp_mem;
> /delete-node/ &ipa_fw_mem;
> /delete-node/ &mpss_mem;
> +
> +&mdmss0_thermal {
> + /delete-node/ cooling-maps;
> +};
> +
> +&mdmss1_thermal {
> + /delete-node/ cooling-maps;
> +};
> +
> +&mdmss2_thermal {
> + /delete-node/ cooling-maps;
> +};
> +
> +&mdmss3_thermal {
> + /delete-node/ cooling-maps;
> +};
> +
> /delete-node/ &remoteproc_mpss;
> /delete-node/ &remoteproc_wpss;
> /delete-node/ &rmtfs_mem;
> diff --git a/arch/arm64/boot/dts/qcom/qcs6490-thundercomm-rubikpi3.dts b/arch/arm64/boot/dts/qcom/qcs6490-thundercomm-rubikpi3.dts
> index f47efca42d48..8e8dd4efd8c0 100644
> --- a/arch/arm64/boot/dts/qcom/qcs6490-thundercomm-rubikpi3.dts
> +++ b/arch/arm64/boot/dts/qcom/qcs6490-thundercomm-rubikpi3.dts
> @@ -23,6 +23,23 @@
> /delete-node/ &adsp_mem;
> /delete-node/ &cdsp_mem;
> /delete-node/ &ipa_fw_mem;
> +
> +&mdmss0_thermal {
> + /delete-node/ cooling-maps;
> +};
> +
> +&mdmss1_thermal {
> + /delete-node/ cooling-maps;
> +};
> +
> +&mdmss2_thermal {
> + /delete-node/ cooling-maps;
> +};
> +
> +&mdmss3_thermal {
> + /delete-node/ cooling-maps;
> +};
> +
> /delete-node/ &mpss_mem;
> /delete-node/ &remoteproc_mpss;
> /delete-node/ &remoteproc_wpss;
> diff --git a/arch/arm64/boot/dts/qcom/sc7280-herobrine-lte-sku.dtsi b/arch/arm64/boot/dts/qcom/sc7280-herobrine-lte-sku.dtsi
> index b721a8546800..1e9d7e7b5fa2 100644
> --- a/arch/arm64/boot/dts/qcom/sc7280-herobrine-lte-sku.dtsi
> +++ b/arch/arm64/boot/dts/qcom/sc7280-herobrine-lte-sku.dtsi
> @@ -26,8 +26,25 @@ &ipa {
> status = "okay";
> };
>
> +&mdmss0_thermal {
> + /delete-node/ cooling-maps;
> +};
> +
> +&mdmss1_thermal {
> + /delete-node/ cooling-maps;
> +};
> +
> +&mdmss2_thermal {
> + /delete-node/ cooling-maps;
> +};
> +
> +&mdmss3_thermal {
> + /delete-node/ cooling-maps;
> +};
> +
> &remoteproc_mpss {
> compatible = "qcom,sc7280-mss-pil";
> + /delete-property/ #cooling-cells;
> reg = <0 0x04080000 0 0x10000>, <0 0x04180000 0 0x48>;
> reg-names = "qdsp6", "rmb";
>
> diff --git a/arch/arm64/boot/dts/qcom/sc7280-herobrine-wifi-sku.dtsi b/arch/arm64/boot/dts/qcom/sc7280-herobrine-wifi-sku.dtsi
> index 3ebc915f0dc2..6642076f62c4 100644
> --- a/arch/arm64/boot/dts/qcom/sc7280-herobrine-wifi-sku.dtsi
> +++ b/arch/arm64/boot/dts/qcom/sc7280-herobrine-wifi-sku.dtsi
> @@ -7,6 +7,22 @@
>
> /* WIFI SKUs save 256M by not having modem/mba/rmtfs memory regions defined. */
>
> +&mdmss0_thermal {
> + /delete-node/ cooling-maps;
> +};
> +
> +&mdmss1_thermal {
> + /delete-node/ cooling-maps;
> +};
> +
> +&mdmss2_thermal {
> + /delete-node/ cooling-maps;
> +};
> +
> +&mdmss3_thermal {
> + /delete-node/ cooling-maps;
> +};
> +
> /delete-node/ &mpss_mem;
> /delete-node/ &remoteproc_mpss;
> /delete-node/ &rmtfs_mem;
>
> --
> 2.34.1
>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v4 03/10] soc: qcom: Add QMI TMD support for remote thermal mitigation
2026-07-03 5:03 ` [PATCH v4 03/10] soc: qcom: Add QMI TMD support for remote thermal mitigation Gaurav Kohli
2026-07-03 5:17 ` sashiko-bot
2026-07-03 8:03 ` Krzysztof Kozlowski
@ 2026-07-03 18:09 ` Julian Braha
2 siblings, 0 replies; 29+ messages in thread
From: Julian Braha @ 2026-07-03 18:09 UTC (permalink / raw)
To: Gaurav Kohli, Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Daniel Lezcano, Amit Kucheria,
Manivannan Sadhasivam, Konrad Dybcio, Kees Cook,
Gustavo A. R. Silva, cros-qcom-dts-watchers
Cc: linux-arm-msm, linux-remoteproc, devicetree, linux-kernel,
linux-pm, linux-hardening, Manaf Meethalavalappu Pallikunhi,
Casey Connolly
Hi all,
On 7/3/26 06:03, Gaurav Kohli wrote:
> +config QCOM_QMI_TMD
> + bool "Qualcomm remote subsystem TMD" if COMPILE_TEST
> + depends on ARCH_QCOM
> + select QCOM_QMI_HELPERS
> + help
> + This enables Qualcomm Messaging Interface (QMI) based Thermal Mitigation
> + Device (TMD) support for Qualcomm remote subsystems. It manages
> + TMD messaging and handles QMI communication with remote processors
> + to exchange mitigation state and apply thermal mitigation requests.
> +
QCOM_QMI_TMD can trigger an unmet dependency and build failure due to
selecting QCOM_QMI_HELPERS, without ensuring NET is enabled:
WARNING: unmet direct dependencies detected for QCOM_QMI_HELPERS
Depends on [n]: NET [=n]
Selected by [y]:
- QCOM_QMI_TMD [=y] && ARCH_QCOM [=y]
- Julian Braha
^ permalink raw reply [flat|nested] 29+ messages in thread
end of thread, other threads:[~2026-07-03 18:09 UTC | newest]
Thread overview: 29+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-03 5:03 [PATCH v4 00/10] Add support for Qualcomm remoteproc subsystem cooling Gaurav Kohli
2026-07-03 5:03 ` [PATCH v4 01/10] dt-bindings: firmware: qcom: tmd: add TMD device type constants Gaurav Kohli
2026-07-03 7:47 ` Krzysztof Kozlowski
2026-07-03 10:14 ` Gaurav Kohli
2026-07-03 7:52 ` Krzysztof Kozlowski
2026-07-03 10:31 ` Gaurav Kohli
2026-07-03 7:53 ` Konrad Dybcio
2026-07-03 14:13 ` Gaurav Kohli
2026-07-03 15:42 ` Dmitry Baryshkov
2026-07-03 5:03 ` [PATCH v4 02/10] dt-bindings: remoteproc: qcom,pas: add #cooling-cells property Gaurav Kohli
2026-07-03 5:15 ` sashiko-bot
2026-07-03 7:49 ` Krzysztof Kozlowski
2026-07-03 5:03 ` [PATCH v4 03/10] soc: qcom: Add QMI TMD support for remote thermal mitigation Gaurav Kohli
2026-07-03 5:17 ` sashiko-bot
2026-07-03 8:03 ` Krzysztof Kozlowski
2026-07-03 18:09 ` Julian Braha
2026-07-03 5:03 ` [PATCH v4 04/10] remoteproc: qcom: pas: add support for TMD thermal cooling devices Gaurav Kohli
2026-07-03 5:22 ` sashiko-bot
2026-07-03 7:56 ` Krzysztof Kozlowski
2026-07-03 5:03 ` [PATCH v4 05/10] remoteproc: qcom_q6v5_pas: enable QMI TMD cooling support Gaurav Kohli
2026-07-03 5:23 ` sashiko-bot
2026-07-03 5:03 ` [PATCH v4 06/10] arm64: dts: qcom: kodiak: Enable CDSP & Modem cooling Gaurav Kohli
2026-07-03 7:51 ` Krzysztof Kozlowski
2026-07-03 15:48 ` Dmitry Baryshkov
2026-07-03 5:03 ` [PATCH v4 07/10] arm64: dts: qcom: lemans: Enable CDSP cooling Gaurav Kohli
2026-07-03 5:18 ` sashiko-bot
2026-07-03 5:03 ` [PATCH v4 08/10] arm64: dts: qcom: talos: " Gaurav Kohli
2026-07-03 5:03 ` [PATCH v4 09/10] arm64: dts: qcom: monaco: " Gaurav Kohli
2026-07-03 5:03 ` [PATCH v4 10/10] arm64: dts: qcom: hamoa: " Gaurav Kohli
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox