drivers: thermal: qmi_cooling: Add qmi cooling driver snapshot

This is a snapshot taken of qmi_cooling driver from msm-5.15
commit e40c031f04e1 ("drivers: thermal: qmi_cooling: Add
support for extended device list").

Updates:
    - Change GPL v2 license to GPL
    - Added qmi cooling driver description to kernel config
    - Updated Makefile

Change-Id: Ia4a95cc2a85348d27691c4e52513e996dd1a5990
Signed-off-by: Rashid Zafar <quic_rzafar@quicinc.com>
This commit is contained in:
Rashid Zafar 2022-11-04 15:34:21 -07:00
parent c4de850798
commit c1d32883d2
5 changed files with 1148 additions and 1 deletions

View File

@ -82,6 +82,17 @@ config QTI_POLICY_ENGINE_SENSOR
a sensor. This will enable to provide configuration to mitigate
cooling devices when a recommendation is sent from hardware.
config QTI_QMI_COOLING_DEVICE
tristate "QTI QMI cooling devices"
depends on QCOM_QMI_HELPERS && THERMAL
help
This enables the QTI remote subsystem cooling devices. These cooling
devices will be used by QTI chipset to place various remote
subsystem mitigations like remote processor passive mitigation,
remote subsystem voltage restriction at low temperatures etc.
The QMI cooling device will interface with remote subsystem
using QTI QMI interface.
config QTI_QMI_SENSOR_V2
tristate "QTI QMI TS V2 sensor driver"
depends on THERMAL_OF

View File

@ -1,8 +1,8 @@
# SPDX-License-Identifier: GPL-2.0-only
obj-$(CONFIG_QCOM_TSENS) += qcom_tsens.o
qcom_tsens-y += tsens.o tsens-v2.o tsens-v1.o tsens-v0_1.o \
tsens-8960.o
obj-$(CONFIG_QCOM_SPMI_ADC_TM5) += qcom-spmi-adc-tm5.o
obj-$(CONFIG_QCOM_SPMI_TEMP_ALARM) += qcom-spmi-temp-alarm.o
obj-$(CONFIG_QCOM_LMH) += lmh.o
@ -11,5 +11,8 @@ obj-$(CONFIG_QTI_BCL_PMIC5) += bcl_pmic5.o
obj-$(CONFIG_QTI_BCL_SOC_DRIVER) += bcl_soc.o
obj-$(CONFIG_QTI_POLICY_ENGINE_SENSOR) += policy_engine.o
obj-$(CONFIG_QTI_QMI_COOLING_DEVICE) += qti_qmi_cdev.o
qti_qmi_cdev-y += thermal_mitigation_device_service_v01.o qmi_cooling.o
obj-$(CONFIG_QTI_QMI_SENSOR_V2) += qti_qmi_sensor_v2.o
qti_qmi_sensor_v2-y += thermal_sensor_service_v02.o qmi_sensors_v2.o

View File

@ -0,0 +1,621 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#define pr_fmt(fmt) "%s:%s " fmt, KBUILD_MODNAME, __func__
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/thermal.h>
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/of.h>
#include <linux/soc/qcom/qmi.h>
#include <linux/net.h>
#include "thermal_mitigation_device_service_v01.h"
#define QMI_CDEV_DRIVER "qmi-cooling-device"
#define QMI_TMD_RESP_TOUT msecs_to_jiffies(100)
#define QMI_CLIENT_NAME_LENGTH 40
struct qmi_cooling_device {
struct device_node *np;
char cdev_name[THERMAL_NAME_LENGTH];
char qmi_name[QMI_CLIENT_NAME_LENGTH];
bool connection_active;
struct list_head qmi_node;
struct thermal_cooling_device *cdev;
unsigned int mtgn_state;
unsigned int max_level;
struct qmi_tmd_instance *tmd;
};
struct qmi_tmd_instance {
struct device *dev;
struct qmi_handle handle;
struct mutex mutex;
uint32_t inst_id;
struct list_head tmd_cdev_list;
struct work_struct svc_arrive_work;
};
static struct qmi_tmd_instance *tmd_instances;
static int tmd_inst_cnt;
static char device_clients[][QMI_CLIENT_NAME_LENGTH] = {
{"pa"},
{"pa_fr1"},
{"cx_vdd_limit"},
{"modem"},
{"modem_current"},
{"modem_skin"},
{"modem_bw"},
{"modem_bw_backoff"},
{"vbatt_low"},
{"charge_state"},
{"mmw0"},
{"mmw1"},
{"mmw2"},
{"mmw3"},
{"mmw_skin0"},
{"mmw_skin1"},
{"mmw_skin2"},
{"mmw_skin3"},
{"wlan"},
{"wlan_bw"},
{"mmw_skin0_dsc"},
{"mmw_skin1_dsc"},
{"mmw_skin2_dsc"},
{"mmw_skin3_dsc"},
{"modem_skin_lte_dsc"},
{"modem_skin_nr_dsc"},
{"pa_dsc"},
{"pa_fr1_dsc"},
{"cdsp_sw"},
{"cdsp_hw"},
{"cpuv_restriction_cold"},
{"cpr_cold"},
{"modem_lte_dsc"},
{"modem_nr_dsc"},
{"modem_nr_scg_dsc"},
{"sdr0_lte_dsc"},
{"sdr1_lte_dsc"},
{"sdr0_nr_dsc"},
{"sdr1_nr_dsc"},
{"pa_lte_sdr0_dsc"},
{"pa_lte_sdr1_dsc"},
{"pa_nr_sdr0_dsc"},
{"pa_nr_sdr1_dsc"},
{"pa_nr_sdr0_scg_dsc"},
{"pa_nr_sdr1_scg_dsc"},
{"mmw0_dsc"},
{"mmw1_dsc"},
{"mmw2_dsc"},
{"mmw3_dsc"},
{"mmw_ific_dsc"},
{"modem_lte_sub1_dsc"},
{"modem_nr_sub1_dsc"},
{"modem_nr_scg_sub1_dsc"},
{"sdr0_lte_sub1_dsc"},
{"sdr1_lte_sub1_dsc"},
{"sdr0_nr_sub1_dsc"},
{"sdr1_nr_sub1_dsc"},
{"pa_lte_sdr0_sub1_dsc"},
{"pa_lte_sdr1_sub1_dsc"},
{"pa_nr_sdr0_sub1_dsc"},
{"pa_nr_sdr1_sub1_dsc"},
{"pa_nr_sdr0_scg_sub1_dsc"},
{"pa_nr_sdr1_scg_sub1_dsc"},
{"mmw0_sub1_dsc"},
{"mmw1_sub1_dsc"},
{"mmw2_sub1_dsc"},
{"mmw3_sub1_dsc"},
{"mmw_ific_sub1_dsc"},
};
static int qmi_get_max_state(struct thermal_cooling_device *cdev,
unsigned long *state)
{
struct qmi_cooling_device *qmi_cdev = cdev->devdata;
if (!qmi_cdev)
return -EINVAL;
*state = qmi_cdev->max_level;
return 0;
}
static int qmi_get_cur_state(struct thermal_cooling_device *cdev,
unsigned long *state)
{
struct qmi_cooling_device *qmi_cdev = cdev->devdata;
if (!qmi_cdev)
return -EINVAL;
*state = qmi_cdev->mtgn_state;
return 0;
}
static int qmi_tmd_send_state_request(struct qmi_cooling_device *qmi_cdev,
uint8_t state)
{
int ret = 0;
struct tmd_set_mitigation_level_req_msg_v01 req;
struct tmd_set_mitigation_level_resp_msg_v01 tmd_resp;
struct qmi_tmd_instance *tmd = qmi_cdev->tmd;
struct qmi_txn txn;
memset(&req, 0, sizeof(req));
memset(&tmd_resp, 0, sizeof(tmd_resp));
strscpy(req.mitigation_dev_id.mitigation_dev_id, qmi_cdev->qmi_name,
QMI_TMD_MITIGATION_DEV_ID_LENGTH_MAX_V01);
req.mitigation_level = state;
mutex_lock(&tmd->mutex);
ret = qmi_txn_init(&tmd->handle, &txn,
tmd_set_mitigation_level_resp_msg_v01_ei, &tmd_resp);
if (ret < 0) {
pr_err("qmi set state:%d txn init failed for %s ret:%d\n",
state, qmi_cdev->cdev_name, ret);
goto qmi_send_exit;
}
ret = qmi_send_request(&tmd->handle, NULL, &txn,
QMI_TMD_SET_MITIGATION_LEVEL_REQ_V01,
TMD_SET_MITIGATION_LEVEL_REQ_MSG_V01_MAX_MSG_LEN,
tmd_set_mitigation_level_req_msg_v01_ei, &req);
if (ret < 0) {
pr_err("qmi set state:%d txn send failed for %s ret:%d\n",
state, qmi_cdev->cdev_name, ret);
qmi_txn_cancel(&txn);
goto qmi_send_exit;
}
ret = qmi_txn_wait(&txn, QMI_TMD_RESP_TOUT);
if (ret < 0) {
pr_err("qmi set state:%d txn wait failed for %s ret:%d\n",
state, qmi_cdev->cdev_name, ret);
goto qmi_send_exit;
}
if (tmd_resp.resp.result != QMI_RESULT_SUCCESS_V01) {
ret = tmd_resp.resp.result;
pr_err("qmi set state:%d NOT success for %s ret:%d\n",
state, qmi_cdev->cdev_name, ret);
goto qmi_send_exit;
}
ret = 0;
pr_debug("Requested qmi state:%d for %s\n", state, qmi_cdev->cdev_name);
qmi_send_exit:
mutex_unlock(&tmd->mutex);
return ret;
}
static int qmi_set_cur_state(struct thermal_cooling_device *cdev,
unsigned long state)
{
struct qmi_cooling_device *qmi_cdev = cdev->devdata;
int ret = 0;
if (!qmi_cdev)
return -EINVAL;
if (state > qmi_cdev->max_level)
return -EINVAL;
if (qmi_cdev->mtgn_state == state)
return 0;
/* save it and return if server exit */
if (!qmi_cdev->connection_active) {
qmi_cdev->mtgn_state = state;
pr_debug("Pending request:%ld for %s\n", state,
qmi_cdev->cdev_name);
return 0;
}
/* It is best effort to save state even if QMI fail */
ret = qmi_tmd_send_state_request(qmi_cdev, (uint8_t)state);
qmi_cdev->mtgn_state = state;
return ret;
}
static struct thermal_cooling_device_ops qmi_device_ops = {
.get_max_state = qmi_get_max_state,
.get_cur_state = qmi_get_cur_state,
.set_cur_state = qmi_set_cur_state,
};
static int qmi_register_cooling_device(struct qmi_cooling_device *qmi_cdev)
{
qmi_cdev->cdev = thermal_of_cooling_device_register(
qmi_cdev->np,
qmi_cdev->cdev_name,
qmi_cdev,
&qmi_device_ops);
if (IS_ERR(qmi_cdev->cdev)) {
pr_err("Cooling register failed for %s, ret:%ld\n",
qmi_cdev->cdev_name, PTR_ERR(qmi_cdev->cdev));
return PTR_ERR(qmi_cdev->cdev);
}
pr_debug("Cooling register success for %s\n", qmi_cdev->cdev_name);
return 0;
}
static int verify_devices_and_register(struct qmi_tmd_instance *tmd)
{
struct tmd_get_mitigation_device_list_req_msg_v01 req;
struct tmd_get_mitigation_device_list_resp_msg_v01 *tmd_resp;
int ret = 0, i;
struct qmi_txn txn;
memset(&req, 0, sizeof(req));
/* size of tmd_resp is very high, use heap memory rather than stack */
tmd_resp = kzalloc(sizeof(*tmd_resp), GFP_KERNEL);
if (!tmd_resp)
return -ENOMEM;
mutex_lock(&tmd->mutex);
ret = qmi_txn_init(&tmd->handle, &txn,
tmd_get_mitigation_device_list_resp_msg_v01_ei, tmd_resp);
if (ret < 0) {
pr_err("Transaction Init error for inst_id:0x%x ret:%d\n",
tmd->inst_id, ret);
goto reg_exit;
}
ret = qmi_send_request(&tmd->handle, NULL, &txn,
QMI_TMD_GET_MITIGATION_DEVICE_LIST_REQ_V01,
TMD_GET_MITIGATION_DEVICE_LIST_REQ_MSG_V01_MAX_MSG_LEN,
tmd_get_mitigation_device_list_req_msg_v01_ei,
&req);
if (ret < 0) {
qmi_txn_cancel(&txn);
goto reg_exit;
}
ret = qmi_txn_wait(&txn, QMI_TMD_RESP_TOUT);
if (ret < 0) {
pr_err("Transaction wait error for inst_id:0x%x ret:%d\n",
tmd->inst_id, ret);
goto reg_exit;
}
if (tmd_resp->resp.result != QMI_RESULT_SUCCESS_V01) {
ret = tmd_resp->resp.result;
pr_err("Get device list NOT success for inst_id:0x%x ret:%d\n",
tmd->inst_id, ret);
goto reg_exit;
}
mutex_unlock(&tmd->mutex);
for (i = 0; i < tmd_resp->mitigation_device_list_len; i++) {
struct qmi_cooling_device *qmi_cdev = NULL;
list_for_each_entry(qmi_cdev, &tmd->tmd_cdev_list,
qmi_node) {
struct tmd_mitigation_dev_list_type_v01 *device =
&tmd_resp->mitigation_device_list[i];
if ((strncasecmp(qmi_cdev->qmi_name,
device->mitigation_dev_id.mitigation_dev_id,
QMI_TMD_MITIGATION_DEV_ID_LENGTH_MAX_V01)))
continue;
qmi_cdev->connection_active = true;
qmi_cdev->max_level = device->max_mitigation_level;
/*
* It is better to set current state
* initially or during restart
*/
qmi_tmd_send_state_request(qmi_cdev,
qmi_cdev->mtgn_state);
if (!qmi_cdev->cdev)
ret = qmi_register_cooling_device(qmi_cdev);
break;
}
}
for (i = 0; tmd_resp->mitigation_device_list_ext01_valid &&
i < tmd_resp->mitigation_device_list_ext01_len; i++) {
struct qmi_cooling_device *qmi_cdev = NULL;
list_for_each_entry(qmi_cdev, &tmd->tmd_cdev_list,
qmi_node) {
struct tmd_mitigation_dev_list_type_v01 *device =
&tmd_resp->mitigation_device_list_ext01[i];
if ((strncasecmp(qmi_cdev->qmi_name,
device->mitigation_dev_id.mitigation_dev_id,
QMI_TMD_MITIGATION_DEV_ID_LENGTH_MAX_V01)))
continue;
qmi_cdev->connection_active = true;
qmi_cdev->max_level = device->max_mitigation_level;
/*
* It is better to set current state
* initially or during restart
*/
qmi_tmd_send_state_request(qmi_cdev,
qmi_cdev->mtgn_state);
if (!qmi_cdev->cdev)
ret = qmi_register_cooling_device(qmi_cdev);
break;
}
}
kfree(tmd_resp);
return ret;
reg_exit:
mutex_unlock(&tmd->mutex);
kfree(tmd_resp);
return ret;
}
static void qmi_tmd_svc_arrive(struct work_struct *work)
{
struct qmi_tmd_instance *tmd = container_of(work,
struct qmi_tmd_instance,
svc_arrive_work);
verify_devices_and_register(tmd);
}
static void thermal_qmi_net_reset(struct qmi_handle *qmi)
{
struct qmi_tmd_instance *tmd = container_of(qmi,
struct qmi_tmd_instance,
handle);
struct qmi_cooling_device *qmi_cdev = NULL;
list_for_each_entry(qmi_cdev, &tmd->tmd_cdev_list,
qmi_node) {
if (qmi_cdev->connection_active)
qmi_tmd_send_state_request(qmi_cdev,
qmi_cdev->mtgn_state);
}
}
static void thermal_qmi_del_server(struct qmi_handle *qmi,
struct qmi_service *service)
{
struct qmi_tmd_instance *tmd = container_of(qmi,
struct qmi_tmd_instance,
handle);
struct qmi_cooling_device *qmi_cdev = NULL;
list_for_each_entry(qmi_cdev, &tmd->tmd_cdev_list, qmi_node)
qmi_cdev->connection_active = false;
}
static int thermal_qmi_new_server(struct qmi_handle *qmi,
struct qmi_service *service)
{
struct qmi_tmd_instance *tmd = container_of(qmi,
struct qmi_tmd_instance,
handle);
struct sockaddr_qrtr sq = {AF_QIPCRTR, service->node, service->port};
mutex_lock(&tmd->mutex);
kernel_connect(qmi->sock, (struct sockaddr *)&sq, sizeof(sq), 0);
mutex_unlock(&tmd->mutex);
queue_work(system_highpri_wq, &tmd->svc_arrive_work);
return 0;
}
static struct qmi_ops thermal_qmi_event_ops = {
.new_server = thermal_qmi_new_server,
.del_server = thermal_qmi_del_server,
.net_reset = thermal_qmi_net_reset,
};
static void qmi_tmd_cleanup(void)
{
int idx = 0;
struct qmi_tmd_instance *tmd = tmd_instances;
struct qmi_cooling_device *qmi_cdev, *c_next;
for (; idx < tmd_inst_cnt; idx++) {
mutex_lock(&tmd[idx].mutex);
list_for_each_entry_safe(qmi_cdev, c_next,
&tmd[idx].tmd_cdev_list, qmi_node) {
qmi_cdev->connection_active = false;
if (qmi_cdev->cdev)
thermal_cooling_device_unregister(
qmi_cdev->cdev);
list_del(&qmi_cdev->qmi_node);
}
qmi_handle_release(&tmd[idx].handle);
mutex_unlock(&tmd[idx].mutex);
}
}
static int of_get_qmi_tmd_platform_data(struct device *dev)
{
int ret = 0, idx = 0, i = 0, subsys_cnt = 0;
struct device_node *np = dev->of_node;
struct device_node *subsys_np = NULL, *cdev_np = NULL;
struct qmi_tmd_instance *tmd;
struct qmi_cooling_device *qmi_cdev;
subsys_cnt = of_get_available_child_count(np);
if (!subsys_cnt) {
dev_err(dev, "No child node to process\n");
return -EFAULT;
}
tmd = devm_kcalloc(dev, subsys_cnt, sizeof(*tmd), GFP_KERNEL);
if (!tmd)
return -ENOMEM;
for_each_available_child_of_node(np, subsys_np) {
if (idx >= subsys_cnt) {
of_node_put(subsys_np);
break;
}
ret = of_property_read_u32(subsys_np, "qcom,instance-id",
&tmd[idx].inst_id);
if (ret) {
dev_err(dev, "error reading qcom,insance-id. ret:%d\n",
ret);
goto data_subsys_error;
}
tmd[idx].dev = dev;
mutex_init(&tmd[idx].mutex);
INIT_LIST_HEAD(&tmd[idx].tmd_cdev_list);
INIT_WORK(&tmd[idx].svc_arrive_work, qmi_tmd_svc_arrive);
for_each_available_child_of_node(subsys_np, cdev_np) {
const char *qmi_name;
qmi_cdev = devm_kzalloc(dev, sizeof(*qmi_cdev),
GFP_KERNEL);
if (!qmi_cdev) {
ret = -ENOMEM;
goto data_error;
}
strscpy(qmi_cdev->cdev_name, cdev_np->name,
THERMAL_NAME_LENGTH);
if (!of_property_read_string(cdev_np,
"qcom,qmi-dev-name",
&qmi_name)) {
strscpy(qmi_cdev->qmi_name, qmi_name,
QMI_CLIENT_NAME_LENGTH);
} else {
dev_err(dev, "Fail to parse dev name for %s\n",
cdev_np->name);
break;
}
/* Check for supported qmi dev*/
for (i = 0; i < ARRAY_SIZE(device_clients); i++) {
if (strcmp(device_clients[i],
qmi_cdev->qmi_name) == 0)
break;
}
if (i >= ARRAY_SIZE(device_clients)) {
dev_err(dev, "Not supported dev name for %s\n",
cdev_np->name);
break;
}
qmi_cdev->tmd = &tmd[idx];
qmi_cdev->np = cdev_np;
qmi_cdev->mtgn_state = 0;
list_add(&qmi_cdev->qmi_node, &tmd[idx].tmd_cdev_list);
}
idx++;
}
of_node_put(np);
tmd_instances = tmd;
tmd_inst_cnt = subsys_cnt;
return 0;
data_error:
of_node_put(cdev_np);
data_subsys_error:
of_node_put(subsys_np);
of_node_put(np);
return ret;
}
static int qmi_device_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
int ret = 0, idx = 0;
ret = of_get_qmi_tmd_platform_data(dev);
if (ret)
goto probe_err;
if (!tmd_instances || !tmd_inst_cnt) {
dev_err(dev, "Empty tmd instances\n");
return -EINVAL;
}
for (; idx < tmd_inst_cnt; idx++) {
struct qmi_tmd_instance *tmd = &tmd_instances[idx];
if (list_empty(&tmd->tmd_cdev_list))
continue;
ret = qmi_handle_init(&tmd->handle,
TMD_GET_MITIGATION_DEVICE_LIST_RESP_MSG_V01_MAX_MSG_LEN,
&thermal_qmi_event_ops, NULL);
if (ret < 0) {
dev_err(dev, "QMI[0x%x] handle init failed. err:%d\n",
tmd->inst_id, ret);
tmd_inst_cnt = idx;
goto probe_err;
}
ret = qmi_add_lookup(&tmd->handle, TMD_SERVICE_ID_V01,
TMD_SERVICE_VERS_V01,
tmd->inst_id);
if (ret < 0) {
dev_err(dev, "QMI register failed for 0x%x, ret:%d\n",
tmd->inst_id, ret);
goto probe_err;
}
}
return 0;
probe_err:
qmi_tmd_cleanup();
return ret;
}
static int qmi_device_remove(struct platform_device *pdev)
{
qmi_tmd_cleanup();
return 0;
}
static const struct of_device_id qmi_device_match[] = {
{.compatible = "qcom,qmi-cooling-devices"},
{}
};
static struct platform_driver qmi_device_driver = {
.probe = qmi_device_probe,
.remove = qmi_device_remove,
.driver = {
.name = QMI_CDEV_DRIVER,
.of_match_table = qmi_device_match,
},
};
static int __init qmi_device_init(void)
{
return platform_driver_register(&qmi_device_driver);
}
module_init(qmi_device_init);
static void __exit qmi_device_exit(void)
{
platform_driver_unregister(&qmi_device_driver);
}
module_exit(qmi_device_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("QTI QMI cooling device driver");

View File

@ -0,0 +1,386 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
* Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/soc/qcom/qmi.h>
#include "thermal_mitigation_device_service_v01.h"
static struct qmi_elem_info tmd_mitigation_dev_id_type_v01_ei[] = {
{
.data_type = QMI_STRING,
.elem_len = QMI_TMD_MITIGATION_DEV_ID_LENGTH_MAX_V01 + 1,
.elem_size = sizeof(char),
.array_type = NO_ARRAY,
.tlv_type = 0,
.offset = offsetof(
struct tmd_mitigation_dev_id_type_v01,
mitigation_dev_id),
},
{
.data_type = QMI_EOTI,
.array_type = NO_ARRAY,
.tlv_type = QMI_COMMON_TLV_TYPE,
},
};
static struct qmi_elem_info tmd_mitigation_dev_list_type_v01_ei[] = {
{
.data_type = QMI_STRUCT,
.elem_len = 1,
.elem_size = sizeof(struct tmd_mitigation_dev_id_type_v01),
.array_type = NO_ARRAY,
.tlv_type = 0,
.offset = offsetof(
struct tmd_mitigation_dev_list_type_v01,
mitigation_dev_id),
.ei_array = tmd_mitigation_dev_id_type_v01_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_mitigation_dev_list_type_v01,
max_mitigation_level),
},
{
.data_type = QMI_EOTI,
.array_type = NO_ARRAY,
.tlv_type = QMI_COMMON_TLV_TYPE,
},
};
struct qmi_elem_info tmd_get_mitigation_device_list_req_msg_v01_ei[] = {
{
.data_type = QMI_EOTI,
.array_type = NO_ARRAY,
.tlv_type = QMI_COMMON_TLV_TYPE,
},
};
struct qmi_elem_info tmd_get_mitigation_device_list_resp_msg_v01_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_mitigation_device_list_resp_msg_v01,
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_mitigation_device_list_resp_msg_v01,
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_mitigation_device_list_resp_msg_v01,
mitigation_device_list_len),
},
{
.data_type = QMI_STRUCT,
.elem_len = QMI_TMD_MITIGATION_DEV_LIST_MAX_V01,
.elem_size = sizeof(
struct tmd_mitigation_dev_list_type_v01),
.array_type = VAR_LEN_ARRAY,
.tlv_type = 0x10,
.offset = offsetof(
struct tmd_get_mitigation_device_list_resp_msg_v01,
mitigation_device_list),
.ei_array = tmd_mitigation_dev_list_type_v01_ei,
},
{
.data_type = QMI_OPT_FLAG,
.elem_len = 1,
.elem_size = sizeof(uint8_t),
.array_type = NO_ARRAY,
.tlv_type = 0x11,
.offset = offsetof(
struct tmd_get_mitigation_device_list_resp_msg_v01,
mitigation_device_list_ext01_valid),
},
{
.data_type = QMI_DATA_LEN,
.elem_len = 1,
.elem_size = sizeof(uint8_t),
.array_type = NO_ARRAY,
.tlv_type = 0x11,
.offset = offsetof(
struct tmd_get_mitigation_device_list_resp_msg_v01,
mitigation_device_list_ext01_len),
},
{
.data_type = QMI_STRUCT,
.elem_len = QMI_TMD_MITIGATION_DEV_LIST_EXT01_MAX_V01,
.elem_size = sizeof(
struct tmd_mitigation_dev_list_type_v01),
.array_type = VAR_LEN_ARRAY,
.tlv_type = 0x11,
.offset = offsetof(
struct tmd_get_mitigation_device_list_resp_msg_v01,
mitigation_device_list_ext01),
.ei_array = tmd_mitigation_dev_list_type_v01_ei,
},
{
.data_type = QMI_EOTI,
.array_type = NO_ARRAY,
.tlv_type = QMI_COMMON_TLV_TYPE,
},
};
struct qmi_elem_info tmd_set_mitigation_level_req_msg_v01_ei[] = {
{
.data_type = QMI_STRUCT,
.elem_len = 1,
.elem_size = sizeof(struct tmd_mitigation_dev_id_type_v01),
.array_type = NO_ARRAY,
.tlv_type = 0x01,
.offset = offsetof(
struct tmd_set_mitigation_level_req_msg_v01,
mitigation_dev_id),
.ei_array = tmd_mitigation_dev_id_type_v01_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_mitigation_level_req_msg_v01,
mitigation_level),
},
{
.data_type = QMI_EOTI,
.array_type = NO_ARRAY,
.tlv_type = QMI_COMMON_TLV_TYPE,
},
};
struct qmi_elem_info tmd_set_mitigation_level_resp_msg_v01_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_mitigation_level_resp_msg_v01,
resp),
.ei_array = qmi_response_type_v01_ei,
},
{
.data_type = QMI_EOTI,
.array_type = NO_ARRAY,
.tlv_type = QMI_COMMON_TLV_TYPE,
},
};
struct qmi_elem_info tmd_get_mitigation_level_req_msg_v01_ei[] = {
{
.data_type = QMI_STRUCT,
.elem_len = 1,
.elem_size = sizeof(struct tmd_mitigation_dev_id_type_v01),
.array_type = NO_ARRAY,
.tlv_type = 0x01,
.offset = offsetof(
struct tmd_get_mitigation_level_req_msg_v01,
mitigation_device),
.ei_array = tmd_mitigation_dev_id_type_v01_ei,
},
{
.data_type = QMI_EOTI,
.array_type = NO_ARRAY,
.tlv_type = QMI_COMMON_TLV_TYPE,
},
};
struct qmi_elem_info tmd_get_mitigation_level_resp_msg_v01_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_mitigation_level_resp_msg_v01,
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_mitigation_level_resp_msg_v01,
current_mitigation_level_valid),
},
{
.data_type = QMI_UNSIGNED_1_BYTE,
.elem_len = 1,
.elem_size = sizeof(uint8_t),
.array_type = NO_ARRAY,
.tlv_type = 0x10,
.offset = offsetof(
struct tmd_get_mitigation_level_resp_msg_v01,
current_mitigation_level),
},
{
.data_type = QMI_OPT_FLAG,
.elem_len = 1,
.elem_size = sizeof(uint8_t),
.array_type = NO_ARRAY,
.tlv_type = 0x11,
.offset = offsetof(
struct tmd_get_mitigation_level_resp_msg_v01,
requested_mitigation_level_valid),
},
{
.data_type = QMI_UNSIGNED_1_BYTE,
.elem_len = 1,
.elem_size = sizeof(uint8_t),
.array_type = NO_ARRAY,
.tlv_type = 0x11,
.offset = offsetof(
struct tmd_get_mitigation_level_resp_msg_v01,
requested_mitigation_level),
},
{
.data_type = QMI_EOTI,
.array_type = NO_ARRAY,
.tlv_type = QMI_COMMON_TLV_TYPE,
},
};
struct qmi_elem_info
tmd_register_notification_mitigation_level_req_msg_v01_ei[] = {
{
.data_type = QMI_STRUCT,
.elem_len = 1,
.elem_size = sizeof(struct tmd_mitigation_dev_id_type_v01),
.array_type = NO_ARRAY,
.tlv_type = 0x01,
.offset = offsetof(
struct tmd_register_notification_mitigation_level_req_msg_v01,
mitigation_device),
.ei_array = tmd_mitigation_dev_id_type_v01_ei,
},
{
.data_type = QMI_EOTI,
.array_type = NO_ARRAY,
.tlv_type = QMI_COMMON_TLV_TYPE,
},
};
struct qmi_elem_info
tmd_register_notification_mitigation_level_resp_msg_v01_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_register_notification_mitigation_level_resp_msg_v01,
resp),
.ei_array = qmi_response_type_v01_ei,
},
{
.data_type = QMI_EOTI,
.array_type = NO_ARRAY,
.tlv_type = QMI_COMMON_TLV_TYPE,
},
};
struct qmi_elem_info
tmd_deregister_notification_mitigation_level_req_msg_v01_ei[]
= {
{
.data_type = QMI_STRUCT,
.elem_len = 1,
.elem_size = sizeof(struct tmd_mitigation_dev_id_type_v01),
.array_type = NO_ARRAY,
.tlv_type = 0x01,
.offset = offsetof(struct
tmd_deregister_notification_mitigation_level_req_msg_v01,
mitigation_device),
.ei_array = tmd_mitigation_dev_id_type_v01_ei,
},
{
.data_type = QMI_EOTI,
.array_type = NO_ARRAY,
.tlv_type = QMI_COMMON_TLV_TYPE,
},
};
struct qmi_elem_info
tmd_deregister_notification_mitigation_level_resp_msg_v01_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_deregister_notification_mitigation_level_resp_msg_v01,
resp),
.ei_array = qmi_response_type_v01_ei,
},
{
.data_type = QMI_EOTI,
.array_type = NO_ARRAY,
.tlv_type = QMI_COMMON_TLV_TYPE,
},
};
struct qmi_elem_info tmd_mitigation_level_report_ind_msg_v01_ei[] = {
{
.data_type = QMI_STRUCT,
.elem_len = 1,
.elem_size = sizeof(struct tmd_mitigation_dev_id_type_v01),
.array_type = NO_ARRAY,
.tlv_type = 0x01,
.offset = offsetof(
struct tmd_mitigation_level_report_ind_msg_v01,
mitigation_device),
.ei_array = tmd_mitigation_dev_id_type_v01_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_mitigation_level_report_ind_msg_v01,
current_mitigation_level),
},
{
.data_type = QMI_EOTI,
.array_type = NO_ARRAY,
.tlv_type = QMI_COMMON_TLV_TYPE,
},
};

