* [PATCH v5 1/9] dt-bindings: remoteproc: qcom,pas: add #cooling-cells property
2026-07-21 6:28 [PATCH v5 0/9] Add support for Qualcomm remoteproc subsystem cooling Gaurav Kohli
@ 2026-07-21 6:28 ` Gaurav Kohli
2026-07-22 7:06 ` Krzysztof Kozlowski
2026-07-21 6:28 ` [PATCH v5 2/9] soc: qcom: Add QMI TMD support for remote thermal mitigation Gaurav Kohli
` (7 subsequent siblings)
8 siblings, 1 reply; 24+ messages in thread
From: Gaurav Kohli @ 2026-07-21 6:28 UTC (permalink / raw)
To: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Daniel Lezcano, Amit Kucheria,
Konrad Dybcio, Rafael J. Wysocki, Daniel Lezcano, Zhang Rui,
Lukasz Luba, Manivannan Sadhasivam, 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.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_id selects the TMD endpoint (for example PA, modem, or
CDSP software mitigation), with constants defined in:
include/dt-bindings/thermal/qcom,qmi-tmd.h
Example usage in a thermal zone:
cooling-maps {
map0 {
trip = <&cpu_alert>;
cooling-device = <&remoteproc_cdsp
QCOM_TMD_CDSP_SW
0 THERMAL_NO_LIMIT>;
};
};
Signed-off-by: Gaurav Kohli <gaurav.kohli@oss.qualcomm.com>
---
.../bindings/remoteproc/qcom,pas-common.yaml | 9 +++++++++
MAINTAINERS | 1 +
include/dt-bindings/thermal/qcom,qmi-tmd.h | 20 ++++++++++++++++++++
3 files changed, 30 insertions(+)
diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,pas-common.yaml b/Documentation/devicetree/bindings/remoteproc/qcom,pas-common.yaml
index 11faf655f530..39e79a1c1079 100644
--- a/Documentation/devicetree/bindings/remoteproc/qcom,pas-common.yaml
+++ b/Documentation/devicetree/bindings/remoteproc/qcom,pas-common.yaml
@@ -77,6 +77,15 @@ properties:
channels and devices related to the ADSP.
unevaluatedProperties: false
+ '#cooling-cells':
+ description: |
+ Cooling device with three cells:
+ Cell 0: Cooling device id as defined in
+ include/dt-bindings/thermal/qcom,qmi-tmd.h
+ Cell 1: Minimum cooling state
+ Cell 2: Maximum cooling state
+ const: 3
+
glink-edge:
$ref: /schemas/remoteproc/qcom,glink-edge.yaml#
description:
diff --git a/MAINTAINERS b/MAINTAINERS
index dcffe9fc54f6..2d4d19201aec 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3423,6 +3423,7 @@ F: drivers/watchdog/gunyah_wdt.c
F: include/dt-bindings/arm/qcom,ids.h
F: include/dt-bindings/firmware/qcom,scm.h
F: include/dt-bindings/soc/qcom*
+F: include/dt-bindings/thermal/qcom,qmi-tmd.h
F: include/linux/firmware/qcom
F: include/linux/soc/qcom/
F: include/soc/qcom/
diff --git a/include/dt-bindings/thermal/qcom,qmi-tmd.h b/include/dt-bindings/thermal/qcom,qmi-tmd.h
new file mode 100644
index 000000000000..a07a515905e7
--- /dev/null
+++ b/include/dt-bindings/thermal/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_THERMAL_QCOM_QMI_TMD_H
+#define _DT_BINDINGS_THERMAL_QCOM_QMI_TMD_H
+
+/* CDSP thermal mitigation device id */
+#define QCOM_TMD_CDSP_SW 0
+
+/* Modem thermal mitigation device id */
+#define QCOM_TMD_PA 0
+#define QCOM_TMD_MODEM 1
+
+#endif /* _DT_BINDINGS_THERMAL_QCOM_QMI_TMD_H */
--
2.34.1
^ permalink raw reply related [flat|nested] 24+ messages in thread* Re: [PATCH v5 1/9] dt-bindings: remoteproc: qcom,pas: add #cooling-cells property
2026-07-21 6:28 ` [PATCH v5 1/9] dt-bindings: remoteproc: qcom,pas: add #cooling-cells property Gaurav Kohli
@ 2026-07-22 7:06 ` Krzysztof Kozlowski
2026-07-22 13:38 ` Gaurav Kohli
0 siblings, 1 reply; 24+ messages in thread
From: Krzysztof Kozlowski @ 2026-07-22 7:06 UTC (permalink / raw)
To: Gaurav Kohli
Cc: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Daniel Lezcano, Amit Kucheria,
Konrad Dybcio, Rafael J. Wysocki, Daniel Lezcano, Zhang Rui,
Lukasz Luba, Manivannan Sadhasivam, Kees Cook,
Gustavo A. R. Silva, cros-qcom-dts-watchers, linux-arm-msm,
linux-remoteproc, devicetree, linux-kernel, linux-pm,
linux-hardening, manaf.pallikunhi
On Tue, Jul 21, 2026 at 11:58:58AM +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_id selects the TMD endpoint (for example PA, modem, or
> CDSP software mitigation), with constants defined in:
> include/dt-bindings/thermal/qcom,qmi-tmd.h
>
> Example usage in a thermal zone:
>
> cooling-maps {
> map0 {
> trip = <&cpu_alert>;
> cooling-device = <&remoteproc_cdsp
> QCOM_TMD_CDSP_SW
> 0 THERMAL_NO_LIMIT>;
> };
> };
>
> Signed-off-by: Gaurav Kohli <gaurav.kohli@oss.qualcomm.com>
> ---
> .../bindings/remoteproc/qcom,pas-common.yaml | 9 +++++++++
> MAINTAINERS | 1 +
> include/dt-bindings/thermal/qcom,qmi-tmd.h | 20 ++++++++++++++++++++
> 3 files changed, 30 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,pas-common.yaml b/Documentation/devicetree/bindings/remoteproc/qcom,pas-common.yaml
> index 11faf655f530..39e79a1c1079 100644
> --- a/Documentation/devicetree/bindings/remoteproc/qcom,pas-common.yaml
> +++ b/Documentation/devicetree/bindings/remoteproc/qcom,pas-common.yaml
> @@ -77,6 +77,15 @@ properties:
> channels and devices related to the ADSP.
> unevaluatedProperties: false
>
> + '#cooling-cells':
> + description: |
> + Cooling device with three cells:
> + Cell 0: Cooling device id as defined in
> + include/dt-bindings/thermal/qcom,qmi-tmd.h
> + Cell 1: Minimum cooling state
> + Cell 2: Maximum cooling state
> + const: 3
> +
> glink-edge:
> $ref: /schemas/remoteproc/qcom,glink-edge.yaml#
> description:
> diff --git a/MAINTAINERS b/MAINTAINERS
> index dcffe9fc54f6..2d4d19201aec 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -3423,6 +3423,7 @@ F: drivers/watchdog/gunyah_wdt.c
> F: include/dt-bindings/arm/qcom,ids.h
> F: include/dt-bindings/firmware/qcom,scm.h
> F: include/dt-bindings/soc/qcom*
> +F: include/dt-bindings/thermal/qcom,qmi-tmd.h
> F: include/linux/firmware/qcom
> F: include/linux/soc/qcom/
> F: include/soc/qcom/
> diff --git a/include/dt-bindings/thermal/qcom,qmi-tmd.h b/include/dt-bindings/thermal/qcom,qmi-tmd.h
Filename must match compatible. There are no qcom,qmi-tmd or qcom,.*tmd
or qcom,.*qmi compatibles.
Which device is providing this ABI? PAS?
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 24+ messages in thread* Re: [PATCH v5 1/9] dt-bindings: remoteproc: qcom,pas: add #cooling-cells property
2026-07-22 7:06 ` Krzysztof Kozlowski
@ 2026-07-22 13:38 ` Gaurav Kohli
2026-07-23 7:22 ` Krzysztof Kozlowski
0 siblings, 1 reply; 24+ messages in thread
From: Gaurav Kohli @ 2026-07-22 13:38 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Daniel Lezcano, Amit Kucheria,
Konrad Dybcio, Rafael J. Wysocki, Daniel Lezcano, Zhang Rui,
Lukasz Luba, Manivannan Sadhasivam, Kees Cook,
Gustavo A. R. Silva, cros-qcom-dts-watchers, linux-arm-msm,
linux-remoteproc, devicetree, linux-kernel, linux-pm,
linux-hardening, manaf.pallikunhi
On 7/22/2026 12:36 PM, Krzysztof Kozlowski wrote:
> On Tue, Jul 21, 2026 at 11:58:58AM +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_id selects the TMD endpoint (for example PA, modem, or
>> CDSP software mitigation), with constants defined in:
>> include/dt-bindings/thermal/qcom,qmi-tmd.h
>>
>> Example usage in a thermal zone:
>>
>> cooling-maps {
>> map0 {
>> trip = <&cpu_alert>;
>> cooling-device = <&remoteproc_cdsp
>> QCOM_TMD_CDSP_SW
>> 0 THERMAL_NO_LIMIT>;
>> };
>> };
>>
>> Signed-off-by: Gaurav Kohli <gaurav.kohli@oss.qualcomm.com>
>> ---
>> .../bindings/remoteproc/qcom,pas-common.yaml | 9 +++++++++
>> MAINTAINERS | 1 +
>> include/dt-bindings/thermal/qcom,qmi-tmd.h | 20 ++++++++++++++++++++
>> 3 files changed, 30 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,pas-common.yaml b/Documentation/devicetree/bindings/remoteproc/qcom,pas-common.yaml
>> index 11faf655f530..39e79a1c1079 100644
>> --- a/Documentation/devicetree/bindings/remoteproc/qcom,pas-common.yaml
>> +++ b/Documentation/devicetree/bindings/remoteproc/qcom,pas-common.yaml
>> @@ -77,6 +77,15 @@ properties:
>> channels and devices related to the ADSP.
>> unevaluatedProperties: false
>>
>> + '#cooling-cells':
>> + description: |
>> + Cooling device with three cells:
>> + Cell 0: Cooling device id as defined in
>> + include/dt-bindings/thermal/qcom,qmi-tmd.h
>> + Cell 1: Minimum cooling state
>> + Cell 2: Maximum cooling state
>> + const: 3
>> +
>> glink-edge:
>> $ref: /schemas/remoteproc/qcom,glink-edge.yaml#
>> description:
>> diff --git a/MAINTAINERS b/MAINTAINERS
>> index dcffe9fc54f6..2d4d19201aec 100644
>> --- a/MAINTAINERS
>> +++ b/MAINTAINERS
>> @@ -3423,6 +3423,7 @@ F: drivers/watchdog/gunyah_wdt.c
>> F: include/dt-bindings/arm/qcom,ids.h
>> F: include/dt-bindings/firmware/qcom,scm.h
>> F: include/dt-bindings/soc/qcom*
>> +F: include/dt-bindings/thermal/qcom,qmi-tmd.h
>> F: include/linux/firmware/qcom
>> F: include/linux/soc/qcom/
>> F: include/soc/qcom/
>> diff --git a/include/dt-bindings/thermal/qcom,qmi-tmd.h b/include/dt-bindings/thermal/qcom,qmi-tmd.h
>
> Filename must match compatible. There are no qcom,qmi-tmd or qcom,.*tmd
> or qcom,.*qmi compatibles.
>
> Which device is providing this ABI? PAS?
thanks for review.
Yes, this belongs under PAS. Should i rename the file to pas?
>
> Best regards,
> Krzysztof
>
^ permalink raw reply [flat|nested] 24+ messages in thread* Re: [PATCH v5 1/9] dt-bindings: remoteproc: qcom,pas: add #cooling-cells property
2026-07-22 13:38 ` Gaurav Kohli
@ 2026-07-23 7:22 ` Krzysztof Kozlowski
0 siblings, 0 replies; 24+ messages in thread
From: Krzysztof Kozlowski @ 2026-07-23 7:22 UTC (permalink / raw)
To: Gaurav Kohli
Cc: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Daniel Lezcano, Amit Kucheria,
Konrad Dybcio, Rafael J. Wysocki, Daniel Lezcano, Zhang Rui,
Lukasz Luba, Manivannan Sadhasivam, Kees Cook,
Gustavo A. R. Silva, cros-qcom-dts-watchers, linux-arm-msm,
linux-remoteproc, devicetree, linux-kernel, linux-pm,
linux-hardening, manaf.pallikunhi
On Wed, Jul 22, 2026 at 07:08:07PM +0530, Gaurav Kohli wrote:
> > Filename must match compatible. There are no qcom,qmi-tmd or qcom,.*tmd
> > or qcom,.*qmi compatibles.
> >
> > Which device is providing this ABI? PAS?
>
> thanks for review.
> Yes, this belongs under PAS. Should i rename the file to pas?
qcom,pas.yaml would work for me.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v5 2/9] soc: qcom: Add QMI TMD support for remote thermal mitigation
2026-07-21 6:28 [PATCH v5 0/9] Add support for Qualcomm remoteproc subsystem cooling Gaurav Kohli
2026-07-21 6:28 ` [PATCH v5 1/9] dt-bindings: remoteproc: qcom,pas: add #cooling-cells property Gaurav Kohli
@ 2026-07-21 6:28 ` Gaurav Kohli
2026-07-21 6:48 ` sashiko-bot
2026-07-21 6:29 ` [PATCH v5 3/9] remoteproc: qcom: pas: add support for TMD thermal cooling devices Gaurav Kohli
` (6 subsequent siblings)
8 siblings, 1 reply; 24+ messages in thread
From: Gaurav Kohli @ 2026-07-21 6:28 UTC (permalink / raw)
To: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Daniel Lezcano, Amit Kucheria,
Konrad Dybcio, Rafael J. Wysocki, Daniel Lezcano, Zhang Rui,
Lukasz Luba, Manivannan Sadhasivam, 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.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 | 7 +
drivers/soc/qcom/Kconfig | 11 +
drivers/soc/qcom/Makefile | 1 +
drivers/soc/qcom/qmi_tmd.c | 595 +++++++++++++++++++++++++++++++++++++++
include/linux/soc/qcom/qmi.h | 1 +
include/linux/soc/qcom/qmi_tmd.h | 22 ++
6 files changed, 637 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index 2d4d19201aec..7ed0eb16962c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -22389,6 +22389,13 @@ 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
+S: Maintained
+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 fd4d4ecd2df0..5c38d598e486 100644
--- a/drivers/soc/qcom/Kconfig
+++ b/drivers/soc/qcom/Kconfig
@@ -319,6 +319,17 @@ config QCOM_QMI_HELPERS
tristate
depends on NET
+config QCOM_QMI_TMD
+ bool "Qualcomm remote subsystem TMD" if COMPILE_TEST
+ depends on ARCH_QCOM && NET
+ select QRTR
+ 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_UBWC_CONFIG
tristate
help
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..b31046241af8
--- /dev/null
+++ b/drivers/soc/qcom/qmi_tmd.c
@@ -0,0 +1,595 @@
+// 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;
+ u8 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 and @exiting
+ * @connection_active: Whether or not we're connected to the QMI TMD service
+ * @exiting: Whether or not teardown has started
+ * @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, connection_active and exiting */
+ struct mutex mutex;
+ bool connection_active;
+ bool exiting;
+ 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)) {
+ int ret = PTR_ERR(tmd->cdev);
+
+ tmd->cdev = NULL;
+ return ret;
+ }
+
+ 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) {
+ if (qmi_tmd_cli->exiting)
+ return;
+
+ 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) {
+ if (qmi_tmd_cli->exiting)
+ return 0;
+
+ 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
+ *
+ * Context: Must be called from probe context.
+ *
+ * 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)
+ return ERR_PTR(dev_err_probe(dev, ret, "QMI handle init failed\n"));
+
+ ret = qmi_add_lookup(&qmi_tmd_cli->handle, QMI_SERVICE_ID_TMD,
+ QMI_TMD_SERVICE_VERS_V01, instance_id);
+ if (ret < 0) {
+ dev_err_probe(dev, ret, "QMI add lookup failed\n");
+ 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;
+
+ scoped_guard(mutex, &qmi_tmd_cli->mutex) {
+ qmi_tmd_cli->exiting = true;
+ qmi_tmd_cli->connection_active = false;
+ }
+
+ qmi_handle_release(&qmi_tmd_cli->handle);
+ cancel_work_sync(&qmi_tmd_cli->svc_arrive_work);
+ qmi_tmd_unregister(qmi_tmd_cli);
+}
+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..fca17a901215
--- /dev/null
+++ b/include/linux/soc/qcom/qmi_tmd.h
@@ -0,0 +1,22 @@
+/* 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] 24+ messages in thread* Re: [PATCH v5 2/9] soc: qcom: Add QMI TMD support for remote thermal mitigation
2026-07-21 6:28 ` [PATCH v5 2/9] soc: qcom: Add QMI TMD support for remote thermal mitigation Gaurav Kohli
@ 2026-07-21 6:48 ` sashiko-bot
2026-07-22 13:25 ` Gaurav Kohli
0 siblings, 1 reply; 24+ messages in thread
From: sashiko-bot @ 2026-07-21 6:48 UTC (permalink / raw)
To: Gaurav Kohli; +Cc: robh, devicetree, conor+dt
Thank you for your contribution! Sashiko AI review found 5 potential issue(s) to consider:
- [High] Data race on `tmd->cur_state` between `qmi_tmd_register()` and `qmi_tmd_set_cur_state()` causes thermal mitigation state desynchronization.
- [High] The `mitigation_device_list_len` field in `struct tmd_get_dev_list_resp` is defined as a `u8`, causing a 3-byte out-of-bounds write when decoded by the QMI framework.
- [Medium] Current state is not capped to the new maximum state during firmware restart synchronization.
- [Medium] Improper dependencies prevent COMPILE_TEST coverage and force dependencies to become built-in.
- [Low] Building with CONFIG_THERMAL=m and CONFIG_QCOM_QMI_TMD=y causes a linker error.
--
--- Patch [2]: [PATCH v5 2/9] soc: qcom: Add QMI TMD support for remote thermal mitigation ---
commit 977e2b6f2dd6931cec0ac743a4bead6a6e561872
Author: Casey Connolly <casey.connolly@linaro.org>
soc: qcom: Add QMI TMD support for remote thermal mitigation
This commit adds support for QMI-based Thermal Mitigation Device (TMD)
cooling devices provided by remote subsystems. It introduces a driver
that discovers the TMD service via QMI, registers cooling devices for
available mitigation endpoints, and forwards state updates.
> diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
> index fd4d4ecd2df0f..5c38d598e4864 100644
> --- a/drivers/soc/qcom/Kconfig
> +++ b/drivers/soc/qcom/Kconfig
> @@ -319,6 +319,17 @@ config QCOM_QMI_HELPERS
> tristate
> depends on NET
>
> +config QCOM_QMI_TMD
> + bool "Qualcomm remote subsystem TMD" if COMPILE_TEST
> + depends on ARCH_QCOM && NET
> + select QRTR
> + select QCOM_QMI_HELPERS
[Severity: Medium]
Does defining this as a boolean rather than a tristate force the selected
tristate dependencies (QRTR and QCOM_QMI_HELPERS) to become built-in when
enabled?
Also, since the depends line strictly requires ARCH_QCOM, does this prevent
the COMPILE_TEST coverage from working on other architectures?
[Severity: Low]
If the kernel is configured with THERMAL=m and QCOM_QMI_TMD=y, will this
cause a linker error due to the missing THERMAL dependency?
> + help
> + This enables Qualcomm Messaging Interface (QMI) based Thermal Mitigation
[ ... ]
> diff --git a/drivers/soc/qcom/qmi_tmd.c b/drivers/soc/qcom/qmi_tmd.c
> new file mode 100644
> index 0000000000000..b31046241af8b
> --- /dev/null
> +++ b/drivers/soc/qcom/qmi_tmd.c
[ ... ]
> +struct tmd_get_dev_list_resp {
> + struct qmi_response_type_v01 resp;
> + u8 mitigation_device_list_valid;
> + u8 mitigation_device_list_len;
> + struct tmd_dev_list
> + mitigation_device_list[QMI_TMD_DEV_LIST_MAX];
> +};
[Severity: High]
Since the QMI framework decodes QMI_DATA_LEN elements by writing 4 bytes
(sizeof(u32)), does defining this length field as a u8 cause a 3-byte
out-of-bounds write?
Could this memory corruption overwrite the first few bytes of the
mitigation_device_list array during decoding?
[ ... ]
> +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 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);
[Severity: Medium]
If the remote QMI service restarts and advertises a lower maximum mitigation
level than before, will this send the old uncapped state to the firmware?
Should we clamp the current state to the new maximum state before sending
the request?
[Severity: High]
Can a concurrent thermal state update cause a race condition here?
If qmi_tmd_register() runs in the workqueue context and reads the state without
a lock:
qmi_tmd_svc_arrive()->qmi_tmd_register()
return qmi_tmd_send_state_request(tmd, tmd->cur_state);
And qmi_tmd_set_cur_state() concurrently updates the state:
qmi_tmd_set_cur_state()
ret = qmi_tmd_send_state_request(tmd, state);
if (!ret)
tmd->cur_state = state;
Could qmi_tmd_register() end up sending a stale state to the firmware, causing
the remote mitigation state to become permanently desynchronized?
> +
> + tmd->cdev = thermal_of_cooling_device_register(dev->of_node, index,
> + label, tmd, &qmi_tmd_cooling_ops);
> + if (IS_ERR(tmd->cdev)) {
> + int ret = PTR_ERR(tmd->cdev);
> +
> + tmd->cdev = NULL;
> + return ret;
> + }
> +
> + return 0;
> +}
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260721-b4-qmi-tmd-v5-0-99620e07f505@oss.qualcomm.com?part=2
^ permalink raw reply [flat|nested] 24+ messages in thread* Re: [PATCH v5 2/9] soc: qcom: Add QMI TMD support for remote thermal mitigation
2026-07-21 6:48 ` sashiko-bot
@ 2026-07-22 13:25 ` Gaurav Kohli
2026-07-22 13:33 ` Dmitry Baryshkov
0 siblings, 1 reply; 24+ messages in thread
From: Gaurav Kohli @ 2026-07-22 13:25 UTC (permalink / raw)
To: sashiko-reviews; +Cc: robh, devicetree, conor+dt
On 7/21/2026 12:18 PM, sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 5 potential issue(s) to consider:
> - [High] Data race on `tmd->cur_state` between `qmi_tmd_register()` and `qmi_tmd_set_cur_state()` causes thermal mitigation state desynchronization.
this looks false positive, as the QMI request path is serialized by
qmi_tmd_cli->mutex in qmi_tmd_send_state_request().
> - [High] The `mitigation_device_list_len` field in `struct tmd_get_dev_list_resp` is defined as a `u8`, causing a 3-byte out-of-bounds write when decoded by the QMI framework.
will fix this.
> - [Medium] Current state is not capped to the new maximum state during firmware restart synchronization.
This is a false positive for this firmware interface.
max_mitigation_level is stable for a given TMD endpoint across service
restarts.
> - [Medium] Improper dependencies prevent COMPILE_TEST coverage and force dependencies to become built-in.
The COMPILE_TEST concern is not relevant here. This driver is
Qualcomm-specific and depends on ARCH_QCOM.
> - [Low] Building with CONFIG_THERMAL=m and CONFIG_QCOM_QMI_TMD=y causes a linker error.
This configuration is not possible in this tree. THERMAL is a bool
symbol in drivers/thermal/Kconfig, not a tristate.
> --
>
> --- Patch [2]: [PATCH v5 2/9] soc: qcom: Add QMI TMD support for remote thermal mitigation ---
> commit 977e2b6f2dd6931cec0ac743a4bead6a6e561872
> Author: Casey Connolly <casey.connolly@linaro.org>
>
> soc: qcom: Add QMI TMD support for remote thermal mitigation
>
> This commit adds support for QMI-based Thermal Mitigation Device (TMD)
> cooling devices provided by remote subsystems. It introduces a driver
> that discovers the TMD service via QMI, registers cooling devices for
> available mitigation endpoints, and forwards state updates.
>
>> diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
>> index fd4d4ecd2df0f..5c38d598e4864 100644
>> --- a/drivers/soc/qcom/Kconfig
>> +++ b/drivers/soc/qcom/Kconfig
>> @@ -319,6 +319,17 @@ config QCOM_QMI_HELPERS
>> tristate
>> depends on NET
>>
>> +config QCOM_QMI_TMD
>> + bool "Qualcomm remote subsystem TMD" if COMPILE_TEST
>> + depends on ARCH_QCOM && NET
>> + select QRTR
>> + select QCOM_QMI_HELPERS
>
> [Severity: Medium]
> Does defining this as a boolean rather than a tristate force the selected
> tristate dependencies (QRTR and QCOM_QMI_HELPERS) to become built-in when
> enabled?
>
> Also, since the depends line strictly requires ARCH_QCOM, does this prevent
> the COMPILE_TEST coverage from working on other architectures?
>
> [Severity: Low]
> If the kernel is configured with THERMAL=m and QCOM_QMI_TMD=y, will this
> cause a linker error due to the missing THERMAL dependency?
>
>> + help
>> + This enables Qualcomm Messaging Interface (QMI) based Thermal Mitigation
>
> [ ... ]
>
>> diff --git a/drivers/soc/qcom/qmi_tmd.c b/drivers/soc/qcom/qmi_tmd.c
>> new file mode 100644
>> index 0000000000000..b31046241af8b
>> --- /dev/null
>> +++ b/drivers/soc/qcom/qmi_tmd.c
>
> [ ... ]
>
>> +struct tmd_get_dev_list_resp {
>> + struct qmi_response_type_v01 resp;
>> + u8 mitigation_device_list_valid;
>> + u8 mitigation_device_list_len;
>> + struct tmd_dev_list
>> + mitigation_device_list[QMI_TMD_DEV_LIST_MAX];
>> +};
>
> [Severity: High]
> Since the QMI framework decodes QMI_DATA_LEN elements by writing 4 bytes
> (sizeof(u32)), does defining this length field as a u8 cause a 3-byte
> out-of-bounds write?
>
> Could this memory corruption overwrite the first few bytes of the
> mitigation_device_list array during decoding?
>
> [ ... ]
>
>> +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 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);
>
> [Severity: Medium]
> If the remote QMI service restarts and advertises a lower maximum mitigation
> level than before, will this send the old uncapped state to the firmware?
>
> Should we clamp the current state to the new maximum state before sending
> the request?
>
> [Severity: High]
> Can a concurrent thermal state update cause a race condition here?
>
> If qmi_tmd_register() runs in the workqueue context and reads the state without
> a lock:
>
> qmi_tmd_svc_arrive()->qmi_tmd_register()
> return qmi_tmd_send_state_request(tmd, tmd->cur_state);
>
> And qmi_tmd_set_cur_state() concurrently updates the state:
>
> qmi_tmd_set_cur_state()
> ret = qmi_tmd_send_state_request(tmd, state);
> if (!ret)
> tmd->cur_state = state;
>
> Could qmi_tmd_register() end up sending a stale state to the firmware, causing
> the remote mitigation state to become permanently desynchronized?
>
>> +
>> + tmd->cdev = thermal_of_cooling_device_register(dev->of_node, index,
>> + label, tmd, &qmi_tmd_cooling_ops);
>> + if (IS_ERR(tmd->cdev)) {
>> + int ret = PTR_ERR(tmd->cdev);
>> +
>> + tmd->cdev = NULL;
>> + return ret;
>> + }
>> +
>> + return 0;
>> +}
>
^ permalink raw reply [flat|nested] 24+ messages in thread* Re: [PATCH v5 2/9] soc: qcom: Add QMI TMD support for remote thermal mitigation
2026-07-22 13:25 ` Gaurav Kohli
@ 2026-07-22 13:33 ` Dmitry Baryshkov
0 siblings, 0 replies; 24+ messages in thread
From: Dmitry Baryshkov @ 2026-07-22 13:33 UTC (permalink / raw)
To: Gaurav Kohli; +Cc: sashiko-reviews, robh, devicetree, conor+dt
On Wed, Jul 22, 2026 at 06:55:23PM +0530, Gaurav Kohli wrote:
>
>
> On 7/21/2026 12:18 PM, sashiko-bot@kernel.org wrote:
>
> > - [Medium] Improper dependencies prevent COMPILE_TEST coverage and force dependencies to become built-in.
>
> The COMPILE_TEST concern is not relevant here. This driver is
> Qualcomm-specific and depends on ARCH_QCOM.
A general recommendation is to make drivers available for COMPILE_TEST.
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v5 3/9] remoteproc: qcom: pas: add support for TMD thermal cooling devices
2026-07-21 6:28 [PATCH v5 0/9] Add support for Qualcomm remoteproc subsystem cooling Gaurav Kohli
2026-07-21 6:28 ` [PATCH v5 1/9] dt-bindings: remoteproc: qcom,pas: add #cooling-cells property Gaurav Kohli
2026-07-21 6:28 ` [PATCH v5 2/9] soc: qcom: Add QMI TMD support for remote thermal mitigation Gaurav Kohli
@ 2026-07-21 6:29 ` Gaurav Kohli
2026-07-21 6:45 ` sashiko-bot
2026-07-21 23:07 ` Dmitry Baryshkov
2026-07-21 6:29 ` [PATCH v5 4/9] remoteproc: qcom_q6v5_pas: enable QMI TMD cooling support Gaurav Kohli
` (5 subsequent siblings)
8 siblings, 2 replies; 24+ messages in thread
From: Gaurav Kohli @ 2026-07-21 6:29 UTC (permalink / raw)
To: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Daniel Lezcano, Amit Kucheria,
Konrad Dybcio, Rafael J. Wysocki, Daniel Lezcano, Zhang Rui,
Lukasz Luba, Manivannan Sadhasivam, 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.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 | 90 +++++++++++++++++++++++++++++++++++++-
2 files changed, 90 insertions(+), 1 deletion(-)
diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
index 65befdbfa5f7..f7c02edf395f 100644
--- a/drivers/remoteproc/Kconfig
+++ b/drivers/remoteproc/Kconfig
@@ -229,6 +229,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
select QCOM_PAS
diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c
index 25599d728208..dc5be2c030cf 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>
@@ -26,8 +27,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/thermal/qcom,qmi-tmd.h>
#include "qcom_common.h"
#include "qcom_pil_info.h"
@@ -38,6 +41,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;
@@ -58,6 +71,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;
@@ -122,6 +139,8 @@ struct qcom_pas {
struct qcom_pas_context *pas_ctx;
struct qcom_pas_context *dtb_pas_ctx;
+
+ struct qmi_tmd_client *tmd_inst;
};
static void qcom_pas_segment_dump(struct rproc *rproc,
@@ -798,6 +817,64 @@ 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;
+
+ 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;
+
+ 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;
+
+ return ret;
+ }
+
+ pas->tmd_inst = tmd_inst;
+
+ return 0;
+}
+
static int qcom_pas_probe(struct platform_device *pdev)
{
const struct qcom_pas_data *desc;
@@ -925,16 +1002,24 @@ static int qcom_pas_probe(struct platform_device *pdev)
if (desc->early_boot)
pas->rproc->state = RPROC_DETACHED;
- 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;
+
node = of_get_compatible_child(pdev->dev.of_node, "qcom,bam-dmux");
pas->bam_dmux = of_platform_device_create(node, NULL, &pdev->dev);
of_node_put(node);
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);
@@ -960,6 +1045,9 @@ static void qcom_pas_remove(struct platform_device *pdev)
if (pas->bam_dmux)
of_platform_device_destroy(&pas->bam_dmux->dev, NULL);
+ 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] 24+ messages in thread* Re: [PATCH v5 3/9] remoteproc: qcom: pas: add support for TMD thermal cooling devices
2026-07-21 6:29 ` [PATCH v5 3/9] remoteproc: qcom: pas: add support for TMD thermal cooling devices Gaurav Kohli
@ 2026-07-21 6:45 ` sashiko-bot
2026-07-21 23:07 ` Dmitry Baryshkov
1 sibling, 0 replies; 24+ messages in thread
From: sashiko-bot @ 2026-07-21 6:45 UTC (permalink / raw)
To: Gaurav Kohli; +Cc: robh, devicetree, conor+dt
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] The Kconfig symbol QCOM_Q6V5_PAS unconditionally selects QCOM_QMI_TMD without inheriting its NET dependency, leading to unmet dependency warnings and potential build failures.
--
--- Patch [3]: [PATCH v5 3/9] remoteproc: qcom: pas: add support for TMD thermal cooling devices ---
commit 55e78a265d3400a946df10d192ba5fdd761cbe31
Author: Gaurav Kohli <gaurav.kohli@oss.qualcomm.com>
remoteproc: qcom: pas: add support for TMD thermal cooling devices
This commit registers Thermal Mitigation Devices (TMDs) for PAS-managed
remote processors to enable thermal throttling through QMI. It updates
Kconfig to select the necessary QMI TMD support and adds the device tree
parsing and initialization logic.
> diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
> index 65befdbfa5f7d..f7c02edf395fe 100644
> --- a/drivers/remoteproc/Kconfig
> +++ b/drivers/remoteproc/Kconfig
> @@ -229,6 +229,7 @@ config QCOM_Q6V5_PAS
> select QCOM_PIL_INFO
> select QCOM_MDT_LOADER
> select QCOM_Q6V5_COMMON
> + select QCOM_QMI_TMD
[Severity: Low]
Does selecting QCOM_QMI_TMD here without inheriting its dependency on NET
cause Kconfig unmet dependency warnings and potential build failures when
CONFIG_NET=n?
[ ... ]
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260721-b4-qmi-tmd-v5-0-99620e07f505@oss.qualcomm.com?part=3
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v5 3/9] remoteproc: qcom: pas: add support for TMD thermal cooling devices
2026-07-21 6:29 ` [PATCH v5 3/9] remoteproc: qcom: pas: add support for TMD thermal cooling devices Gaurav Kohli
2026-07-21 6:45 ` sashiko-bot
@ 2026-07-21 23:07 ` Dmitry Baryshkov
1 sibling, 0 replies; 24+ messages in thread
From: Dmitry Baryshkov @ 2026-07-21 23:07 UTC (permalink / raw)
To: Gaurav Kohli
Cc: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Daniel Lezcano, Amit Kucheria,
Konrad Dybcio, Rafael J. Wysocki, Daniel Lezcano, Zhang Rui,
Lukasz Luba, Manivannan Sadhasivam, Kees Cook,
Gustavo A. R. Silva, cros-qcom-dts-watchers, linux-arm-msm,
linux-remoteproc, devicetree, linux-kernel, linux-pm,
linux-hardening, manaf.pallikunhi
On Tue, Jul 21, 2026 at 11:59:00AM +0530, Gaurav Kohli wrote:
> 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 | 90 +++++++++++++++++++++++++++++++++++++-
> 2 files changed, 90 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
> index 65befdbfa5f7..f7c02edf395f 100644
> --- a/drivers/remoteproc/Kconfig
> +++ b/drivers/remoteproc/Kconfig
> @@ -229,6 +229,7 @@ config QCOM_Q6V5_PAS
> select QCOM_PIL_INFO
> select QCOM_MDT_LOADER
> select QCOM_Q6V5_COMMON
> + select QCOM_QMI_TMD
Sashiko warned here about the missing NET dependencies.
> select QCOM_RPROC_COMMON
> select QCOM_SCM
> select QCOM_PAS
> diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c
> index 25599d728208..dc5be2c030cf 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>
> @@ -26,8 +27,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/thermal/qcom,qmi-tmd.h>
>
> #include "qcom_common.h"
> #include "qcom_pil_info.h"
> @@ -38,6 +41,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;
> @@ -58,6 +71,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;
> @@ -122,6 +139,8 @@ struct qcom_pas {
>
> struct qcom_pas_context *pas_ctx;
> struct qcom_pas_context *dtb_pas_ctx;
> +
> + struct qmi_tmd_client *tmd_inst;
> };
>
> static void qcom_pas_segment_dump(struct rproc *rproc,
> @@ -798,6 +817,64 @@ 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;
> +
> + 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;
> +
> + for (i = 0; i < desc->num_tmd; i++) {
> + tmd = &desc->tmd_name[i];
> +
> + if (tmd->id < 0 || tmd->id >= desc->num_tmd) {
The < 0 check is totally redundant.
For the second check, currently the driver will set num_tmd to
ARRAY_SIZE(desc->tmds), which makes second part either redundant or
invalid. I assume that here you want to compare to some maximum TMD
number to be supported rather than a fixed ARRAY_SIZE().
> + 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);
And this makes it even more strange. Can there be holes in the
tmd_names? Can platform omit some of the TMDs? Assumingly yes, this
is not correct (nor is devm_kcalloc).
> + if (IS_ERR(tmd_inst)) {
> + ret = PTR_ERR(tmd_inst);
> + if (ret == -ENODEV)
> + return 0;
> +
> + return ret;
> + }
> +
> + pas->tmd_inst = tmd_inst;
> +
> + return 0;
> +}
> +
> static int qcom_pas_probe(struct platform_device *pdev)
> {
> const struct qcom_pas_data *desc;
> @@ -925,16 +1002,24 @@ static int qcom_pas_probe(struct platform_device *pdev)
> if (desc->early_boot)
> pas->rproc->state = RPROC_DETACHED;
>
> - 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;
> +
> node = of_get_compatible_child(pdev->dev.of_node, "qcom,bam-dmux");
> pas->bam_dmux = of_platform_device_create(node, NULL, &pdev->dev);
> of_node_put(node);
>
> 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);
> @@ -960,6 +1045,9 @@ static void qcom_pas_remove(struct platform_device *pdev)
> if (pas->bam_dmux)
> of_platform_device_destroy(&pas->bam_dmux->dev, NULL);
>
> + if (pas->tmd_inst)
> + qmi_tmd_exit(pas->tmd_inst);
> +
> rproc_del(pas->rproc);
>
> qcom_q6v5_deinit(&pas->q6v5);
>
> --
> 2.34.1
>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v5 4/9] remoteproc: qcom_q6v5_pas: enable QMI TMD cooling support
2026-07-21 6:28 [PATCH v5 0/9] Add support for Qualcomm remoteproc subsystem cooling Gaurav Kohli
` (2 preceding siblings ...)
2026-07-21 6:29 ` [PATCH v5 3/9] remoteproc: qcom: pas: add support for TMD thermal cooling devices Gaurav Kohli
@ 2026-07-21 6:29 ` Gaurav Kohli
2026-07-21 6:29 ` [PATCH v5 5/9] arm64: dts: qcom: kodiak: Enable CDSP & Modem cooling Gaurav Kohli
` (4 subsequent siblings)
8 siblings, 0 replies; 24+ messages in thread
From: Gaurav Kohli @ 2026-07-21 6:29 UTC (permalink / raw)
To: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Daniel Lezcano, Amit Kucheria,
Konrad Dybcio, Rafael J. Wysocki, Daniel Lezcano, Zhang Rui,
Lukasz Luba, Manivannan Sadhasivam, 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.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.
Reviewed-by: Daniel Lezcano <daniel.lezcano@oss.qualcomm.com>
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 dc5be2c030cf..b7fb4326ada8 100644
--- a/drivers/remoteproc/qcom_q6v5_pas.c
+++ b/drivers/remoteproc/qcom_q6v5_pas.c
@@ -1061,6 +1061,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_TMD_CDSP_SW },
+};
+
+static const struct tmd_name modem_tmd_name[] = {
+ { .name = "pa", .id = QCOM_TMD_PA },
+ { .name = "modem", .id = QCOM_TMD_MODEM },
+};
+
static const struct qcom_pas_data adsp_resource_init = {
.crash_reason_smem = 423,
.firmware_name = "adsp.mdt",
@@ -1218,6 +1227,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 = {
@@ -1236,6 +1248,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 = {
@@ -1263,6 +1278,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 = {
@@ -1278,6 +1296,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 = {
@@ -1362,6 +1383,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 = {
@@ -1430,6 +1454,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] 24+ messages in thread* [PATCH v5 5/9] arm64: dts: qcom: kodiak: Enable CDSP & Modem cooling
2026-07-21 6:28 [PATCH v5 0/9] Add support for Qualcomm remoteproc subsystem cooling Gaurav Kohli
` (3 preceding siblings ...)
2026-07-21 6:29 ` [PATCH v5 4/9] remoteproc: qcom_q6v5_pas: enable QMI TMD cooling support Gaurav Kohli
@ 2026-07-21 6:29 ` Gaurav Kohli
2026-07-21 23:11 ` Dmitry Baryshkov
2026-07-21 6:29 ` [PATCH v5 6/9] arm64: dts: qcom: lemans: Enable CDSP cooling Gaurav Kohli
` (3 subsequent siblings)
8 siblings, 1 reply; 24+ messages in thread
From: Gaurav Kohli @ 2026-07-21 6:29 UTC (permalink / raw)
To: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Daniel Lezcano, Amit Kucheria,
Konrad Dybcio, Rafael J. Wysocki, Daniel Lezcano, Zhang Rui,
Lukasz Luba, Manivannan Sadhasivam, 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.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.
Add polling-delay-passive so the governor periodically evaluates
the zone during passive cooling and steps up cooling levels when
temperature stabilizes below the next trip.
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 | 29 +++++
arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts | 1 +
.../dts/qcom/qcs6490-thundercomm-minipc-g1iot.dts | 29 +++++
.../boot/dts/qcom/qcs6490-thundercomm-rubikpi3.dts | 29 +++++
.../boot/dts/qcom/qcs6490-vicharak-axon-mini.dts | 29 +++++
.../boot/dts/qcom/sc7280-herobrine-lte-sku.dtsi | 29 +++++
.../boot/dts/qcom/sc7280-herobrine-wifi-sku.dtsi | 28 +++++
8 files changed, 304 insertions(+), 4 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/kodiak.dtsi b/arch/arm64/boot/dts/qcom/kodiak.dtsi
index 7e73348fe0d0..df5099023b77 100644
--- a/arch/arm64/boot/dts/qcom/kodiak.dtsi
+++ b/arch/arm64/boot/dts/qcom/kodiak.dtsi
@@ -30,6 +30,7 @@
#include <dt-bindings/sound/qcom,lpass.h>
#include <dt-bindings/sound/qcom,q6afe.h>
#include <dt-bindings/sound/qcom,q6asm.h>
+#include <dt-bindings/thermal/qcom,qmi-tmd.h>
#include <dt-bindings/thermal/thermal.h>
/ {
@@ -3431,6 +3432,8 @@ remoteproc_mpss: remoteproc@4080000 {
qcom,smem-states = <&modem_smp2p_out 0>;
qcom,smem-state-names = "stop";
+ #cooling-cells = <3>;
+
status = "disabled";
glink-edge {
@@ -4803,6 +4806,8 @@ remoteproc_cdsp: remoteproc@a300000 {
qcom,smem-states = <&cdsp_smp2p_out 0>;
qcom,smem-state-names = "stop";
+ #cooling-cells = <3>;
+
status = "disabled";
glink-edge {
@@ -4922,6 +4927,7 @@ compute-cb@14 {
};
};
};
+
};
usb_1: usb@a600000 {
@@ -7732,6 +7738,8 @@ map0 {
};
nspss0-thermal {
+ polling-delay-passive = <200>;
+
thermal-sensors = <&tsens1 3>;
trips {
@@ -7741,15 +7749,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_TMD_CDSP_SW
+ THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
};
nspss1-thermal {
+ polling-delay-passive = <200>;
+
thermal-sensors = <&tsens1 4>;
trips {
@@ -7759,12 +7783,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_TMD_CDSP_SW
+ THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
};
video-thermal {
@@ -7803,7 +7841,9 @@ ddr_crit: ddr-crit {
};
};
- mdmss0-thermal {
+ mdmss0_thermal: mdmss0-thermal {
+ polling-delay-passive = <200>;
+
thermal-sensors = <&tsens1 7>;
trips {
@@ -7813,15 +7853,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_TMD_PA
+ THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+
+ map1 {
+ trip = <&mdmss0_alert1>;
+ cooling-device = <&remoteproc_mpss QCOM_TMD_MODEM
+ THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
};
- mdmss1-thermal {
+ mdmss1_thermal: mdmss1-thermal {
+ polling-delay-passive = <200>;
+
thermal-sensors = <&tsens1 8>;
trips {
@@ -7831,15 +7893,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_TMD_PA
+ THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+
+ map1 {
+ trip = <&mdmss1_alert1>;
+ cooling-device = <&remoteproc_mpss QCOM_TMD_MODEM
+ THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
};
- mdmss2-thermal {
+ mdmss2_thermal: mdmss2-thermal {
+ polling-delay-passive = <200>;
+
thermal-sensors = <&tsens1 9>;
trips {
@@ -7849,15 +7933,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_TMD_PA
+ THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+
+ map1 {
+ trip = <&mdmss2_alert1>;
+ cooling-device = <&remoteproc_mpss QCOM_TMD_MODEM
+ THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
};
- mdmss3-thermal {
+ mdmss3_thermal: mdmss3-thermal {
+ polling-delay-passive = <200>;
+
thermal-sensors = <&tsens1 10>;
trips {
@@ -7867,12 +7973,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_TMD_PA
+ THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+
+ map1 {
+ trip = <&mdmss3_alert1>;
+ cooling-device = <&remoteproc_mpss QCOM_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 82ebd88f9aba..befd3f908ce5 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,35 @@
/delete-node/ &adsp_mem;
/delete-node/ &cdsp_mem;
/delete-node/ &ipa_fw_mem;
+
+&mdmss0_thermal {
+ cooling-maps {
+ /delete-node/ map0;
+ /delete-node/ map1;
+ };
+};
+
+&mdmss1_thermal {
+ cooling-maps {
+ /delete-node/ map0;
+ /delete-node/ map1;
+ };
+};
+
+&mdmss2_thermal {
+ cooling-maps {
+ /delete-node/ map0;
+ /delete-node/ map1;
+ };
+};
+
+&mdmss3_thermal {
+ cooling-maps {
+ /delete-node/ map0;
+ /delete-node/ map1;
+ };
+};
+
/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 e9a932c90d14..48751bc2265d 100644
--- a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts
+++ b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts
@@ -25,6 +25,7 @@
/delete-node/ &rmtfs_mem;
/delete-node/ &adsp_mem;
/delete-node/ &cdsp_mem;
+
/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 c8eed8ba93f5..041a02a03d1c 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,35 @@
/delete-node/ &cdsp_mem;
/delete-node/ &ipa_fw_mem;
/delete-node/ &mpss_mem;
+
+&mdmss0_thermal {
+ cooling-maps {
+ /delete-node/ map0;
+ /delete-node/ map1;
+ };
+};
+
+&mdmss1_thermal {
+ cooling-maps {
+ /delete-node/ map0;
+ /delete-node/ map1;
+ };
+};
+
+&mdmss2_thermal {
+ cooling-maps {
+ /delete-node/ map0;
+ /delete-node/ map1;
+ };
+};
+
+&mdmss3_thermal {
+ cooling-maps {
+ /delete-node/ map0;
+ /delete-node/ map1;
+ };
+};
+
/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 d8a9a7e47bdc..764c9dab046e 100644
--- a/arch/arm64/boot/dts/qcom/qcs6490-thundercomm-rubikpi3.dts
+++ b/arch/arm64/boot/dts/qcom/qcs6490-thundercomm-rubikpi3.dts
@@ -23,6 +23,35 @@
/delete-node/ &adsp_mem;
/delete-node/ &cdsp_mem;
/delete-node/ &ipa_fw_mem;
+
+&mdmss0_thermal {
+ cooling-maps {
+ /delete-node/ map0;
+ /delete-node/ map1;
+ };
+};
+
+&mdmss1_thermal {
+ cooling-maps {
+ /delete-node/ map0;
+ /delete-node/ map1;
+ };
+};
+
+&mdmss2_thermal {
+ cooling-maps {
+ /delete-node/ map0;
+ /delete-node/ map1;
+ };
+};
+
+&mdmss3_thermal {
+ cooling-maps {
+ /delete-node/ map0;
+ /delete-node/ map1;
+ };
+};
+
/delete-node/ &mpss_mem;
/delete-node/ &remoteproc_mpss;
/delete-node/ &remoteproc_wpss;
diff --git a/arch/arm64/boot/dts/qcom/qcs6490-vicharak-axon-mini.dts b/arch/arm64/boot/dts/qcom/qcs6490-vicharak-axon-mini.dts
index 4f2e0109f49b..2a49f07ceed1 100644
--- a/arch/arm64/boot/dts/qcom/qcs6490-vicharak-axon-mini.dts
+++ b/arch/arm64/boot/dts/qcom/qcs6490-vicharak-axon-mini.dts
@@ -25,6 +25,35 @@
/delete-node/ &cdsp_mem;
/delete-node/ &ipa_fw_mem;
/delete-node/ &mpss_mem;
+
+&mdmss0_thermal {
+ cooling-maps {
+ /delete-node/ map0;
+ /delete-node/ map1;
+ };
+};
+
+&mdmss1_thermal {
+ cooling-maps {
+ /delete-node/ map0;
+ /delete-node/ map1;
+ };
+};
+
+&mdmss2_thermal {
+ cooling-maps {
+ /delete-node/ map0;
+ /delete-node/ map1;
+ };
+};
+
+&mdmss3_thermal {
+ cooling-maps {
+ /delete-node/ map0;
+ /delete-node/ map1;
+ };
+};
+
/delete-node/ &remoteproc_mpss;
/delete-node/ &remoteproc_wpss;
/delete-node/ &rmtfs_mem;
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 ac89724ee099..ccb13d2fa5c0 100644
--- a/arch/arm64/boot/dts/qcom/sc7280-herobrine-lte-sku.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7280-herobrine-lte-sku.dtsi
@@ -28,8 +28,37 @@ &ipa {
status = "okay";
};
+&mdmss0_thermal {
+ cooling-maps {
+ /delete-node/ map0;
+ /delete-node/ map1;
+ };
+};
+
+&mdmss1_thermal {
+ cooling-maps {
+ /delete-node/ map0;
+ /delete-node/ map1;
+ };
+};
+
+&mdmss2_thermal {
+ cooling-maps {
+ /delete-node/ map0;
+ /delete-node/ map1;
+ };
+};
+
+&mdmss3_thermal {
+ cooling-maps {
+ /delete-node/ map0;
+ /delete-node/ map1;
+ };
+};
+
&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..87b8ed5d1893 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,34 @@
/* WIFI SKUs save 256M by not having modem/mba/rmtfs memory regions defined. */
+&mdmss0_thermal {
+ cooling-maps {
+ /delete-node/ map0;
+ /delete-node/ map1;
+ };
+};
+
+&mdmss1_thermal {
+ cooling-maps {
+ /delete-node/ map0;
+ /delete-node/ map1;
+ };
+};
+
+&mdmss2_thermal {
+ cooling-maps {
+ /delete-node/ map0;
+ /delete-node/ map1;
+ };
+};
+
+&mdmss3_thermal {
+ cooling-maps {
+ /delete-node/ map0;
+ /delete-node/ map1;
+ };
+};
+
/delete-node/ &mpss_mem;
/delete-node/ &remoteproc_mpss;
/delete-node/ &rmtfs_mem;
--
2.34.1
^ permalink raw reply related [flat|nested] 24+ messages in thread* Re: [PATCH v5 5/9] arm64: dts: qcom: kodiak: Enable CDSP & Modem cooling
2026-07-21 6:29 ` [PATCH v5 5/9] arm64: dts: qcom: kodiak: Enable CDSP & Modem cooling Gaurav Kohli
@ 2026-07-21 23:11 ` Dmitry Baryshkov
2026-07-22 13:32 ` Gaurav Kohli
0 siblings, 1 reply; 24+ messages in thread
From: Dmitry Baryshkov @ 2026-07-21 23:11 UTC (permalink / raw)
To: Gaurav Kohli
Cc: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Daniel Lezcano, Amit Kucheria,
Konrad Dybcio, Rafael J. Wysocki, Daniel Lezcano, Zhang Rui,
Lukasz Luba, Manivannan Sadhasivam, Kees Cook,
Gustavo A. R. Silva, cros-qcom-dts-watchers, linux-arm-msm,
linux-remoteproc, devicetree, linux-kernel, linux-pm,
linux-hardening, manaf.pallikunhi
On Tue, Jul 21, 2026 at 11:59:02AM +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.
>
> Add polling-delay-passive so the governor periodically evaluates
> the zone during passive cooling and steps up cooling levels when
> temperature stabilizes below the next trip.
>
> 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 | 29 +++++
> arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts | 1 +
> .../dts/qcom/qcs6490-thundercomm-minipc-g1iot.dts | 29 +++++
> .../boot/dts/qcom/qcs6490-thundercomm-rubikpi3.dts | 29 +++++
> .../boot/dts/qcom/qcs6490-vicharak-axon-mini.dts | 29 +++++
> .../boot/dts/qcom/sc7280-herobrine-lte-sku.dtsi | 29 +++++
> .../boot/dts/qcom/sc7280-herobrine-wifi-sku.dtsi | 28 +++++
> 8 files changed, 304 insertions(+), 4 deletions(-)
>
> diff --git a/arch/arm64/boot/dts/qcom/kodiak.dtsi b/arch/arm64/boot/dts/qcom/kodiak.dtsi
> index 7e73348fe0d0..df5099023b77 100644
> --- a/arch/arm64/boot/dts/qcom/kodiak.dtsi
> +++ b/arch/arm64/boot/dts/qcom/kodiak.dtsi
> @@ -30,6 +30,7 @@
> #include <dt-bindings/sound/qcom,lpass.h>
> #include <dt-bindings/sound/qcom,q6afe.h>
> #include <dt-bindings/sound/qcom,q6asm.h>
> +#include <dt-bindings/thermal/qcom,qmi-tmd.h>
> #include <dt-bindings/thermal/thermal.h>
>
> / {
> @@ -3431,6 +3432,8 @@ remoteproc_mpss: remoteproc@4080000 {
> qcom,smem-states = <&modem_smp2p_out 0>;
> qcom,smem-state-names = "stop";
>
> + #cooling-cells = <3>;
> +
> status = "disabled";
>
> glink-edge {
> @@ -4803,6 +4806,8 @@ remoteproc_cdsp: remoteproc@a300000 {
> qcom,smem-states = <&cdsp_smp2p_out 0>;
> qcom,smem-state-names = "stop";
>
> + #cooling-cells = <3>;
> +
> status = "disabled";
>
> glink-edge {
> @@ -4922,6 +4927,7 @@ compute-cb@14 {
> };
> };
> };
> +
Extra empty line.
> };
>
> usb_1: usb@a600000 {
> @@ -7732,6 +7738,8 @@ map0 {
> };
>
> nspss0-thermal {
> + polling-delay-passive = <200>;
> +
> thermal-sensors = <&tsens1 3>;
>
> trips {
> @@ -7741,15 +7749,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_TMD_CDSP_SW
> + THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
> + };
> + };
> };
>
> nspss1-thermal {
> + polling-delay-passive = <200>;
> +
> thermal-sensors = <&tsens1 4>;
>
> trips {
> @@ -7759,12 +7783,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_TMD_CDSP_SW
> + THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
> + };
> + };
> };
>
> video-thermal {
> @@ -7803,7 +7841,9 @@ ddr_crit: ddr-crit {
> };
> };
>
> - mdmss0-thermal {
> + mdmss0_thermal: mdmss0-thermal {
> + polling-delay-passive = <200>;
> +
> thermal-sensors = <&tsens1 7>;
>
> trips {
> @@ -7813,15 +7853,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_TMD_PA
> + THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
> + };
> +
> + map1 {
> + trip = <&mdmss0_alert1>;
> + cooling-device = <&remoteproc_mpss QCOM_TMD_MODEM
> + THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
> + };
> + };
> };
>
> - mdmss1-thermal {
> + mdmss1_thermal: mdmss1-thermal {
> + polling-delay-passive = <200>;
> +
> thermal-sensors = <&tsens1 8>;
>
> trips {
> @@ -7831,15 +7893,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_TMD_PA
> + THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
> + };
> +
> + map1 {
> + trip = <&mdmss1_alert1>;
> + cooling-device = <&remoteproc_mpss QCOM_TMD_MODEM
> + THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
> + };
> + };
> };
>
> - mdmss2-thermal {
> + mdmss2_thermal: mdmss2-thermal {
> + polling-delay-passive = <200>;
> +
> thermal-sensors = <&tsens1 9>;
>
> trips {
> @@ -7849,15 +7933,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_TMD_PA
> + THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
> + };
> +
> + map1 {
> + trip = <&mdmss2_alert1>;
> + cooling-device = <&remoteproc_mpss QCOM_TMD_MODEM
> + THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
> + };
> + };
> };
>
> - mdmss3-thermal {
> + mdmss3_thermal: mdmss3-thermal {
> + polling-delay-passive = <200>;
> +
> thermal-sensors = <&tsens1 10>;
>
> trips {
> @@ -7867,12 +7973,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_TMD_PA
> + THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
> + };
> +
> + map1 {
> + trip = <&mdmss3_alert1>;
> + cooling-device = <&remoteproc_mpss QCOM_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 82ebd88f9aba..befd3f908ce5 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,35 @@
> /delete-node/ &adsp_mem;
> /delete-node/ &cdsp_mem;
> /delete-node/ &ipa_fw_mem;
> +
> +&mdmss0_thermal {
> + cooling-maps {
> + /delete-node/ map0;
> + /delete-node/ map1;
> + };
> +};
> +
> +&mdmss1_thermal {
> + cooling-maps {
> + /delete-node/ map0;
> + /delete-node/ map1;
> + };
> +};
> +
> +&mdmss2_thermal {
> + cooling-maps {
> + /delete-node/ map0;
> + /delete-node/ map1;
> + };
> +};
> +
> +&mdmss3_thermal {
> + cooling-maps {
> + /delete-node/ map0;
> + /delete-node/ map1;
> + };
> +};
This is out of place. If you want to remove maps, remove them directly
by label, rather than deleting them through a path under a thermal node.
> +
> /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 e9a932c90d14..48751bc2265d 100644
> --- a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts
> +++ b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts
> @@ -25,6 +25,7 @@
> /delete-node/ &rmtfs_mem;
> /delete-node/ &adsp_mem;
> /delete-node/ &cdsp_mem;
> +
Why?
> /delete-node/ &video_mem;
> /delete-node/ &wlan_ce_mem;
> /delete-node/ &wpss_mem;
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 24+ messages in thread* Re: [PATCH v5 5/9] arm64: dts: qcom: kodiak: Enable CDSP & Modem cooling
2026-07-21 23:11 ` Dmitry Baryshkov
@ 2026-07-22 13:32 ` Gaurav Kohli
0 siblings, 0 replies; 24+ messages in thread
From: Gaurav Kohli @ 2026-07-22 13:32 UTC (permalink / raw)
To: Dmitry Baryshkov
Cc: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Daniel Lezcano, Amit Kucheria,
Konrad Dybcio, Rafael J. Wysocki, Daniel Lezcano, Zhang Rui,
Lukasz Luba, Manivannan Sadhasivam, Kees Cook,
Gustavo A. R. Silva, cros-qcom-dts-watchers, linux-arm-msm,
linux-remoteproc, devicetree, linux-kernel, linux-pm,
linux-hardening, manaf.pallikunhi
On 7/22/2026 4:41 AM, Dmitry Baryshkov wrote:
> On Tue, Jul 21, 2026 at 11:59:02AM +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.
>>
>> Add polling-delay-passive so the governor periodically evaluates
>> the zone during passive cooling and steps up cooling levels when
>> temperature stabilizes below the next trip.
>>
>> 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 | 29 +++++
>> arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts | 1 +
>> .../dts/qcom/qcs6490-thundercomm-minipc-g1iot.dts | 29 +++++
>> .../boot/dts/qcom/qcs6490-thundercomm-rubikpi3.dts | 29 +++++
>> .../boot/dts/qcom/qcs6490-vicharak-axon-mini.dts | 29 +++++
>> .../boot/dts/qcom/sc7280-herobrine-lte-sku.dtsi | 29 +++++
>> .../boot/dts/qcom/sc7280-herobrine-wifi-sku.dtsi | 28 +++++
>> 8 files changed, 304 insertions(+), 4 deletions(-)
>>
>> diff --git a/arch/arm64/boot/dts/qcom/kodiak.dtsi b/arch/arm64/boot/dts/qcom/kodiak.dtsi
>> index 7e73348fe0d0..df5099023b77 100644
>> --- a/arch/arm64/boot/dts/qcom/kodiak.dtsi
>> +++ b/arch/arm64/boot/dts/qcom/kodiak.dtsi
>> @@ -30,6 +30,7 @@
>> #include <dt-bindings/sound/qcom,lpass.h>
>> #include <dt-bindings/sound/qcom,q6afe.h>
>> #include <dt-bindings/sound/qcom,q6asm.h>
>> +#include <dt-bindings/thermal/qcom,qmi-tmd.h>
>> #include <dt-bindings/thermal/thermal.h>
>>
>> / {
>> @@ -3431,6 +3432,8 @@ remoteproc_mpss: remoteproc@4080000 {
>> qcom,smem-states = <&modem_smp2p_out 0>;
>> qcom,smem-state-names = "stop";
>>
>> + #cooling-cells = <3>;
>> +
>> status = "disabled";
>>
>> glink-edge {
>> @@ -4803,6 +4806,8 @@ remoteproc_cdsp: remoteproc@a300000 {
>> qcom,smem-states = <&cdsp_smp2p_out 0>;
>> qcom,smem-state-names = "stop";
>>
>> + #cooling-cells = <3>;
>> +
>> status = "disabled";
>>
>> glink-edge {
>> @@ -4922,6 +4927,7 @@ compute-cb@14 {
>> };
>> };
>> };
>> +
>
> Extra empty line.
thanks for review, will update this.
>
>> };
>>
>> usb_1: usb@a600000 {
>> @@ -7732,6 +7738,8 @@ map0 {
>> };
>>
>> nspss0-thermal {
>> + polling-delay-passive = <200>;
>> +
>> thermal-sensors = <&tsens1 3>;
>>
>> trips {
>> @@ -7741,15 +7749,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_TMD_CDSP_SW
>> + THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
>> + };
>> + };
>> };
>>
>> nspss1-thermal {
>> + polling-delay-passive = <200>;
>> +
>> thermal-sensors = <&tsens1 4>;
>>
>> trips {
>> @@ -7759,12 +7783,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_TMD_CDSP_SW
>> + THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
>> + };
>> + };
>> };
>>
>> video-thermal {
>> @@ -7803,7 +7841,9 @@ ddr_crit: ddr-crit {
>> };
>> };
>>
>> - mdmss0-thermal {
>> + mdmss0_thermal: mdmss0-thermal {
>> + polling-delay-passive = <200>;
>> +
>> thermal-sensors = <&tsens1 7>;
>>
>> trips {
>> @@ -7813,15 +7853,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_TMD_PA
>> + THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
>> + };
>> +
>> + map1 {
>> + trip = <&mdmss0_alert1>;
>> + cooling-device = <&remoteproc_mpss QCOM_TMD_MODEM
>> + THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
>> + };
>> + };
>> };
>>
>> - mdmss1-thermal {
>> + mdmss1_thermal: mdmss1-thermal {
>> + polling-delay-passive = <200>;
>> +
>> thermal-sensors = <&tsens1 8>;
>>
>> trips {
>> @@ -7831,15 +7893,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_TMD_PA
>> + THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
>> + };
>> +
>> + map1 {
>> + trip = <&mdmss1_alert1>;
>> + cooling-device = <&remoteproc_mpss QCOM_TMD_MODEM
>> + THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
>> + };
>> + };
>> };
>>
>> - mdmss2-thermal {
>> + mdmss2_thermal: mdmss2-thermal {
>> + polling-delay-passive = <200>;
>> +
>> thermal-sensors = <&tsens1 9>;
>>
>> trips {
>> @@ -7849,15 +7933,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_TMD_PA
>> + THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
>> + };
>> +
>> + map1 {
>> + trip = <&mdmss2_alert1>;
>> + cooling-device = <&remoteproc_mpss QCOM_TMD_MODEM
>> + THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
>> + };
>> + };
>> };
>>
>> - mdmss3-thermal {
>> + mdmss3_thermal: mdmss3-thermal {
>> + polling-delay-passive = <200>;
>> +
>> thermal-sensors = <&tsens1 10>;
>>
>> trips {
>> @@ -7867,12 +7973,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_TMD_PA
>> + THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
>> + };
>> +
>> + map1 {
>> + trip = <&mdmss3_alert1>;
>> + cooling-device = <&remoteproc_mpss QCOM_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 82ebd88f9aba..befd3f908ce5 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,35 @@
>> /delete-node/ &adsp_mem;
>> /delete-node/ &cdsp_mem;
>> /delete-node/ &ipa_fw_mem;
>> +
>> +&mdmss0_thermal {
>> + cooling-maps {
>> + /delete-node/ map0;
>> + /delete-node/ map1;
>> + };
>> +};
>> +
>> +&mdmss1_thermal {
>> + cooling-maps {
>> + /delete-node/ map0;
>> + /delete-node/ map1;
>> + };
>> +};
>> +
>> +&mdmss2_thermal {
>> + cooling-maps {
>> + /delete-node/ map0;
>> + /delete-node/ map1;
>> + };
>> +};
>> +
>> +&mdmss3_thermal {
>> + cooling-maps {
>> + /delete-node/ map0;
>> + /delete-node/ map1;
>> + };
>> +};
>
> This is out of place. If you want to remove maps, remove them directly
> by label, rather than deleting them through a path under a thermal node.
thanks for this suggestion, will use label.
>
>> +
>> /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 e9a932c90d14..48751bc2265d 100644
>> --- a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts
>> +++ b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts
>> @@ -25,6 +25,7 @@
>> /delete-node/ &rmtfs_mem;
>> /delete-node/ &adsp_mem;
>> /delete-node/ &cdsp_mem;
>> +
>
> Why?
looks like by mistake this got added, will fix this.
>
>> /delete-node/ &video_mem;
>> /delete-node/ &wlan_ce_mem;
>> /delete-node/ &wpss_mem;
>
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v5 6/9] arm64: dts: qcom: lemans: Enable CDSP cooling
2026-07-21 6:28 [PATCH v5 0/9] Add support for Qualcomm remoteproc subsystem cooling Gaurav Kohli
` (4 preceding siblings ...)
2026-07-21 6:29 ` [PATCH v5 5/9] arm64: dts: qcom: kodiak: Enable CDSP & Modem cooling Gaurav Kohli
@ 2026-07-21 6:29 ` Gaurav Kohli
2026-07-21 23:12 ` Dmitry Baryshkov
2026-07-21 6:29 ` [PATCH v5 7/9] arm64: dts: qcom: talos: " Gaurav Kohli
` (2 subsequent siblings)
8 siblings, 1 reply; 24+ messages in thread
From: Gaurav Kohli @ 2026-07-21 6:29 UTC (permalink / raw)
To: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Daniel Lezcano, Amit Kucheria,
Konrad Dybcio, Rafael J. Wysocki, Daniel Lezcano, Zhang Rui,
Lukasz Luba, Manivannan Sadhasivam, 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.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 3b0539e27b51..2f7d4b1e4fdd 100644
--- a/arch/arm64/boot/dts/qcom/lemans.dtsi
+++ b/arch/arm64/boot/dts/qcom/lemans.dtsi
@@ -21,6 +21,7 @@
#include <dt-bindings/power/qcom-rpmpd.h>
#include <dt-bindings/soc/qcom,gpr.h>
#include <dt-bindings/soc/qcom,rpmh-rsc.h>
+#include <dt-bindings/thermal/qcom,qmi-tmd.h>
#include <dt-bindings/thermal/thermal.h>
/ {
@@ -7773,6 +7774,8 @@ remoteproc_cdsp0: remoteproc@26300000 {
qcom,smem-states = <&smp2p_cdsp0_out 0>;
qcom,smem-state-names = "stop";
+ #cooling-cells = <3>;
+
status = "disabled";
glink-edge {
@@ -7912,6 +7915,8 @@ remoteproc_cdsp1: remoteproc@2a300000 {
qcom,smem-states = <&smp2p_cdsp1_out 0>;
qcom,smem-state-names = "stop";
+ #cooling-cells = <3>;
+
status = "disabled";
glink-edge {
@@ -8760,7 +8765,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";
@@ -8772,6 +8777,14 @@ trip-point1 {
type = "passive";
};
};
+
+ cooling-maps {
+ map0 {
+ trip = <&nsp_0_0_0_alert0>;
+ cooling-device = <&remoteproc_cdsp0 QCOM_TMD_CDSP_SW
+ THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
};
nsp-0-1-0-thermal {
@@ -8780,7 +8793,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";
@@ -8792,6 +8805,14 @@ trip-point1 {
type = "passive";
};
};
+
+ cooling-maps {
+ map0 {
+ trip = <&nsp_0_1_0_alert0>;
+ cooling-device = <&remoteproc_cdsp0 QCOM_TMD_CDSP_SW
+ THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
};
nsp-0-2-0-thermal {
@@ -8800,7 +8821,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";
@@ -8812,6 +8833,14 @@ trip-point1 {
type = "passive";
};
};
+
+ cooling-maps {
+ map0 {
+ trip = <&nsp_0_2_0_alert0>;
+ cooling-device = <&remoteproc_cdsp0 QCOM_TMD_CDSP_SW
+ THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
};
nsp-1-0-0-thermal {
@@ -8820,7 +8849,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";
@@ -8832,6 +8861,14 @@ trip-point1 {
type = "passive";
};
};
+
+ cooling-maps {
+ map0 {
+ trip = <&nsp_1_0_0_alert0>;
+ cooling-device = <&remoteproc_cdsp1 QCOM_TMD_CDSP_SW
+ THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
};
nsp-1-1-0-thermal {
@@ -8840,7 +8877,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";
@@ -8852,6 +8889,14 @@ trip-point1 {
type = "passive";
};
};
+
+ cooling-maps {
+ map0 {
+ trip = <&nsp_1_1_0_alert0>;
+ cooling-device = <&remoteproc_cdsp1 QCOM_TMD_CDSP_SW
+ THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
};
nsp-1-2-0-thermal {
@@ -8860,7 +8905,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";
@@ -8872,6 +8917,14 @@ trip-point1 {
type = "passive";
};
};
+
+ cooling-maps {
+ map0 {
+ trip = <&nsp_1_2_0_alert0>;
+ cooling-device = <&remoteproc_cdsp1 QCOM_TMD_CDSP_SW
+ THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
};
ddrss-0-thermal {
@@ -9014,7 +9067,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";
@@ -9026,6 +9079,14 @@ trip-point1 {
type = "passive";
};
};
+
+ cooling-maps {
+ map0 {
+ trip = <&nsp_0_0_1_alert0>;
+ cooling-device = <&remoteproc_cdsp0 QCOM_TMD_CDSP_SW
+ THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
};
nsp-0-1-1-thermal {
@@ -9034,7 +9095,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";
@@ -9046,6 +9107,14 @@ trip-point1 {
type = "passive";
};
};
+
+ cooling-maps {
+ map0 {
+ trip = <&nsp_0_1_1_alert0>;
+ cooling-device = <&remoteproc_cdsp0 QCOM_TMD_CDSP_SW
+ THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
};
nsp-0-2-1-thermal {
@@ -9054,7 +9123,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";
@@ -9066,6 +9135,14 @@ trip-point1 {
type = "passive";
};
};
+
+ cooling-maps {
+ map0 {
+ trip = <&nsp_0_2_1_alert0>;
+ cooling-device = <&remoteproc_cdsp0 QCOM_TMD_CDSP_SW
+ THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
};
nsp-1-0-1-thermal {
@@ -9074,7 +9151,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";
@@ -9086,6 +9163,14 @@ trip-point1 {
type = "passive";
};
};
+
+ cooling-maps {
+ map0 {
+ trip = <&nsp_1_0_1_alert0>;
+ cooling-device = <&remoteproc_cdsp1 QCOM_TMD_CDSP_SW
+ THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
};
nsp-1-1-1-thermal {
@@ -9094,7 +9179,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";
@@ -9106,6 +9191,14 @@ trip-point1 {
type = "passive";
};
};
+
+ cooling-maps {
+ map0 {
+ trip = <&nsp_1_1_1_alert0>;
+ cooling-device = <&remoteproc_cdsp1 QCOM_TMD_CDSP_SW
+ THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
};
nsp-1-2-1-thermal {
@@ -9114,7 +9207,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";
@@ -9126,6 +9219,14 @@ trip-point1 {
type = "passive";
};
};
+
+ cooling-maps {
+ map0 {
+ trip = <&nsp_1_2_1_alert0>;
+ cooling-device = <&remoteproc_cdsp1 QCOM_TMD_CDSP_SW
+ THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
};
ddrss-1-thermal {
--
2.34.1
^ permalink raw reply related [flat|nested] 24+ messages in thread* Re: [PATCH v5 6/9] arm64: dts: qcom: lemans: Enable CDSP cooling
2026-07-21 6:29 ` [PATCH v5 6/9] arm64: dts: qcom: lemans: Enable CDSP cooling Gaurav Kohli
@ 2026-07-21 23:12 ` Dmitry Baryshkov
0 siblings, 0 replies; 24+ messages in thread
From: Dmitry Baryshkov @ 2026-07-21 23:12 UTC (permalink / raw)
To: Gaurav Kohli
Cc: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Daniel Lezcano, Amit Kucheria,
Konrad Dybcio, Rafael J. Wysocki, Daniel Lezcano, Zhang Rui,
Lukasz Luba, Manivannan Sadhasivam, Kees Cook,
Gustavo A. R. Silva, cros-qcom-dts-watchers, linux-arm-msm,
linux-remoteproc, devicetree, linux-kernel, linux-pm,
linux-hardening, manaf.pallikunhi
On Tue, Jul 21, 2026 at 11:59:03AM +0530, Gaurav Kohli wrote:
> 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(-)
>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v5 7/9] arm64: dts: qcom: talos: Enable CDSP cooling
2026-07-21 6:28 [PATCH v5 0/9] Add support for Qualcomm remoteproc subsystem cooling Gaurav Kohli
` (5 preceding siblings ...)
2026-07-21 6:29 ` [PATCH v5 6/9] arm64: dts: qcom: lemans: Enable CDSP cooling Gaurav Kohli
@ 2026-07-21 6:29 ` Gaurav Kohli
2026-07-21 23:12 ` Dmitry Baryshkov
2026-07-21 6:29 ` [PATCH v5 8/9] arm64: dts: qcom: monaco: " Gaurav Kohli
2026-07-21 6:29 ` [PATCH v5 9/9] arm64: dts: qcom: hamoa: " Gaurav Kohli
8 siblings, 1 reply; 24+ messages in thread
From: Gaurav Kohli @ 2026-07-21 6:29 UTC (permalink / raw)
To: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Daniel Lezcano, Amit Kucheria,
Konrad Dybcio, Rafael J. Wysocki, Daniel Lezcano, Zhang Rui,
Lukasz Luba, Manivannan Sadhasivam, 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.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.
Add polling-delay-passive so the governor periodically evaluates
the zone during passive cooling and steps up cooling levels when
temperature stabilizes below the next trip.
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 bdfb70ca9740..5602448f0e42 100644
--- a/arch/arm64/boot/dts/qcom/talos.dtsi
+++ b/arch/arm64/boot/dts/qcom/talos.dtsi
@@ -21,6 +21,7 @@
#include <dt-bindings/power/qcom,rpmhpd.h>
#include <dt-bindings/soc/qcom,gpr.h>
#include <dt-bindings/soc/qcom,rpmh-rsc.h>
+#include <dt-bindings/thermal/qcom,qmi-tmd.h>
#include <dt-bindings/thermal/thermal.h>
/ {
@@ -3840,6 +3841,8 @@ remoteproc_cdsp: remoteproc@8300000 {
qcom,smem-states = <&cdsp_smp2p_out 0>;
qcom,smem-state-names = "stop";
+ #cooling-cells = <3>;
+
status = "disabled";
glink-edge {
@@ -5497,15 +5500,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_TMD_CDSP_SW
+ THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
};
mdm-core-thermal {
--
2.34.1
^ permalink raw reply related [flat|nested] 24+ messages in thread* Re: [PATCH v5 7/9] arm64: dts: qcom: talos: Enable CDSP cooling
2026-07-21 6:29 ` [PATCH v5 7/9] arm64: dts: qcom: talos: " Gaurav Kohli
@ 2026-07-21 23:12 ` Dmitry Baryshkov
0 siblings, 0 replies; 24+ messages in thread
From: Dmitry Baryshkov @ 2026-07-21 23:12 UTC (permalink / raw)
To: Gaurav Kohli
Cc: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Daniel Lezcano, Amit Kucheria,
Konrad Dybcio, Rafael J. Wysocki, Daniel Lezcano, Zhang Rui,
Lukasz Luba, Manivannan Sadhasivam, Kees Cook,
Gustavo A. R. Silva, cros-qcom-dts-watchers, linux-arm-msm,
linux-remoteproc, devicetree, linux-kernel, linux-pm,
linux-hardening, manaf.pallikunhi
On Tue, Jul 21, 2026 at 11:59:04AM +0530, Gaurav Kohli wrote:
> 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.
>
> Add polling-delay-passive so the governor periodically evaluates
> the zone during passive cooling and steps up cooling levels when
> temperature stabilizes below the next trip.
>
> Signed-off-by: Gaurav Kohli <gaurav.kohli@oss.qualcomm.com>
> ---
> arch/arm64/boot/dts/qcom/talos.dtsi | 19 +++++++++++++++++++
> 1 file changed, 19 insertions(+)
>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v5 8/9] arm64: dts: qcom: monaco: Enable CDSP cooling
2026-07-21 6:28 [PATCH v5 0/9] Add support for Qualcomm remoteproc subsystem cooling Gaurav Kohli
` (6 preceding siblings ...)
2026-07-21 6:29 ` [PATCH v5 7/9] arm64: dts: qcom: talos: " Gaurav Kohli
@ 2026-07-21 6:29 ` Gaurav Kohli
2026-07-21 23:12 ` Dmitry Baryshkov
2026-07-21 6:29 ` [PATCH v5 9/9] arm64: dts: qcom: hamoa: " Gaurav Kohli
8 siblings, 1 reply; 24+ messages in thread
From: Gaurav Kohli @ 2026-07-21 6:29 UTC (permalink / raw)
To: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Daniel Lezcano, Amit Kucheria,
Konrad Dybcio, Rafael J. Wysocki, Daniel Lezcano, Zhang Rui,
Lukasz Luba, Manivannan Sadhasivam, 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.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.
Add polling-delay-passive so the governor periodically evaluates
the zone during passive cooling and steps up cooling levels when
temperature stabilizes below the next trip.
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 64fc0d592282..cf30939b4cbb 100644
--- a/arch/arm64/boot/dts/qcom/monaco.dtsi
+++ b/arch/arm64/boot/dts/qcom/monaco.dtsi
@@ -22,6 +22,7 @@
#include <dt-bindings/soc/qcom,gpr.h>
#include <dt-bindings/soc/qcom,rpmh-rsc.h>
#include <dt-bindings/sound/qcom,q6dsp-lpass-ports.h>
+#include <dt-bindings/thermal/qcom,qmi-tmd.h>
#include <dt-bindings/thermal/thermal.h>
/ {
@@ -7738,6 +7739,8 @@ remoteproc_cdsp: remoteproc@26300000 {
qcom,smem-states = <&smp2p_cdsp_out 0>;
qcom,smem-state-names = "stop";
+ #cooling-cells = <3>;
+
status = "disabled";
glink-edge {
@@ -8170,39 +8173,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_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_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_TMD_CDSP_SW
+ THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
};
ddrss-0-thermal {
@@ -8290,39 +8341,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_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_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_TMD_CDSP_SW
+ THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
};
ddrss-1-thermal {
--
2.34.1
^ permalink raw reply related [flat|nested] 24+ messages in thread* Re: [PATCH v5 8/9] arm64: dts: qcom: monaco: Enable CDSP cooling
2026-07-21 6:29 ` [PATCH v5 8/9] arm64: dts: qcom: monaco: " Gaurav Kohli
@ 2026-07-21 23:12 ` Dmitry Baryshkov
0 siblings, 0 replies; 24+ messages in thread
From: Dmitry Baryshkov @ 2026-07-21 23:12 UTC (permalink / raw)
To: Gaurav Kohli
Cc: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Daniel Lezcano, Amit Kucheria,
Konrad Dybcio, Rafael J. Wysocki, Daniel Lezcano, Zhang Rui,
Lukasz Luba, Manivannan Sadhasivam, Kees Cook,
Gustavo A. R. Silva, cros-qcom-dts-watchers, linux-arm-msm,
linux-remoteproc, devicetree, linux-kernel, linux-pm,
linux-hardening, manaf.pallikunhi
On Tue, Jul 21, 2026 at 11:59:05AM +0530, Gaurav Kohli wrote:
> 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.
>
> Add polling-delay-passive so the governor periodically evaluates
> the zone during passive cooling and steps up cooling levels when
> temperature stabilizes below the next trip.
>
> Signed-off-by: Gaurav Kohli <gaurav.kohli@oss.qualcomm.com>
> ---
> arch/arm64/boot/dts/qcom/monaco.dtsi | 99 ++++++++++++++++++++++++++++++++++++
> 1 file changed, 99 insertions(+)
>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v5 9/9] arm64: dts: qcom: hamoa: Enable CDSP cooling
2026-07-21 6:28 [PATCH v5 0/9] Add support for Qualcomm remoteproc subsystem cooling Gaurav Kohli
` (7 preceding siblings ...)
2026-07-21 6:29 ` [PATCH v5 8/9] arm64: dts: qcom: monaco: " Gaurav Kohli
@ 2026-07-21 6:29 ` Gaurav Kohli
2026-07-21 23:13 ` Dmitry Baryshkov
8 siblings, 1 reply; 24+ messages in thread
From: Gaurav Kohli @ 2026-07-21 6:29 UTC (permalink / raw)
To: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Daniel Lezcano, Amit Kucheria,
Konrad Dybcio, Rafael J. Wysocki, Daniel Lezcano, Zhang Rui,
Lukasz Luba, Manivannan Sadhasivam, 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.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.
Add polling-delay-passive so the governor periodically evaluates
the zone during passive cooling and steps up cooling levels when
temperature stabilizes below the next trip.
Signed-off-by: Dipa Ramesh Mantre <dipa.mantre@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts | 32 +++++++++++++++
arch/arm64/boot/dts/qcom/hamoa.dtsi | 63 ++++++++++++++++++++++++++++++
2 files changed, 95 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts b/arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts
index 9fa86bb6438e..a146be1cb5fb 100644
--- a/arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts
+++ b/arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts
@@ -1684,4 +1684,36 @@ trip-point0 {
};
};
};
+
+ nsp0-thermal {
+ trips {
+ trip-point1 {
+ temperature = <105000>;
+ };
+ };
+ };
+
+ nsp1-thermal {
+ trips {
+ trip-point1 {
+ temperature = <105000>;
+ };
+ };
+ };
+
+ nsp2-thermal {
+ trips {
+ trip-point1 {
+ temperature = <105000>;
+ };
+ };
+ };
+
+ nsp3-thermal {
+ trips {
+ trip-point1 {
+ temperature = <105000>;
+ };
+ };
+ };
};
diff --git a/arch/arm64/boot/dts/qcom/hamoa.dtsi b/arch/arm64/boot/dts/qcom/hamoa.dtsi
index 09527dcf9576..a1f7c46f6c27 100644
--- a/arch/arm64/boot/dts/qcom/hamoa.dtsi
+++ b/arch/arm64/boot/dts/qcom/hamoa.dtsi
@@ -23,6 +23,7 @@
#include <dt-bindings/soc/qcom,gpr.h>
#include <dt-bindings/soc/qcom,rpmh-rsc.h>
#include <dt-bindings/sound/qcom,q6dsp-lpass-ports.h>
+#include <dt-bindings/thermal/qcom,qmi-tmd.h>
#include <dt-bindings/thermal/thermal.h>
/ {
@@ -8971,6 +8972,8 @@ remoteproc_cdsp: remoteproc@32300000 {
status = "disabled";
+ #cooling-cells = <3>;
+
glink-edge {
interrupts-extended = <&ipcc IPCC_CLIENT_CDSP
IPCC_MPROC_SIGNAL_GLINK_QMP
@@ -9558,6 +9561,7 @@ aoss0-critical {
};
thermal_nsp0: nsp0-thermal {
+ polling-delay-passive = <200>;
thermal-sensors = <&tsens3 1>;
trips {
@@ -9567,15 +9571,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_TMD_CDSP_SW
+ THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
};
thermal_nsp1: nsp1-thermal {
+ polling-delay-passive = <200>;
thermal-sensors = <&tsens3 2>;
trips {
@@ -9585,15 +9604,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_TMD_CDSP_SW
+ THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
};
thermal_nsp2: nsp2-thermal {
+ polling-delay-passive = <200>;
thermal-sensors = <&tsens3 3>;
trips {
@@ -9603,15 +9637,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_TMD_CDSP_SW
+ THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
};
thermal_nsp3: nsp3-thermal {
+ polling-delay-passive = <200>;
thermal-sensors = <&tsens3 4>;
trips {
@@ -9621,12 +9670,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_TMD_CDSP_SW
+ THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
};
thermal_gpuss_0: gpuss-0-thermal {
--
2.34.1
^ permalink raw reply related [flat|nested] 24+ messages in thread* Re: [PATCH v5 9/9] arm64: dts: qcom: hamoa: Enable CDSP cooling
2026-07-21 6:29 ` [PATCH v5 9/9] arm64: dts: qcom: hamoa: " Gaurav Kohli
@ 2026-07-21 23:13 ` Dmitry Baryshkov
0 siblings, 0 replies; 24+ messages in thread
From: Dmitry Baryshkov @ 2026-07-21 23:13 UTC (permalink / raw)
To: Gaurav Kohli
Cc: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Daniel Lezcano, Amit Kucheria,
Konrad Dybcio, Rafael J. Wysocki, Daniel Lezcano, Zhang Rui,
Lukasz Luba, Manivannan Sadhasivam, Kees Cook,
Gustavo A. R. Silva, cros-qcom-dts-watchers, linux-arm-msm,
linux-remoteproc, devicetree, linux-kernel, linux-pm,
linux-hardening, manaf.pallikunhi, Dipa Ramesh Mantre
On Tue, Jul 21, 2026 at 11:59:06AM +0530, Gaurav Kohli wrote:
> 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.
>
> Add polling-delay-passive so the governor periodically evaluates
> the zone during passive cooling and steps up cooling levels when
> temperature stabilizes below the next trip.
>
> Signed-off-by: Dipa Ramesh Mantre <dipa.mantre@oss.qualcomm.com>
> ---
> arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts | 32 +++++++++++++++
> arch/arm64/boot/dts/qcom/hamoa.dtsi | 63 ++++++++++++++++++++++++++++++
> 2 files changed, 95 insertions(+)
>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 24+ messages in thread