Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'thermal-6.1-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

Pull more thermal control updates from Rafael Wysocki:
"These fix assorted issues in the thermal core and ARM thermal drivers.

Specifics:

- Use platform data to get the sensor ID instead of parsing the
device in imx_sc thermal driver and remove the dedicated OF
function from the core code (Daniel Lezcano).

- Fix Kconfig dependency for the QCom tsens thermal driver (Jonathan
Cameron).

- Add missing const annotation to the RCar ops thermal driver (Lad
Prabhakar).

- Drop duplicate parameter check from
thermal_zone_device_register_with_trips() (Lad Prabhakar).

- Fix NULL pointer dereference in trip_point_temp_store() by making
it check if the ->set_trip_temp() operation is present (Lad
Prabhakar).

- Fix the MSM8939 fourth sensor hardware ID in the QCom tsens thermal
driver (Vincent Knecht)"

* tag 'thermal-6.1-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
thermal/drivers/qcom/tsens-v0_1: Fix MSM8939 fourth sensor hw_id
thermal/core: Add a check before calling set_trip_temp()
thermal/core: Drop valid pointer check for type
thermal/drivers/rcar_thermal: Constify static thermal_zone_device_ops
thermal/drivers/qcom: Drop false build dependency of all QCOM drivers on QCOM_TSENS
thermal/of: Remove the thermal_zone_of_get_sensor_id() function
thermal/drivers/imx_sc: Rely on the platform data to get the resource id