View File

@ -0,0 +1,126 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
* Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef THERMAL_MITIGATION_DEVICE_SERVICE_V01_H
#define THERMAL_MITIGATION_DEVICE_SERVICE_V01_H
#define TMD_SERVICE_ID_V01 0x18
#define TMD_SERVICE_VERS_V01 0x01
#define QMI_TMD_GET_MITIGATION_DEVICE_LIST_RESP_V01 0x0020
#define QMI_TMD_GET_MITIGATION_LEVEL_REQ_V01 0x0022
#define QMI_TMD_GET_SUPPORTED_MSGS_REQ_V01 0x001E
#define QMI_TMD_SET_MITIGATION_LEVEL_REQ_V01 0x0021
#define QMI_TMD_REGISTER_NOTIFICATION_MITIGATION_LEVEL_RESP_V01 0x0023
#define QMI_TMD_GET_SUPPORTED_MSGS_RESP_V01 0x001E
#define QMI_TMD_SET_MITIGATION_LEVEL_RESP_V01 0x0021
#define QMI_TMD_DEREGISTER_NOTIFICATION_MITIGATION_LEVEL_RESP_V01 0x0024
#define QMI_TMD_MITIGATION_LEVEL_REPORT_IND_V01 0x0025
#define QMI_TMD_GET_MITIGATION_LEVEL_RESP_V01 0x0022
#define QMI_TMD_GET_SUPPORTED_FIELDS_REQ_V01 0x001F
#define QMI_TMD_GET_MITIGATION_DEVICE_LIST_REQ_V01 0x0020
#define QMI_TMD_REGISTER_NOTIFICATION_MITIGATION_LEVEL_REQ_V01 0x0023
#define QMI_TMD_DEREGISTER_NOTIFICATION_MITIGATION_LEVEL_REQ_V01 0x0024
#define QMI_TMD_GET_SUPPORTED_FIELDS_RESP_V01 0x001F
#define QMI_TMD_MITIGATION_DEV_ID_LENGTH_MAX_V01 32
#define QMI_TMD_MITIGATION_DEV_LIST_MAX_V01 32
#define QMI_TMD_MITIGATION_DEV_LIST_EXT01_MAX_V01 64
struct tmd_mitigation_dev_id_type_v01 {
char mitigation_dev_id[QMI_TMD_MITIGATION_DEV_ID_LENGTH_MAX_V01 + 1];
};
struct tmd_mitigation_dev_list_type_v01 {
struct tmd_mitigation_dev_id_type_v01 mitigation_dev_id;
uint8_t max_mitigation_level;
};
struct tmd_get_mitigation_device_list_req_msg_v01 {
char placeholder;
};
#define TMD_GET_MITIGATION_DEVICE_LIST_REQ_MSG_V01_MAX_MSG_LEN 0
extern struct qmi_elem_info tmd_get_mitigation_device_list_req_msg_v01_ei[];
struct tmd_get_mitigation_device_list_resp_msg_v01 {
struct qmi_response_type_v01 resp;
uint8_t mitigation_device_list_valid;
uint32_t mitigation_device_list_len;
struct tmd_mitigation_dev_list_type_v01
mitigation_device_list[QMI_TMD_MITIGATION_DEV_LIST_MAX_V01];
uint8_t mitigation_device_list_ext01_valid;
uint32_t mitigation_device_list_ext01_len;
struct tmd_mitigation_dev_list_type_v01
mitigation_device_list_ext01[QMI_TMD_MITIGATION_DEV_LIST_EXT01_MAX_V01];
};
#define TMD_GET_MITIGATION_DEVICE_LIST_RESP_MSG_V01_MAX_MSG_LEN 3279
extern struct qmi_elem_info tmd_get_mitigation_device_list_resp_msg_v01_ei[];
struct tmd_set_mitigation_level_req_msg_v01 {
struct tmd_mitigation_dev_id_type_v01 mitigation_dev_id;
uint8_t mitigation_level;
};
#define TMD_SET_MITIGATION_LEVEL_REQ_MSG_V01_MAX_MSG_LEN 40
extern struct qmi_elem_info tmd_set_mitigation_level_req_msg_v01_ei[];
struct tmd_set_mitigation_level_resp_msg_v01 {
struct qmi_response_type_v01 resp;
};
#define TMD_SET_MITIGATION_LEVEL_RESP_MSG_V01_MAX_MSG_LEN 7
extern struct qmi_elem_info tmd_set_mitigation_level_resp_msg_v01_ei[];
struct tmd_get_mitigation_level_req_msg_v01 {
struct tmd_mitigation_dev_id_type_v01 mitigation_device;
};
#define TMD_GET_MITIGATION_LEVEL_REQ_MSG_V01_MAX_MSG_LEN 36
extern struct qmi_elem_info tmd_get_mitigation_level_req_msg_v01_ei[];
struct tmd_get_mitigation_level_resp_msg_v01 {
struct qmi_response_type_v01 resp;
uint8_t current_mitigation_level_valid;
uint8_t current_mitigation_level;
uint8_t requested_mitigation_level_valid;
uint8_t requested_mitigation_level;
};
#define TMD_GET_MITIGATION_LEVEL_RESP_MSG_V01_MAX_MSG_LEN 15
extern struct qmi_elem_info tmd_get_mitigation_level_resp_msg_v01_ei[];
struct tmd_register_notification_mitigation_level_req_msg_v01 {
struct tmd_mitigation_dev_id_type_v01 mitigation_device;
};
#define TMD_REGISTER_NOTIFICATION_MITIGATION_LEVEL_REQ_MSG_V01_MAX_MSG_LEN 36
extern struct qmi_elem_info
tmd_register_notification_mitigation_level_req_msg_v01_ei[];
struct tmd_register_notification_mitigation_level_resp_msg_v01 {
struct qmi_response_type_v01 resp;
};
#define TMD_REGISTER_NOTIFICATION_MITIGATION_LEVEL_RESP_MSG_V01_MAX_MSG_LEN 7
extern struct qmi_elem_info
tmd_register_notification_mitigation_level_resp_msg_v01_ei[];
struct tmd_deregister_notification_mitigation_level_req_msg_v01 {
struct tmd_mitigation_dev_id_type_v01 mitigation_device;
};
#define TMD_DEREGISTER_NOTIFICATION_MITIGATION_LEVEL_REQ_MSG_V01_MAX_MSG_LEN 36
extern struct qmi_elem_info
tmd_deregister_notification_mitigation_level_req_msg_v01_ei[];
struct tmd_deregister_notification_mitigation_level_resp_msg_v01 {
struct qmi_response_type_v01 resp;
};
#define TMD_DEREGISTER_NOTIFICATION_MITIGATION_LEVEL_RESP_MSG_V01_MAX_MSG_LEN 7
extern struct qmi_elem_info
tmd_deregister_notification_mitigation_level_resp_msg_v01_ei[];
struct tmd_mitigation_level_report_ind_msg_v01 {
struct tmd_mitigation_dev_id_type_v01 mitigation_device;
uint8_t current_mitigation_level;
};
#define TMD_MITIGATION_LEVEL_REPORT_IND_MSG_V01_MAX_MSG_LEN 40
extern struct qmi_elem_info tmd_mitigation_level_report_ind_msg_v01_ei[];
#endif