Lines Matching +full:cooling +full:- +full:maps
1 // SPDX-License-Identifier: GPL-2.0
3 * of-thermal.c - Generic Thermal Management device tree support.
25 * struct __thermal_cooling_bind_param - a cooling device for a trip point
26 * @cooling_device: a pointer to identify the referred cooling device
27 * @min: minimum cooling state used at this trip point
28 * @max: maximum cooling state used at this trip point
38 * struct __thermal_bind_param - a match between trip and cooling device
39 * @tcbp: a pointer to an array of cooling devices
42 * @usage: the percentage (from 0 to 100) of cooling contribution
53 * struct __thermal_zone - internal representation of a thermal zone
54 * @passive_delay: polling interval while passive cooling is activated
59 * @trips: an array of trip points (0..ntrips - 1)
61 * @tbps: an array of thermal bind params (0..num_tbps - 1)
76 /* cooling binding data */
90 struct __thermal_zone *data = tz->devdata; in of_thermal_get_temp()
92 if (!data->ops || !data->ops->get_temp) in of_thermal_get_temp()
93 return -EINVAL; in of_thermal_get_temp()
95 return data->ops->get_temp(data->sensor_data, temp); in of_thermal_get_temp()
101 struct __thermal_zone *data = tz->devdata; in of_thermal_set_trips()
103 if (!data->ops || !data->ops->set_trips) in of_thermal_set_trips()
104 return -EINVAL; in of_thermal_set_trips()
106 return data->ops->set_trips(data->sensor_data, low, high); in of_thermal_set_trips()
110 * of_thermal_get_ntrips - function to export number of available trip
117 * Return: number of available trip points, -ENODEV when data not available
121 struct __thermal_zone *data = tz->devdata; in of_thermal_get_ntrips()
124 return -ENODEV; in of_thermal_get_ntrips()
126 return data->ntrips; in of_thermal_get_ntrips()
131 * of_thermal_is_trip_valid - function to check if trip point is valid
142 struct __thermal_zone *data = tz->devdata; in of_thermal_is_trip_valid()
144 if (!data || trip >= data->ntrips || trip < 0) in of_thermal_is_trip_valid()
152 * of_thermal_get_trip_points - function to get access to a globally exported
164 struct __thermal_zone *data = tz->devdata; in of_thermal_get_trip_points()
169 return data->trips; in of_thermal_get_trip_points()
174 * of_thermal_set_emul_temp - function to set emulated temperature
187 struct __thermal_zone *data = tz->devdata; in of_thermal_set_emul_temp()
189 if (!data->ops || !data->ops->set_emul_temp) in of_thermal_set_emul_temp()
190 return -EINVAL; in of_thermal_set_emul_temp()
192 return data->ops->set_emul_temp(data->sensor_data, temp); in of_thermal_set_emul_temp()
198 struct __thermal_zone *data = tz->devdata; in of_thermal_get_trend()
200 if (!data->ops || !data->ops->get_trend) in of_thermal_get_trend()
201 return -EINVAL; in of_thermal_get_trend()
203 return data->ops->get_trend(data->sensor_data, trip, trend); in of_thermal_get_trend()
209 struct __thermal_zone *data = thermal->devdata; in of_thermal_bind()
215 return -ENODEV; in of_thermal_bind()
218 for (i = 0; i < data->num_tbps; i++) { in of_thermal_bind()
219 tbp = data->tbps + i; in of_thermal_bind()
221 for (j = 0; j < tbp->count; j++) { in of_thermal_bind()
222 tcbp = tbp->tcbp + j; in of_thermal_bind()
224 if (tcbp->cooling_device == cdev->np) { in of_thermal_bind()
228 tbp->trip_id, cdev, in of_thermal_bind()
229 tcbp->max, in of_thermal_bind()
230 tcbp->min, in of_thermal_bind()
231 tbp->usage); in of_thermal_bind()
244 struct __thermal_zone *data = thermal->devdata; in of_thermal_unbind()
250 return -ENODEV; in of_thermal_unbind()
253 for (i = 0; i < data->num_tbps; i++) { in of_thermal_unbind()
254 tbp = data->tbps + i; in of_thermal_unbind()
256 for (j = 0; j < tbp->count; j++) { in of_thermal_unbind()
257 tcbp = tbp->tcbp + j; in of_thermal_unbind()
259 if (tcbp->cooling_device == cdev->np) { in of_thermal_unbind()
263 tbp->trip_id, cdev); in of_thermal_unbind()
276 struct __thermal_zone *data = tz->devdata; in of_thermal_get_trip_type()
278 if (trip >= data->ntrips || trip < 0) in of_thermal_get_trip_type()
279 return -EDOM; in of_thermal_get_trip_type()
281 *type = data->trips[trip].type; in of_thermal_get_trip_type()
289 struct __thermal_zone *data = tz->devdata; in of_thermal_get_trip_temp()
291 if (trip >= data->ntrips || trip < 0) in of_thermal_get_trip_temp()
292 return -EDOM; in of_thermal_get_trip_temp()
294 *temp = data->trips[trip].temperature; in of_thermal_get_trip_temp()
302 struct __thermal_zone *data = tz->devdata; in of_thermal_set_trip_temp()
304 if (trip >= data->ntrips || trip < 0) in of_thermal_set_trip_temp()
305 return -EDOM; in of_thermal_set_trip_temp()
307 if (data->ops && data->ops->set_trip_temp) { in of_thermal_set_trip_temp()
310 ret = data->ops->set_trip_temp(data->sensor_data, trip, temp); in of_thermal_set_trip_temp()
315 /* thermal framework should take care of data->mask & (1 << trip) */ in of_thermal_set_trip_temp()
316 data->trips[trip].temperature = temp; in of_thermal_set_trip_temp()
324 struct __thermal_zone *data = tz->devdata; in of_thermal_get_trip_hyst()
326 if (trip >= data->ntrips || trip < 0) in of_thermal_get_trip_hyst()
327 return -EDOM; in of_thermal_get_trip_hyst()
329 *hyst = data->trips[trip].hysteresis; in of_thermal_get_trip_hyst()
337 struct __thermal_zone *data = tz->devdata; in of_thermal_set_trip_hyst()
339 if (trip >= data->ntrips || trip < 0) in of_thermal_set_trip_hyst()
340 return -EDOM; in of_thermal_set_trip_hyst()
342 /* thermal framework should take care of data->mask & (1 << trip) */ in of_thermal_set_trip_hyst()
343 data->trips[trip].hysteresis = hyst; in of_thermal_set_trip_hyst()
351 struct __thermal_zone *data = tz->devdata; in of_thermal_get_crit_temp()
354 for (i = 0; i < data->ntrips; i++) in of_thermal_get_crit_temp()
355 if (data->trips[i].type == THERMAL_TRIP_CRITICAL) { in of_thermal_get_crit_temp()
356 *temp = data->trips[i].temperature; in of_thermal_get_crit_temp()
360 return -EINVAL; in of_thermal_get_crit_temp()
385 tzd = thermal_zone_get_zone_by_name(zone->name); in thermal_zone_of_add_sensor()
387 return ERR_PTR(-EPROBE_DEFER); in thermal_zone_of_add_sensor()
389 tz = tzd->devdata; in thermal_zone_of_add_sensor()
392 return ERR_PTR(-EINVAL); in thermal_zone_of_add_sensor()
394 mutex_lock(&tzd->lock); in thermal_zone_of_add_sensor()
395 tz->ops = ops; in thermal_zone_of_add_sensor()
396 tz->sensor_data = data; in thermal_zone_of_add_sensor()
398 tzd->ops->get_temp = of_thermal_get_temp; in thermal_zone_of_add_sensor()
399 tzd->ops->get_trend = of_thermal_get_trend; in thermal_zone_of_add_sensor()
405 if (ops->set_trips) in thermal_zone_of_add_sensor()
406 tzd->ops->set_trips = of_thermal_set_trips; in thermal_zone_of_add_sensor()
408 if (ops->set_emul_temp) in thermal_zone_of_add_sensor()
409 tzd->ops->set_emul_temp = of_thermal_set_emul_temp; in thermal_zone_of_add_sensor()
411 mutex_unlock(&tzd->lock); in thermal_zone_of_add_sensor()
417 * thermal_zone_of_get_sensor_id - get sensor ID from a DT thermal zone
436 "thermal-sensors", in thermal_zone_of_get_sensor_id()
437 "#thermal-sensor-cells", in thermal_zone_of_get_sensor_id()
445 return -ENODEV; in thermal_zone_of_get_sensor_id()
461 * thermal_zone_of_sensor_register - registers a sensor to a DT thermal zone
472 * @dev->of_node as temperature providers. For the zone pointing to the
482 * 01 - This function must enqueue the new sensor instead of using
485 * 02 - There must be a way to match the sensor with all thermal zones
497 struct thermal_zone_device *tzd = ERR_PTR(-ENODEV); in thermal_zone_of_sensor_register()
499 np = of_find_node_by_name(NULL, "thermal-zones"); in thermal_zone_of_sensor_register()
501 return ERR_PTR(-ENODEV); in thermal_zone_of_sensor_register()
503 if (!dev || !dev->of_node) { in thermal_zone_of_sensor_register()
505 return ERR_PTR(-ENODEV); in thermal_zone_of_sensor_register()
508 sensor_np = of_node_get(dev->of_node); in thermal_zone_of_sensor_register()
537 * thermal_zone_of_sensor_unregister - unregisters a sensor from a DT thermal zone
556 if (!dev || !tzd || !tzd->devdata) in thermal_zone_of_sensor_unregister()
559 tz = tzd->devdata; in thermal_zone_of_sensor_unregister()
568 mutex_lock(&tzd->lock); in thermal_zone_of_sensor_unregister()
569 tzd->ops->get_temp = NULL; in thermal_zone_of_sensor_unregister()
570 tzd->ops->get_trend = NULL; in thermal_zone_of_sensor_unregister()
571 tzd->ops->set_emul_temp = NULL; in thermal_zone_of_sensor_unregister()
573 tz->ops = NULL; in thermal_zone_of_sensor_unregister()
574 tz->sensor_data = NULL; in thermal_zone_of_sensor_unregister()
575 mutex_unlock(&tzd->lock); in thermal_zone_of_sensor_unregister()
597 * devm_thermal_zone_of_sensor_register - Resource managed version of
624 return ERR_PTR(-ENOMEM); in devm_thermal_zone_of_sensor_register()
640 * devm_thermal_zone_of_sensor_unregister - Resource managed version of
663 * thermal_of_populate_bind_params - parse and fill cooling map data
664 * @np: DT node containing a cooling-map node
665 * @__tbp: data structure to be filled with cooling map info
669 * This function parses a cooling-map type of node represented by
688 __tbp->usage = THERMAL_WEIGHT_DEFAULT; in thermal_of_populate_bind_params()
691 __tbp->usage = prop; in thermal_of_populate_bind_params()
696 return -ENODEV; in thermal_of_populate_bind_params()
702 __tbp->trip_id = i; in thermal_of_populate_bind_params()
707 ret = -ENODEV; in thermal_of_populate_bind_params()
711 count = of_count_phandle_with_args(np, "cooling-device", in thermal_of_populate_bind_params()
712 "#cooling-cells"); in thermal_of_populate_bind_params()
715 ret = -ENOENT; in thermal_of_populate_bind_params()
721 ret = -ENOMEM; in thermal_of_populate_bind_params()
726 ret = of_parse_phandle_with_args(np, "cooling-device", in thermal_of_populate_bind_params()
727 "#cooling-cells", i, &cooling_spec); in thermal_of_populate_bind_params()
729 pr_err("Invalid cooling-device entry\n"); in thermal_of_populate_bind_params()
739 pr_err("wrong reference to cooling device, missing limits\n"); in thermal_of_populate_bind_params()
743 __tbp->tcbp = __tcbp; in thermal_of_populate_bind_params()
744 __tbp->count = count; in thermal_of_populate_bind_params()
749 for (i = i - 1; i >= 0; i--) in thermal_of_populate_bind_params()
759 * It maps 'enum thermal_trip_type' found in include/linux/thermal.h
770 * thermal_of_get_trip_type - Get phy mode for given device_node
795 return -ENODEV; in thermal_of_get_trip_type()
799 * thermal_of_populate_trip - parse and fill one trip point data
819 trip->temperature = prop; in thermal_of_populate_trip()
826 trip->hysteresis = prop; in thermal_of_populate_trip()
828 ret = thermal_of_get_trip_type(np, &trip->type); in thermal_of_populate_trip()
834 /* Required for cooling map matching */ in thermal_of_populate_trip()
835 trip->np = np; in thermal_of_populate_trip()
842 * thermal_of_build_thermal_zone - parse and fill one thermal zone data
849 * TODO: Missing properties to parse: thermal-sensor-names
865 return ERR_PTR(-EINVAL); in thermal_of_build_thermal_zone()
870 return ERR_PTR(-ENOMEM); in thermal_of_build_thermal_zone()
872 ret = of_property_read_u32(np, "polling-delay-passive", &prop); in thermal_of_build_thermal_zone()
874 pr_err("%pOFn: missing polling-delay-passive property\n", np); in thermal_of_build_thermal_zone()
877 tz->passive_delay = prop; in thermal_of_build_thermal_zone()
879 ret = of_property_read_u32(np, "polling-delay", &prop); in thermal_of_build_thermal_zone()
881 pr_err("%pOFn: missing polling-delay property\n", np); in thermal_of_build_thermal_zone()
884 tz->polling_delay = prop; in thermal_of_build_thermal_zone()
893 tz->slope = coef[0]; in thermal_of_build_thermal_zone()
894 tz->offset = coef[1]; in thermal_of_build_thermal_zone()
896 tz->slope = 1; in thermal_of_build_thermal_zone()
897 tz->offset = 0; in thermal_of_build_thermal_zone()
907 tz->ntrips = of_get_child_count(child); in thermal_of_build_thermal_zone()
908 if (tz->ntrips == 0) /* must have at least one child */ in thermal_of_build_thermal_zone()
911 tz->trips = kcalloc(tz->ntrips, sizeof(*tz->trips), GFP_KERNEL); in thermal_of_build_thermal_zone()
912 if (!tz->trips) { in thermal_of_build_thermal_zone()
913 ret = -ENOMEM; in thermal_of_build_thermal_zone()
919 ret = thermal_of_populate_trip(gchild, &tz->trips[i++]); in thermal_of_build_thermal_zone()
926 /* cooling-maps */ in thermal_of_build_thermal_zone()
927 child = of_get_child_by_name(np, "cooling-maps"); in thermal_of_build_thermal_zone()
929 /* cooling-maps not provided */ in thermal_of_build_thermal_zone()
933 tz->num_tbps = of_get_child_count(child); in thermal_of_build_thermal_zone()
934 if (tz->num_tbps == 0) in thermal_of_build_thermal_zone()
937 tz->tbps = kcalloc(tz->num_tbps, sizeof(*tz->tbps), GFP_KERNEL); in thermal_of_build_thermal_zone()
938 if (!tz->tbps) { in thermal_of_build_thermal_zone()
939 ret = -ENOMEM; in thermal_of_build_thermal_zone()
945 ret = thermal_of_populate_bind_params(gchild, &tz->tbps[i++], in thermal_of_build_thermal_zone()
946 tz->trips, tz->ntrips); in thermal_of_build_thermal_zone()
957 for (i = i - 1; i >= 0; i--) { in thermal_of_build_thermal_zone()
958 struct __thermal_bind_params *tbp = tz->tbps + i; in thermal_of_build_thermal_zone()
961 for (j = 0; j < tbp->count; j++) in thermal_of_build_thermal_zone()
962 of_node_put(tbp->tcbp[j].cooling_device); in thermal_of_build_thermal_zone()
964 kfree(tbp->tcbp); in thermal_of_build_thermal_zone()
967 kfree(tz->tbps); in thermal_of_build_thermal_zone()
969 for (i = 0; i < tz->ntrips; i++) in thermal_of_build_thermal_zone()
970 of_node_put(tz->trips[i].np); in thermal_of_build_thermal_zone()
971 kfree(tz->trips); in thermal_of_build_thermal_zone()
985 for (i = 0; i < tz->num_tbps; i++) { in of_thermal_free_zone()
986 tbp = tz->tbps + i; in of_thermal_free_zone()
988 for (j = 0; j < tbp->count; j++) in of_thermal_free_zone()
989 of_node_put(tbp->tcbp[j].cooling_device); in of_thermal_free_zone()
991 kfree(tbp->tcbp); in of_thermal_free_zone()
994 kfree(tz->tbps); in of_thermal_free_zone()
995 for (i = 0; i < tz->ntrips; i++) in of_thermal_free_zone()
996 of_node_put(tz->trips[i].np); in of_thermal_free_zone()
997 kfree(tz->trips); in of_thermal_free_zone()
1002 * of_thermal_destroy_zones - remove all zones parsed and allocated resources
1012 np = of_find_node_by_name(NULL, "thermal-zones"); in of_thermal_destroy_zones()
1021 zone = thermal_zone_get_zone_by_name(child->name); in of_thermal_destroy_zones()
1026 kfree(zone->tzp); in of_thermal_destroy_zones()
1027 kfree(zone->ops); in of_thermal_destroy_zones()
1028 of_thermal_free_zone(zone->devdata); in of_thermal_destroy_zones()
1034 * of_parse_thermal_zones - parse device tree thermal data
1039 * Cooling devices and sensor devices nodes are supposed to be parsed
1051 np = of_find_node_by_name(NULL, "thermal-zones"); in of_parse_thermal_zones()
1082 tzp->no_hwmon = true; in of_parse_thermal_zones()
1084 if (!of_property_read_u32(child, "sustainable-power", &prop)) in of_parse_thermal_zones()
1085 tzp->sustainable_power = prop; in of_parse_thermal_zones()
1087 for (i = 0; i < tz->ntrips; i++) in of_parse_thermal_zones()
1091 tzp->slope = tz->slope; in of_parse_thermal_zones()
1092 tzp->offset = tz->offset; in of_parse_thermal_zones()
1094 zone = thermal_zone_device_register(child->name, tz->ntrips, in of_parse_thermal_zones()
1097 tz->passive_delay, in of_parse_thermal_zones()
1098 tz->polling_delay); in of_parse_thermal_zones()
1120 return -ENOMEM; in of_parse_thermal_zones()