Re: [PATCH v5 3/9] remoteproc: qcom: pas: add support for TMD thermal cooling devices
Dmitry Baryshkov <[email protected]> Wed, 22 Jul 2026 02:07:58 +0300
| Newsgroups | org.kernel.vger.linux-remoteproc,org.kernel.vger.linux-arm-msm,org.kernel.vger.linux-devicetree,org.kernel.vger.linux-hardening,org.kernel.vger.linux-kernel,org.kernel.vger.linux-pm |
|---|---|
| Message-ID | <vxmb3padun4hydx3g7r7gecpeawoslc7djpaaxjl3o5bq5n5ip@nf5djjaelfy3> |
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 <[email protected]> > --- > 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