* [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 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, 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
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 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
` (6 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,
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 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, 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
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:03 ` [PATCH v4 06/10] arm64: dts: qcom: kodiak: Enable CDSP & Modem cooling Gaurav Kohli
` (4 subsequent siblings)
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
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:03 ` [PATCH v4 08/10] arm64: dts: qcom: talos: " Gaurav Kohli
` (2 subsequent siblings)
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 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 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 7:49 ` Krzysztof Kozlowski
2026-07-05 8:41 ` Gaurav Kohli
0 siblings, 1 reply; 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 7:56 ` Krzysztof Kozlowski
2026-07-05 9:56 ` Gaurav Kohli
0 siblings, 1 reply; 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 8:03 ` Krzysztof Kozlowski
2026-07-05 9:37 ` Gaurav Kohli
2026-07-03 18:09 ` Julian Braha
1 sibling, 1 reply; 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
2026-07-05 10:19 ` Gaurav Kohli
1 sibling, 1 reply; 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 8:03 ` Krzysztof Kozlowski
@ 2026-07-03 18:09 ` Julian Braha
2026-07-05 9:50 ` Gaurav Kohli
1 sibling, 1 reply; 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
* Re: [PATCH v4 02/10] dt-bindings: remoteproc: qcom,pas: add #cooling-cells property
2026-07-03 7:49 ` Krzysztof Kozlowski
@ 2026-07-05 8:41 ` Gaurav Kohli
0 siblings, 0 replies; 29+ messages in thread
From: Gaurav Kohli @ 2026-07-05 8:41 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:19 PM, Krzysztof Kozlowski wrote:
> 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.
thanks for review, will update this.
>
>> + 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.
>
Ack, will remove this.
>> +
>> + 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.
>
Ack, wanted to show by example, can i use commit message for that.
> 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 03/10] soc: qcom: Add QMI TMD support for remote thermal mitigation
2026-07-03 8:03 ` Krzysztof Kozlowski
@ 2026-07-05 9:37 ` Gaurav Kohli
0 siblings, 0 replies; 29+ messages in thread
From: Gaurav Kohli @ 2026-07-05 9:37 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, Casey Connolly
On 7/3/2026 1:33 PM, Krzysztof Kozlowski wrote:
> 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()?
>
Thanks for review, this is probe-path only.
Will update the comment for context and dev_err_probe as well.
> 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?
Thanks for catching this, qmi_handle_release should come before cancel
of work item. Releasing the handle closes the socket which prevents any
further callbacks. Will update this.
>
>> + 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 03/10] soc: qcom: Add QMI TMD support for remote thermal mitigation
2026-07-03 18:09 ` Julian Braha
@ 2026-07-05 9:50 ` Gaurav Kohli
0 siblings, 0 replies; 29+ messages in thread
From: Gaurav Kohli @ 2026-07-05 9:50 UTC (permalink / raw)
To: Julian Braha, 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
On 7/3/2026 11:39 PM, Julian Braha wrote:
> 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]
Thanks for review. Will add depends on NET to fix the unmet dependency.
>
> - Julian Braha
^ 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 7:56 ` Krzysztof Kozlowski
@ 2026-07-05 9:56 ` Gaurav Kohli
0 siblings, 0 replies; 29+ messages in thread
From: Gaurav Kohli @ 2026-07-05 9:56 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:26 PM, Krzysztof Kozlowski wrote:
> 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?
>
thanks for review, this looks redundant. will drop it.
> 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 06/10] arm64: dts: qcom: kodiak: Enable CDSP & Modem cooling
2026-07-03 15:48 ` Dmitry Baryshkov
@ 2026-07-05 10:19 ` Gaurav Kohli
0 siblings, 0 replies; 29+ messages in thread
From: Gaurav Kohli @ 2026-07-05 10:19 UTC (permalink / raw)
To: Dmitry Baryshkov
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 9:18 PM, Dmitry Baryshkov wrote:
> 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.
Thanks for review, will update the reasoning(passive polling mode) in
commit message.
>
>> +
>> 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.
Thanks for review, will change this to delete only the MPSS map entries.
>
>> +};
>> +
>> +&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?
thanks for review, Let me recheck this and fix this.
>
>> +};
>> +
>> +&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 [flat|nested] 29+ messages in thread
end of thread, other threads:[~2026-07-05 10:19 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 7:49 ` Krzysztof Kozlowski
2026-07-05 8:41 ` Gaurav Kohli
2026-07-03 5:03 ` [PATCH v4 03/10] soc: qcom: Add QMI TMD support for remote thermal mitigation Gaurav Kohli
2026-07-03 8:03 ` Krzysztof Kozlowski
2026-07-05 9:37 ` Gaurav Kohli
2026-07-03 18:09 ` Julian Braha
2026-07-05 9:50 ` Gaurav Kohli
2026-07-03 5:03 ` [PATCH v4 04/10] remoteproc: qcom: pas: add support for TMD thermal cooling devices Gaurav Kohli
2026-07-03 7:56 ` Krzysztof Kozlowski
2026-07-05 9:56 ` Gaurav Kohli
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 ` [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-05 10:19 ` Gaurav Kohli
2026-07-03 5:03 ` [PATCH v4 07/10] arm64: dts: qcom: lemans: Enable CDSP cooling Gaurav Kohli
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