+42 -96
+1 -1
drivers/thermal/Makefile
··· 52 52 obj-y += intel/ 53 53 obj-$(CONFIG_TI_SOC_THERMAL) += ti-soc-thermal/ 54 54 obj-y += st/ 55 - obj-$(CONFIG_QCOM_TSENS) += qcom/ 55 + obj-y += qcom/ 56 56 obj-y += tegra/ 57 57 obj-$(CONFIG_HISI_THERMAL) += hisi_thermal.o 58 58 obj-$(CONFIG_MTK_THERMAL) += mtk_thermal.o
+33 -35
drivers/thermal/imx_sc_thermal.c
··· 76 76 77 77 static int imx_sc_thermal_probe(struct platform_device *pdev) 78 78 { 79 - struct device_node *np, *child, *sensor_np; 80 79 struct imx_sc_sensor *sensor; 81 - int ret; 80 + const int *resource_id; 81 + int i, ret; 82 82 83 83 ret = imx_scu_get_handle(&thermal_ipc_handle); 84 84 if (ret) 85 85 return ret; 86 86 87 - np = of_find_node_by_name(NULL, "thermal-zones"); 88 - if (!np) 89 - return -ENODEV; 87 + resource_id = of_device_get_match_data(&pdev->dev); 88 + if (!resource_id) 89 + return -EINVAL; 90 90 91 - sensor_np = of_node_get(pdev->dev.of_node); 91 + for (i = 0; resource_id[i] > 0; i++) { 92 92 93 - for_each_available_child_of_node(np, child) { 94 93 sensor = devm_kzalloc(&pdev->dev, sizeof(*sensor), GFP_KERNEL); 95 - if (!sensor) { 96 - of_node_put(child); 97 - ret = -ENOMEM; 98 - goto put_node; 99 - } 94 + if (!sensor) 95 + return -ENOMEM; 100 96 101 - ret = thermal_zone_of_get_sensor_id(child, 102 - sensor_np, 103 - &sensor->resource_id); 104 - if (ret < 0) { 105 - dev_err(&pdev->dev, 106 - "failed to get valid sensor resource id: %d\n", 107 - ret); 108 - of_node_put(child); 109 - break; 110 - } 97 + sensor->resource_id = resource_id[i]; 111 98 112 - sensor->tzd = devm_thermal_of_zone_register(&pdev->dev, 113 - sensor->resource_id, 114 - sensor, 115 - &imx_sc_thermal_ops); 99 + sensor->tzd = devm_thermal_of_zone_register(&pdev->dev, sensor->resource_id, 100 + sensor, &imx_sc_thermal_ops); 116 101 if (IS_ERR(sensor->tzd)) { 117 - dev_err(&pdev->dev, "failed to register thermal zone\n"); 102 + /* 103 + * Save the error value before freeing the 104 + * sensor pointer, otherwise we endup with a 105 + * use-after-free error 106 + */ 118 107 ret = PTR_ERR(sensor->tzd); 119 - of_node_put(child); 120 - break; 108 + 109 + devm_kfree(&pdev->dev, sensor); 110 + 111 + /* 112 + * The thermal framework notifies us there is 113 + * no thermal zone description for such a 114 + * sensor id 115 + */ 116 + if (ret == -ENODEV) 117 + continue; 118 + 119 + dev_err(&pdev->dev, "failed to register thermal zone\n"); 120 + return ret; 121 121 } 122 122 123 123 if (devm_thermal_add_hwmon_sysfs(sensor->tzd)) 124 124 dev_warn(&pdev->dev, "failed to add hwmon sysfs attributes\n"); 125 125 } 126 126 127 - put_node: 128 - of_node_put(sensor_np); 129 - of_node_put(np); 130 - 131 - return ret; 127 + return 0; 132 128 } 133 129 134 130 static int imx_sc_thermal_remove(struct platform_device *pdev) ··· 132 136 return 0; 133 137 } 134 138 139 + static int imx_sc_sensors[] = { IMX_SC_R_SYSTEM, IMX_SC_R_PMIC_0, -1 }; 140 + 135 141 static const struct of_device_id imx_sc_thermal_table[] = { 136 - { .compatible = "fsl,imx-sc-thermal", }, 142 + { .compatible = "fsl,imx-sc-thermal", .data = imx_sc_sensors }, 137 143 {} 138 144 }; 139 145 MODULE_DEVICE_TABLE(of, imx_sc_thermal_table);
+1 -1
drivers/thermal/qcom/tsens-v0_1.c
··· 604 604 struct tsens_plat_data data_8939 = { 605 605 .num_sensors = 10, 606 606 .ops = &ops_8939, 607 - .hw_ids = (unsigned int []){ 0, 1, 2, 4, 5, 6, 7, 8, 9, 10 }, 607 + .hw_ids = (unsigned int []){ 0, 1, 2, 3, 5, 6, 7, 8, 9, 10 }, 608 608 609 609 .feat = &tsens_v0_1_feat, 610 610 .fields = tsens_v0_1_regfields,
+1 -1
drivers/thermal/rcar_thermal.c
··· 316 316 return 0; 317 317 } 318 318 319 - static struct thermal_zone_device_ops rcar_thermal_zone_of_ops = { 319 + static const struct thermal_zone_device_ops rcar_thermal_zone_of_ops = { 320 320 .get_temp = rcar_thermal_get_temp, 321 321 }; 322 322
+1 -1
drivers/thermal/thermal_core.c
··· 1186 1186 return ERR_PTR(-EINVAL); 1187 1187 } 1188 1188 1189 - if (type && strlen(type) >= THERMAL_NAME_LENGTH) { 1189 + if (strlen(type) >= THERMAL_NAME_LENGTH) { 1190 1190 pr_err("Thermal zone name (%s) too long, should be under %d chars\n", 1191 1191 type, THERMAL_NAME_LENGTH); 1192 1192 return ERR_PTR(-EINVAL);
-44
drivers/thermal/thermal_of.c
··· 130 130 return -EINVAL; 131 131 } 132 132 133 - /** 134 - * thermal_zone_of_get_sensor_id - get sensor ID from a DT thermal zone 135 - * @tz_np: a valid thermal zone device node. 136 - * @sensor_np: a sensor node of a valid sensor device. 137 - * @id: the sensor ID returned if success. 138 - * 139 - * This function will get sensor ID from a given thermal zone node and 140 - * the sensor node must match the temperature provider @sensor_np. 141 - * 142 - * Return: 0 on success, proper error code otherwise. 143 - */ 144 - 145 - int thermal_zone_of_get_sensor_id(struct device_node *tz_np, 146 - struct device_node *sensor_np, 147 - u32 *id) 148 - { 149 - struct of_phandle_args sensor_specs; 150 - int ret; 151 - 152 - ret = of_parse_phandle_with_args(tz_np, 153 - "thermal-sensors", 154 - "#thermal-sensor-cells", 155 - 0, 156 - &sensor_specs); 157 - if (ret) 158 - return ret; 159 - 160 - if (sensor_specs.np != sensor_np) { 161 - of_node_put(sensor_specs.np); 162 - return -ENODEV; 163 - } 164 - 165 - if (sensor_specs.args_count > 1) 166 - pr_warn("%pOFn: too many cells in sensor specifier %d\n", 167 - sensor_specs.np, sensor_specs.args_count); 168 - 169 - *id = sensor_specs.args_count ? sensor_specs.args[0] : 0; 170 - 171 - of_node_put(sensor_specs.np); 172 - 173 - return 0; 174 - } 175 - EXPORT_SYMBOL_GPL(thermal_zone_of_get_sensor_id); 176 - 177 133 /*** functions parsing device tree nodes ***/ 178 134 179 135 static int of_find_trip_id(struct device_node *np, struct device_node *trip)
+5 -3
drivers/thermal/thermal_sysfs.c
··· 128 128 if (kstrtoint(buf, 10, &temperature)) 129 129 return -EINVAL; 130 130 131 - ret = tz->ops->set_trip_temp(tz, trip, temperature); 132 - if (ret) 133 - return ret; 131 + if (tz->ops->set_trip_temp) { 132 + ret = tz->ops->set_trip_temp(tz, trip, temperature); 133 + if (ret) 134 + return ret; 135 + } 134 136 135 137 if (tz->trips) 136 138 tz->trips[trip].temperature = temperature;
-10
include/linux/thermal.h
··· 308 308 309 309 void thermal_of_zone_unregister(struct thermal_zone_device *tz); 310 310 311 - int thermal_zone_of_get_sensor_id(struct device_node *tz_np, 312 - struct device_node *sensor_np, 313 - u32 *id); 314 311 #else 315 312 static inline 316 313 struct thermal_zone_device *thermal_of_zone_register(struct device_node *sensor, int id, void *data, ··· 330 333 static inline void devm_thermal_of_zone_unregister(struct device *dev, 331 334 struct thermal_zone_device *tz) 332 335 { 333 - } 334 - 335 - static inline int thermal_zone_of_get_sensor_id(struct device_node *tz_np, 336 - struct device_node *sensor_np, 337 - u32 *id) 338 - { 339 - return -ENOENT; 340 336 } 341 337 #endif 342 338