Loading Documentation/devicetree/bindings/arm/msm/msm_thermal.txt +93 −0 Original line number Diff line number Diff line Loading @@ -286,3 +286,96 @@ Example: }; }; The sensor information node is an optional node that holds information about thermal sensors on a target. The information includes sensor type, sensor name, sensor alias and sensor scaling factor. The parent node name is qcom,sensor-information. It has a list of optional child nodes, each representing a sensor. The child node is named as qcom,sensor-information@<id>. The id takes values sequentially from 0 to N-1 where N is the number of sensors. This id doesn't relate to zone id or sensor id. The devicetree representation of sensor information node should be: 1.0 Required properties: - compatible: "qcom,sensor-information" 1.1 Optional nodes: qcom,sensor-information@<id> The below properties belong to the child node qcom,sensor-information@<id>. Following are the required and optional properties of a child node. 1.1.a Required properties: - qcom,sensor-type: Type of a sensor. A sensor can be of type tsens, alarm or adc. tsens: Sensors that are on MSM die. alarm: Sensors that are on PMIC die. adc: Sensors that are usually thermistors placed out of the die. - qcom,sensor-name: Name of a sensor as defined by low level sensor driver. 1.1.b Optional properties: - qcom,alias-name: Alias name for a sensor. The alias name corresponds to a device such as cpu/gpu/pop-mem whose temperature is relative to the sensor temperature defined in the child node. - qcom,scaling-factor: The unit that needs to be multiplied to the sensor temperature to get temperature unit in degree centigrade. If this property is not present, a default scaling factor of 1 is assigned to a sensor. Example: qcom,sensor-information { compatible = "qcom,sensor-information"; sensor_information0: qcom,sensor-information@0 { qcom,sensor-type = "tsens"; qcom,sensor-name = "tsens_tz_sensor0"; }; sensor_information1: qcom,sensor-information@1 { qcom,sensor-type = "tsens"; qcom,sensor-name = "tsens_tz_sensor1"; }; sensor_information2: qcom,sensor-information@2 { qcom,sensor-type = "tsens"; qcom,sensor-name = "tsens_tz_sensor2"; }; sensor_information3: qcom,sensor-information@3 { qcom,sensor-type = "tsens"; qcom,sensor-name = "tsens_tz_sensor3"; }; sensor_information4: qcom,sensor-information@4 { qcom,sensor-type = "tsens"; qcom,sensor-name = "tsens_tz_sensor4"; }; sensor_information5: qcom,sensor-information@5 { qcom,sensor-type = "tsens"; qcom,sensor-name = "tsens_tz_sensor5"; }; sensor_information6: qcom,sensor-information@6 { qcom,sensor-type = "tsens"; qcom,sensor-name = "tsens_tz_sensor6"; qcom,alias-name = "cpu7"; } sensor_information7: qcom,sensor-information@7 { qcom,sensor-type = "alarm"; qcom,sensor-name = "pm8994_tz"; qcom,scaling-factor = <1000>; }; }; drivers/thermal/msm_thermal.c +142 −0 Original line number Diff line number Diff line Loading @@ -47,6 +47,7 @@ #define TSENS_NAME_MAX 20 #define TSENS_NAME_FORMAT "tsens_tz_sensor%d" #define THERM_SECURE_BITE_CMD 8 #define SENSOR_SCALING_FACTOR 1 static struct msm_thermal_data msm_thermal_info; static struct delayed_work check_temp_work; Loading @@ -65,6 +66,7 @@ static struct completion thermal_monitor_complete; static int enabled; static int polling_enabled; static int rails_cnt; static int sensor_cnt; static int psm_rails_cnt; static int ocr_rail_cnt; static int limit_idx; Loading @@ -77,6 +79,8 @@ static int freq_table_get; static bool vdd_rstr_enabled; static bool vdd_rstr_nodes_called; static bool vdd_rstr_probed; static bool sensor_info_nodes_called; static bool sensor_info_probed; static bool psm_enabled; static bool psm_nodes_called; static bool psm_probed; Loading Loading @@ -189,6 +193,13 @@ struct rail { struct attribute_group attr_gp; }; struct msm_sensor_info { const char *name; const char *alias; const char *type; uint32_t scaling_factor; }; struct psm_rail { const char *name; uint8_t init; Loading Loading @@ -230,6 +241,7 @@ enum msm_temp_band { static struct psm_rail *psm_rails; static struct psm_rail *ocr_rails; static struct rail *rails; static struct msm_sensor_info *sensors; static struct cpu_info cpus[NR_CPUS]; static struct threshold_info *thresh; static bool mx_restr_applied; Loading Loading @@ -1086,6 +1098,30 @@ static uint32_t msm_thermal_str_to_int(const char *inp) return output; } static ssize_t sensor_info_show( struct kobject *kobj, struct kobj_attribute *attr, char *buf) { int i; ssize_t tot_size = 0, size = 0; for (i = 0; i < sensor_cnt; i++) { size = snprintf(&buf[tot_size], PAGE_SIZE - tot_size, "%s:%s:%s:%d ", sensors[i].type, sensors[i].name, sensors[i].alias ? : "", sensors[i].scaling_factor); if (tot_size + size >= PAGE_SIZE) { pr_err("Not enough buffer size\n"); break; } tot_size += size; } if (tot_size) buf[tot_size - 1] = '\n'; return tot_size; } static struct vdd_rstr_enable vdd_rstr_en = { .ko_attr.attr.name = __stringify(enabled), .ko_attr.attr.mode = 0644, Loading Loading @@ -3579,6 +3615,37 @@ psm_reg_exit: return ret; } static struct kobj_attribute sensor_info_attr = __ATTR_RO(sensor_info); static int msm_thermal_add_sensor_info_nodes(void) { struct kobject *module_kobj = NULL; int ret = 0; if (!sensor_info_probed) { sensor_info_nodes_called = true; return ret; } if (sensor_info_probed && sensor_cnt == 0) return ret; module_kobj = kset_find_obj(module_kset, KBUILD_MODNAME); if (!module_kobj) { pr_err("cannot find kobject\n"); return -ENOENT; } sysfs_attr_init(&sensor_info_attr.attr); ret = sysfs_create_file(module_kobj, &sensor_info_attr.attr); if (ret) { pr_err( "cannot create sensor info kobject attribute. err:%d\n", ret); return ret; } return ret; } static int msm_thermal_add_vdd_rstr_nodes(void) { struct kobject *module_kobj = NULL; Loading Loading @@ -3961,6 +4028,75 @@ read_node_fail: return ret; } static void probe_sensor_info(struct device_node *node, struct msm_thermal_data *data, struct platform_device *pdev) { int err = 0; int i = 0; char *key = NULL; struct device_node *child_node = NULL; struct device_node *np = NULL; np = of_find_compatible_node(NULL, NULL, "qcom,sensor-information"); if (!np) { dev_info(&pdev->dev, "%s:unable to find DT for sensor-information.KTM continues\n", __func__); sensor_info_probed = true; return; } sensor_cnt = of_get_child_count(np); if (sensor_cnt == 0) { err = -ENODEV; goto read_node_fail; } sensors = devm_kzalloc(&pdev->dev, sizeof(struct msm_sensor_info) * sensor_cnt, GFP_KERNEL); if (!sensors) { pr_err("Fail to allocate memory for sensor_info.\n"); err = -ENOMEM; goto read_node_fail; } for_each_child_of_node(np, child_node) { key = "qcom,sensor-type"; err = of_property_read_string(child_node, key, &sensors[i].type); if (err) goto read_node_fail; key = "qcom,sensor-name"; err = of_property_read_string(child_node, key, &sensors[i].name); if (err) goto read_node_fail; key = "qcom,alias-name"; of_property_read_string(child_node, key, &sensors[i].alias); key = "qcom,scaling-factor"; err = of_property_read_u32(child_node, key, &sensors[i].scaling_factor); if (err) { sensors[i].scaling_factor = SENSOR_SCALING_FACTOR; err = 0; } i++; } read_node_fail: sensor_info_probed = true; if (err) { dev_info(&pdev->dev, "%s:Failed reading node=%s, key=%s. err=%d. KTM continues\n", __func__, np->full_name, key, err); devm_kfree(&pdev->dev, sensors); } } static int probe_ocr(struct device_node *node, struct msm_thermal_data *data, struct platform_device *pdev) { Loading Loading @@ -4487,6 +4623,7 @@ static int msm_thermal_dev_probe(struct platform_device *pdev) ret = probe_vdd_rstr(node, &data, pdev); if (ret == -EPROBE_DEFER) goto fail; probe_sensor_info(node, &data, pdev); ret = probe_ocr(node, &data, pdev); update_cpu_topology(&pdev->dev); Loading @@ -4503,6 +4640,10 @@ static int msm_thermal_dev_probe(struct platform_device *pdev) msm_thermal_add_vdd_rstr_nodes(); vdd_rstr_nodes_called = false; } if (sensor_info_nodes_called) { msm_thermal_add_sensor_info_nodes(); sensor_info_nodes_called = false; } if (ocr_nodes_called) { msm_thermal_add_ocr_nodes(); ocr_nodes_called = false; Loading Loading @@ -4588,6 +4729,7 @@ int __init msm_thermal_late_init(void) msm_thermal_add_cc_nodes(); msm_thermal_add_psm_nodes(); msm_thermal_add_vdd_rstr_nodes(); msm_thermal_add_sensor_info_nodes(); if (ocr_reg_init_defer) { if (!ocr_reg_init(msm_thermal_info.pdev)) { ocr_enabled = true; Loading Loading
Documentation/devicetree/bindings/arm/msm/msm_thermal.txt +93 −0 Original line number Diff line number Diff line Loading @@ -286,3 +286,96 @@ Example: }; }; The sensor information node is an optional node that holds information about thermal sensors on a target. The information includes sensor type, sensor name, sensor alias and sensor scaling factor. The parent node name is qcom,sensor-information. It has a list of optional child nodes, each representing a sensor. The child node is named as qcom,sensor-information@<id>. The id takes values sequentially from 0 to N-1 where N is the number of sensors. This id doesn't relate to zone id or sensor id. The devicetree representation of sensor information node should be: 1.0 Required properties: - compatible: "qcom,sensor-information" 1.1 Optional nodes: qcom,sensor-information@<id> The below properties belong to the child node qcom,sensor-information@<id>. Following are the required and optional properties of a child node. 1.1.a Required properties: - qcom,sensor-type: Type of a sensor. A sensor can be of type tsens, alarm or adc. tsens: Sensors that are on MSM die. alarm: Sensors that are on PMIC die. adc: Sensors that are usually thermistors placed out of the die. - qcom,sensor-name: Name of a sensor as defined by low level sensor driver. 1.1.b Optional properties: - qcom,alias-name: Alias name for a sensor. The alias name corresponds to a device such as cpu/gpu/pop-mem whose temperature is relative to the sensor temperature defined in the child node. - qcom,scaling-factor: The unit that needs to be multiplied to the sensor temperature to get temperature unit in degree centigrade. If this property is not present, a default scaling factor of 1 is assigned to a sensor. Example: qcom,sensor-information { compatible = "qcom,sensor-information"; sensor_information0: qcom,sensor-information@0 { qcom,sensor-type = "tsens"; qcom,sensor-name = "tsens_tz_sensor0"; }; sensor_information1: qcom,sensor-information@1 { qcom,sensor-type = "tsens"; qcom,sensor-name = "tsens_tz_sensor1"; }; sensor_information2: qcom,sensor-information@2 { qcom,sensor-type = "tsens"; qcom,sensor-name = "tsens_tz_sensor2"; }; sensor_information3: qcom,sensor-information@3 { qcom,sensor-type = "tsens"; qcom,sensor-name = "tsens_tz_sensor3"; }; sensor_information4: qcom,sensor-information@4 { qcom,sensor-type = "tsens"; qcom,sensor-name = "tsens_tz_sensor4"; }; sensor_information5: qcom,sensor-information@5 { qcom,sensor-type = "tsens"; qcom,sensor-name = "tsens_tz_sensor5"; }; sensor_information6: qcom,sensor-information@6 { qcom,sensor-type = "tsens"; qcom,sensor-name = "tsens_tz_sensor6"; qcom,alias-name = "cpu7"; } sensor_information7: qcom,sensor-information@7 { qcom,sensor-type = "alarm"; qcom,sensor-name = "pm8994_tz"; qcom,scaling-factor = <1000>; }; };
drivers/thermal/msm_thermal.c +142 −0 Original line number Diff line number Diff line Loading @@ -47,6 +47,7 @@ #define TSENS_NAME_MAX 20 #define TSENS_NAME_FORMAT "tsens_tz_sensor%d" #define THERM_SECURE_BITE_CMD 8 #define SENSOR_SCALING_FACTOR 1 static struct msm_thermal_data msm_thermal_info; static struct delayed_work check_temp_work; Loading @@ -65,6 +66,7 @@ static struct completion thermal_monitor_complete; static int enabled; static int polling_enabled; static int rails_cnt; static int sensor_cnt; static int psm_rails_cnt; static int ocr_rail_cnt; static int limit_idx; Loading @@ -77,6 +79,8 @@ static int freq_table_get; static bool vdd_rstr_enabled; static bool vdd_rstr_nodes_called; static bool vdd_rstr_probed; static bool sensor_info_nodes_called; static bool sensor_info_probed; static bool psm_enabled; static bool psm_nodes_called; static bool psm_probed; Loading Loading @@ -189,6 +193,13 @@ struct rail { struct attribute_group attr_gp; }; struct msm_sensor_info { const char *name; const char *alias; const char *type; uint32_t scaling_factor; }; struct psm_rail { const char *name; uint8_t init; Loading Loading @@ -230,6 +241,7 @@ enum msm_temp_band { static struct psm_rail *psm_rails; static struct psm_rail *ocr_rails; static struct rail *rails; static struct msm_sensor_info *sensors; static struct cpu_info cpus[NR_CPUS]; static struct threshold_info *thresh; static bool mx_restr_applied; Loading Loading @@ -1086,6 +1098,30 @@ static uint32_t msm_thermal_str_to_int(const char *inp) return output; } static ssize_t sensor_info_show( struct kobject *kobj, struct kobj_attribute *attr, char *buf) { int i; ssize_t tot_size = 0, size = 0; for (i = 0; i < sensor_cnt; i++) { size = snprintf(&buf[tot_size], PAGE_SIZE - tot_size, "%s:%s:%s:%d ", sensors[i].type, sensors[i].name, sensors[i].alias ? : "", sensors[i].scaling_factor); if (tot_size + size >= PAGE_SIZE) { pr_err("Not enough buffer size\n"); break; } tot_size += size; } if (tot_size) buf[tot_size - 1] = '\n'; return tot_size; } static struct vdd_rstr_enable vdd_rstr_en = { .ko_attr.attr.name = __stringify(enabled), .ko_attr.attr.mode = 0644, Loading Loading @@ -3579,6 +3615,37 @@ psm_reg_exit: return ret; } static struct kobj_attribute sensor_info_attr = __ATTR_RO(sensor_info); static int msm_thermal_add_sensor_info_nodes(void) { struct kobject *module_kobj = NULL; int ret = 0; if (!sensor_info_probed) { sensor_info_nodes_called = true; return ret; } if (sensor_info_probed && sensor_cnt == 0) return ret; module_kobj = kset_find_obj(module_kset, KBUILD_MODNAME); if (!module_kobj) { pr_err("cannot find kobject\n"); return -ENOENT; } sysfs_attr_init(&sensor_info_attr.attr); ret = sysfs_create_file(module_kobj, &sensor_info_attr.attr); if (ret) { pr_err( "cannot create sensor info kobject attribute. err:%d\n", ret); return ret; } return ret; } static int msm_thermal_add_vdd_rstr_nodes(void) { struct kobject *module_kobj = NULL; Loading Loading @@ -3961,6 +4028,75 @@ read_node_fail: return ret; } static void probe_sensor_info(struct device_node *node, struct msm_thermal_data *data, struct platform_device *pdev) { int err = 0; int i = 0; char *key = NULL; struct device_node *child_node = NULL; struct device_node *np = NULL; np = of_find_compatible_node(NULL, NULL, "qcom,sensor-information"); if (!np) { dev_info(&pdev->dev, "%s:unable to find DT for sensor-information.KTM continues\n", __func__); sensor_info_probed = true; return; } sensor_cnt = of_get_child_count(np); if (sensor_cnt == 0) { err = -ENODEV; goto read_node_fail; } sensors = devm_kzalloc(&pdev->dev, sizeof(struct msm_sensor_info) * sensor_cnt, GFP_KERNEL); if (!sensors) { pr_err("Fail to allocate memory for sensor_info.\n"); err = -ENOMEM; goto read_node_fail; } for_each_child_of_node(np, child_node) { key = "qcom,sensor-type"; err = of_property_read_string(child_node, key, &sensors[i].type); if (err) goto read_node_fail; key = "qcom,sensor-name"; err = of_property_read_string(child_node, key, &sensors[i].name); if (err) goto read_node_fail; key = "qcom,alias-name"; of_property_read_string(child_node, key, &sensors[i].alias); key = "qcom,scaling-factor"; err = of_property_read_u32(child_node, key, &sensors[i].scaling_factor); if (err) { sensors[i].scaling_factor = SENSOR_SCALING_FACTOR; err = 0; } i++; } read_node_fail: sensor_info_probed = true; if (err) { dev_info(&pdev->dev, "%s:Failed reading node=%s, key=%s. err=%d. KTM continues\n", __func__, np->full_name, key, err); devm_kfree(&pdev->dev, sensors); } } static int probe_ocr(struct device_node *node, struct msm_thermal_data *data, struct platform_device *pdev) { Loading Loading @@ -4487,6 +4623,7 @@ static int msm_thermal_dev_probe(struct platform_device *pdev) ret = probe_vdd_rstr(node, &data, pdev); if (ret == -EPROBE_DEFER) goto fail; probe_sensor_info(node, &data, pdev); ret = probe_ocr(node, &data, pdev); update_cpu_topology(&pdev->dev); Loading @@ -4503,6 +4640,10 @@ static int msm_thermal_dev_probe(struct platform_device *pdev) msm_thermal_add_vdd_rstr_nodes(); vdd_rstr_nodes_called = false; } if (sensor_info_nodes_called) { msm_thermal_add_sensor_info_nodes(); sensor_info_nodes_called = false; } if (ocr_nodes_called) { msm_thermal_add_ocr_nodes(); ocr_nodes_called = false; Loading Loading @@ -4588,6 +4729,7 @@ int __init msm_thermal_late_init(void) msm_thermal_add_cc_nodes(); msm_thermal_add_psm_nodes(); msm_thermal_add_vdd_rstr_nodes(); msm_thermal_add_sensor_info_nodes(); if (ocr_reg_init_defer) { if (!ocr_reg_init(msm_thermal_info.pdev)) { ocr_enabled = true; Loading