1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * of-thermal.c - Generic Thermal Management device tree support. 4 * 5 * Copyright (C) 2013 Texas Instruments 6 * Copyright (C) 2013 Eduardo Valentin <eduardo.valentin@ti.com> 7 */ 8 9 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 10 11 #include <linux/err.h> 12 #include <linux/export.h> 13 #include <linux/of_device.h> 14 #include <linux/of_platform.h> 15 #include <linux/slab.h> 16 #include <linux/thermal.h> 17 #include <linux/types.h> 18 #include <linux/string.h> 19 20 #include "thermal_core.h" 21 22 /*** Private data structures to represent thermal device tree data ***/ 23 24 /** 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 29 */ 30 31 struct __thermal_cooling_bind_param { 32 struct device_node *cooling_device; 33 unsigned long min; 34 unsigned long max; 35 }; 36 37 /** 38 * struct __thermal_bind_params - a match between trip and cooling device 39 * @tcbp: a pointer to an array of cooling devices 40 * @count: number of elements in array 41 * @trip_id: the trip point index 42 * @usage: the percentage (from 0 to 100) of cooling contribution 43 */ 44 45 struct __thermal_bind_params { 46 struct __thermal_cooling_bind_param *tcbp; 47 unsigned int count; 48 unsigned int trip_id; 49 unsigned int usage; 50 }; 51 52 /** 53 * struct __thermal_zone - internal representation of a thermal zone 54 * @passive_delay: polling interval while passive cooling is activated 55 * @polling_delay: zone polling interval 56 * @slope: slope of the temperature adjustment curve 57 * @offset: offset of the temperature adjustment curve 58 * @ntrips: number of trip points 59 * @trips: an array of trip points (0..ntrips - 1) 60 * @num_tbps: number of thermal bind params 61 * @tbps: an array of thermal bind params (0..num_tbps - 1) 62 * @sensor_data: sensor private data used while reading temperature and trend 63 * @ops: set of callbacks to handle the thermal zone based on DT 64 */ 65 66 struct __thermal_zone { 67 int passive_delay; 68 int polling_delay; 69 int slope; 70 int offset; 71 72 /* trip data */ 73 int ntrips; 74 struct thermal_trip *trips; 75 76 /* cooling binding data */ 77 int num_tbps; 78 struct __thermal_bind_params *tbps; 79 80 /* sensor interface */ 81 void *sensor_data; 82 const struct thermal_zone_of_device_ops *ops; 83 }; 84 85 /*** DT thermal zone device callbacks ***/ 86 87 static int of_thermal_get_temp(struct thermal_zone_device *tz, 88 int *temp) 89 { 90 struct __thermal_zone *data = tz->devdata; 91 92 if (!data->ops || !data->ops->get_temp) 93 return -EINVAL; 94 95 return data->ops->get_temp(data->sensor_data, temp); 96 } 97 98 static int of_thermal_set_trips(struct thermal_zone_device *tz, 99 int low, int high) 100 { 101 struct __thermal_zone *data = tz->devdata; 102 103 if (!data->ops || !data->ops->set_trips) 104 return -EINVAL; 105 106 return data->ops->set_trips(data->sensor_data, low, high); 107 } 108 109 /** 110 * of_thermal_get_ntrips - function to export number of available trip 111 * points. 112 * @tz: pointer to a thermal zone 113 * 114 * This function is a globally visible wrapper to get number of trip points 115 * stored in the local struct __thermal_zone 116 * 117 * Return: number of available trip points, -ENODEV when data not available 118 */ 119 int of_thermal_get_ntrips(struct thermal_zone_device *tz) 120 { 121 return tz->num_trips; 122 } 123 EXPORT_SYMBOL_GPL(of_thermal_get_ntrips); 124 125 /** 126 * of_thermal_is_trip_valid - function to check if trip point is valid 127 * 128 * @tz: pointer to a thermal zone 129 * @trip: trip point to evaluate 130 * 131 * This function is responsible for checking if passed trip point is valid 132 * 133 * Return: true if trip point is valid, false otherwise 134 */ 135 bool of_thermal_is_trip_valid(struct thermal_zone_device *tz, int trip) 136 { 137 if (trip >= tz->num_trips || trip < 0) 138 return false; 139 140 return true; 141 } 142 EXPORT_SYMBOL_GPL(of_thermal_is_trip_valid); 143 144 /** 145 * of_thermal_get_trip_points - function to get access to a globally exported 146 * trip points 147 * 148 * @tz: pointer to a thermal zone 149 * 150 * This function provides a pointer to trip points table 151 * 152 * Return: pointer to trip points table, NULL otherwise 153 */ 154 const struct thermal_trip * 155 of_thermal_get_trip_points(struct thermal_zone_device *tz) 156 { 157 return tz->trips; 158 } 159 EXPORT_SYMBOL_GPL(of_thermal_get_trip_points); 160 161 /** 162 * of_thermal_set_emul_temp - function to set emulated temperature 163 * 164 * @tz: pointer to a thermal zone 165 * @temp: temperature to set 166 * 167 * This function gives the ability to set emulated value of temperature, 168 * which is handy for debugging 169 * 170 * Return: zero on success, error code otherwise 171 */ 172 static int of_thermal_set_emul_temp(struct thermal_zone_device *tz, 173 int temp) 174 { 175 struct __thermal_zone *data = tz->devdata; 176 177 if (!data->ops || !data->ops->set_emul_temp) 178 return -EINVAL; 179 180 return data->ops->set_emul_temp(data->sensor_data, temp); 181 } 182 183 static int of_thermal_get_trend(struct thermal_zone_device *tz, int trip, 184 enum thermal_trend *trend) 185 { 186 struct __thermal_zone *data = tz->devdata; 187 188 if (!data->ops || !data->ops->get_trend) 189 return -EINVAL; 190 191 return data->ops->get_trend(data->sensor_data, trip, trend); 192 } 193 194 static int of_thermal_change_mode(struct thermal_zone_device *tz, 195 enum thermal_device_mode mode) 196 { 197 struct __thermal_zone *data = tz->devdata; 198 199 return data->ops->change_mode(data->sensor_data, mode); 200 } 201 202 static int of_thermal_bind(struct thermal_zone_device *thermal, 203 struct thermal_cooling_device *cdev) 204 { 205 struct __thermal_zone *data = thermal->devdata; 206 struct __thermal_bind_params *tbp; 207 struct __thermal_cooling_bind_param *tcbp; 208 int i, j; 209 210 if (!data || IS_ERR(data)) 211 return -ENODEV; 212 213 /* find where to bind */ 214 for (i = 0; i < data->num_tbps; i++) { 215 tbp = data->tbps + i; 216 217 for (j = 0; j < tbp->count; j++) { 218 tcbp = tbp->tcbp + j; 219 220 if (tcbp->cooling_device == cdev->np) { 221 int ret; 222 223 ret = thermal_zone_bind_cooling_device(thermal, 224 tbp->trip_id, cdev, 225 tcbp->max, 226 tcbp->min, 227 tbp->usage); 228 if (ret) 229 return ret; 230 } 231 } 232 } 233 234 return 0; 235 } 236 237 static int of_thermal_unbind(struct thermal_zone_device *thermal, 238 struct thermal_cooling_device *cdev) 239 { 240 struct __thermal_zone *data = thermal->devdata; 241 struct __thermal_bind_params *tbp; 242 struct __thermal_cooling_bind_param *tcbp; 243 int i, j; 244 245 if (!data || IS_ERR(data)) 246 return -ENODEV; 247 248 /* find where to unbind */ 249 for (i = 0; i < data->num_tbps; i++) { 250 tbp = data->tbps + i; 251 252 for (j = 0; j < tbp->count; j++) { 253 tcbp = tbp->tcbp + j; 254 255 if (tcbp->cooling_device == cdev->np) { 256 int ret; 257 258 ret = thermal_zone_unbind_cooling_device(thermal, 259 tbp->trip_id, cdev); 260 if (ret) 261 return ret; 262 } 263 } 264 } 265 266 return 0; 267 } 268 269 static int of_thermal_get_trip_type(struct thermal_zone_device *tz, int trip, 270 enum thermal_trip_type *type) 271 { 272 if (trip >= tz->num_trips || trip < 0) 273 return -EDOM; 274 275 *type = tz->trips[trip].type; 276 277 return 0; 278 } 279 280 static int of_thermal_get_trip_temp(struct thermal_zone_device *tz, int trip, 281 int *temp) 282 { 283 if (trip >= tz->num_trips || trip < 0) 284 return -EDOM; 285 286 *temp = tz->trips[trip].temperature; 287 288 return 0; 289 } 290 291 static int of_thermal_set_trip_temp(struct thermal_zone_device *tz, int trip, 292 int temp) 293 { 294 struct __thermal_zone *data = tz->devdata; 295 296 if (trip >= tz->num_trips || trip < 0) 297 return -EDOM; 298 299 if (data->ops && data->ops->set_trip_temp) { 300 int ret; 301 302 ret = data->ops->set_trip_temp(data->sensor_data, trip, temp); 303 if (ret) 304 return ret; 305 } 306 307 /* thermal framework should take care of data->mask & (1 << trip) */ 308 tz->trips[trip].temperature = temp; 309 310 return 0; 311 } 312 313 static int of_thermal_get_trip_hyst(struct thermal_zone_device *tz, int trip, 314 int *hyst) 315 { 316 if (trip >= tz->num_trips || trip < 0) 317 return -EDOM; 318 319 *hyst = tz->trips[trip].hysteresis; 320 321 return 0; 322 } 323 324 static int of_thermal_set_trip_hyst(struct thermal_zone_device *tz, int trip, 325 int hyst) 326 { 327 if (trip >= tz->num_trips || trip < 0) 328 return -EDOM; 329 330 /* thermal framework should take care of data->mask & (1 << trip) */ 331 tz->trips[trip].hysteresis = hyst; 332 333 return 0; 334 } 335 336 static int of_thermal_get_crit_temp(struct thermal_zone_device *tz, 337 int *temp) 338 { 339 int i; 340 341 for (i = 0; i < tz->num_trips; i++) 342 if (tz->trips[i].type == THERMAL_TRIP_CRITICAL) { 343 *temp = tz->trips[i].temperature; 344 return 0; 345 } 346 347 return -EINVAL; 348 } 349 350 static struct thermal_zone_device_ops of_thermal_ops = { 351 .get_trip_type = of_thermal_get_trip_type, 352 .get_trip_temp = of_thermal_get_trip_temp, 353 .set_trip_temp = of_thermal_set_trip_temp, 354 .get_trip_hyst = of_thermal_get_trip_hyst, 355 .set_trip_hyst = of_thermal_set_trip_hyst, 356 .get_crit_temp = of_thermal_get_crit_temp, 357 358 .bind = of_thermal_bind, 359 .unbind = of_thermal_unbind, 360 }; 361 362 /*** sensor API ***/ 363 364 static struct thermal_zone_device * 365 thermal_zone_of_add_sensor(struct device_node *zone, 366 struct device_node *sensor, void *data, 367 const struct thermal_zone_of_device_ops *ops) 368 { 369 struct thermal_zone_device *tzd; 370 struct __thermal_zone *tz; 371 372 tzd = thermal_zone_get_zone_by_name(zone->name); 373 if (IS_ERR(tzd)) 374 return ERR_PTR(-EPROBE_DEFER); 375 376 tz = tzd->devdata; 377 378 if (!ops) 379 return ERR_PTR(-EINVAL); 380 381 mutex_lock(&tzd->lock); 382 tz->ops = ops; 383 tz->sensor_data = data; 384 385 tzd->ops->get_temp = of_thermal_get_temp; 386 tzd->ops->get_trend = of_thermal_get_trend; 387 388 /* 389 * The thermal zone core will calculate the window if they have set the 390 * optional set_trips pointer. 391 */ 392 if (ops->set_trips) 393 tzd->ops->set_trips = of_thermal_set_trips; 394 395 if (ops->set_emul_temp) 396 tzd->ops->set_emul_temp = of_thermal_set_emul_temp; 397 398 if (ops->change_mode) 399 tzd->ops->change_mode = of_thermal_change_mode; 400 401 mutex_unlock(&tzd->lock); 402 403 return tzd; 404 } 405 406 /** 407 * thermal_zone_of_get_sensor_id - get sensor ID from a DT thermal zone 408 * @tz_np: a valid thermal zone device node. 409 * @sensor_np: a sensor node of a valid sensor device. 410 * @id: the sensor ID returned if success. 411 * 412 * This function will get sensor ID from a given thermal zone node and 413 * the sensor node must match the temperature provider @sensor_np. 414 * 415 * Return: 0 on success, proper error code otherwise. 416 */ 417 418 int thermal_zone_of_get_sensor_id(struct device_node *tz_np, 419 struct device_node *sensor_np, 420 u32 *id) 421 { 422 struct of_phandle_args sensor_specs; 423 int ret; 424 425 ret = of_parse_phandle_with_args(tz_np, 426 "thermal-sensors", 427 "#thermal-sensor-cells", 428 0, 429 &sensor_specs); 430 if (ret) 431 return ret; 432 433 if (sensor_specs.np != sensor_np) { 434 of_node_put(sensor_specs.np); 435 return -ENODEV; 436 } 437 438 if (sensor_specs.args_count > 1) 439 pr_warn("%pOFn: too many cells in sensor specifier %d\n", 440 sensor_specs.np, sensor_specs.args_count); 441 442 *id = sensor_specs.args_count ? sensor_specs.args[0] : 0; 443 444 of_node_put(sensor_specs.np); 445 446 return 0; 447 } 448 EXPORT_SYMBOL_GPL(thermal_zone_of_get_sensor_id); 449 450 /** 451 * thermal_zone_of_sensor_register - registers a sensor to a DT thermal zone 452 * @dev: a valid struct device pointer of a sensor device. Must contain 453 * a valid .of_node, for the sensor node. 454 * @sensor_id: a sensor identifier, in case the sensor IP has more 455 * than one sensors 456 * @data: a private pointer (owned by the caller) that will be passed 457 * back, when a temperature reading is needed. 458 * @ops: struct thermal_zone_of_device_ops *. Must contain at least .get_temp. 459 * 460 * This function will search the list of thermal zones described in device 461 * tree and look for the zone that refer to the sensor device pointed by 462 * @dev->of_node as temperature providers. For the zone pointing to the 463 * sensor node, the sensor will be added to the DT thermal zone device. 464 * 465 * The thermal zone temperature is provided by the @get_temp function 466 * pointer. When called, it will have the private pointer @data back. 467 * 468 * The thermal zone temperature trend is provided by the @get_trend function 469 * pointer. When called, it will have the private pointer @data back. 470 * 471 * TODO: 472 * 01 - This function must enqueue the new sensor instead of using 473 * it as the only source of temperature values. 474 * 475 * 02 - There must be a way to match the sensor with all thermal zones 476 * that refer to it. 477 * 478 * Return: On success returns a valid struct thermal_zone_device, 479 * otherwise, it returns a corresponding ERR_PTR(). Caller must 480 * check the return value with help of IS_ERR() helper. 481 */ 482 struct thermal_zone_device * 483 thermal_zone_of_sensor_register(struct device *dev, int sensor_id, void *data, 484 const struct thermal_zone_of_device_ops *ops) 485 { 486 struct device_node *np, *child, *sensor_np; 487 struct thermal_zone_device *tzd = ERR_PTR(-ENODEV); 488 489 np = of_find_node_by_name(NULL, "thermal-zones"); 490 if (!np) 491 return ERR_PTR(-ENODEV); 492 493 if (!dev || !dev->of_node) { 494 of_node_put(np); 495 return ERR_PTR(-ENODEV); 496 } 497 498 sensor_np = of_node_get(dev->of_node); 499 500 for_each_available_child_of_node(np, child) { 501 int ret, id; 502 503 /* For now, thermal framework supports only 1 sensor per zone */ 504 ret = thermal_zone_of_get_sensor_id(child, sensor_np, &id); 505 if (ret) 506 continue; 507 508 if (id == sensor_id) { 509 tzd = thermal_zone_of_add_sensor(child, sensor_np, 510 data, ops); 511 if (!IS_ERR(tzd)) 512 thermal_zone_device_enable(tzd); 513 514 of_node_put(child); 515 goto exit; 516 } 517 } 518 exit: 519 of_node_put(sensor_np); 520 of_node_put(np); 521 522 return tzd; 523 } 524 EXPORT_SYMBOL_GPL(thermal_zone_of_sensor_register); 525 526 /** 527 * thermal_zone_of_sensor_unregister - unregisters a sensor from a DT thermal zone 528 * @dev: a valid struct device pointer of a sensor device. Must contain 529 * a valid .of_node, for the sensor node. 530 * @tzd: a pointer to struct thermal_zone_device where the sensor is registered. 531 * 532 * This function removes the sensor callbacks and private data from the 533 * thermal zone device registered with thermal_zone_of_sensor_register() 534 * API. It will also silent the zone by remove the .get_temp() and .get_trend() 535 * thermal zone device callbacks. 536 * 537 * TODO: When the support to several sensors per zone is added, this 538 * function must search the sensor list based on @dev parameter. 539 * 540 */ 541 void thermal_zone_of_sensor_unregister(struct device *dev, 542 struct thermal_zone_device *tzd) 543 { 544 struct __thermal_zone *tz; 545 546 if (!dev || !tzd || !tzd->devdata) 547 return; 548 549 tz = tzd->devdata; 550 551 /* no __thermal_zone, nothing to be done */ 552 if (!tz) 553 return; 554 555 /* stop temperature polling */ 556 thermal_zone_device_disable(tzd); 557 558 mutex_lock(&tzd->lock); 559 tzd->ops->get_temp = NULL; 560 tzd->ops->get_trend = NULL; 561 tzd->ops->set_emul_temp = NULL; 562 tzd->ops->change_mode = NULL; 563 564 tz->ops = NULL; 565 tz->sensor_data = NULL; 566 mutex_unlock(&tzd->lock); 567 } 568 EXPORT_SYMBOL_GPL(thermal_zone_of_sensor_unregister); 569 570 static void devm_thermal_zone_of_sensor_release(struct device *dev, void *res) 571 { 572 thermal_zone_of_sensor_unregister(dev, 573 *(struct thermal_zone_device **)res); 574 } 575 576 static int devm_thermal_zone_of_sensor_match(struct device *dev, void *res, 577 void *data) 578 { 579 struct thermal_zone_device **r = res; 580 581 if (WARN_ON(!r || !*r)) 582 return 0; 583 584 return *r == data; 585 } 586 587 /** 588 * devm_thermal_zone_of_sensor_register - Resource managed version of 589 * thermal_zone_of_sensor_register() 590 * @dev: a valid struct device pointer of a sensor device. Must contain 591 * a valid .of_node, for the sensor node. 592 * @sensor_id: a sensor identifier, in case the sensor IP has more 593 * than one sensors 594 * @data: a private pointer (owned by the caller) that will be passed 595 * back, when a temperature reading is needed. 596 * @ops: struct thermal_zone_of_device_ops *. Must contain at least .get_temp. 597 * 598 * Refer thermal_zone_of_sensor_register() for more details. 599 * 600 * Return: On success returns a valid struct thermal_zone_device, 601 * otherwise, it returns a corresponding ERR_PTR(). Caller must 602 * check the return value with help of IS_ERR() helper. 603 * Registered thermal_zone_device device will automatically be 604 * released when device is unbounded. 605 */ 606 struct thermal_zone_device *devm_thermal_zone_of_sensor_register( 607 struct device *dev, int sensor_id, 608 void *data, const struct thermal_zone_of_device_ops *ops) 609 { 610 struct thermal_zone_device **ptr, *tzd; 611 612 ptr = devres_alloc(devm_thermal_zone_of_sensor_release, sizeof(*ptr), 613 GFP_KERNEL); 614 if (!ptr) 615 return ERR_PTR(-ENOMEM); 616 617 tzd = thermal_zone_of_sensor_register(dev, sensor_id, data, ops); 618 if (IS_ERR(tzd)) { 619 devres_free(ptr); 620 return tzd; 621 } 622 623 *ptr = tzd; 624 devres_add(dev, ptr); 625 626 return tzd; 627 } 628 EXPORT_SYMBOL_GPL(devm_thermal_zone_of_sensor_register); 629 630 /** 631 * devm_thermal_zone_of_sensor_unregister - Resource managed version of 632 * thermal_zone_of_sensor_unregister(). 633 * @dev: Device for which which resource was allocated. 634 * @tzd: a pointer to struct thermal_zone_device where the sensor is registered. 635 * 636 * This function removes the sensor callbacks and private data from the 637 * thermal zone device registered with devm_thermal_zone_of_sensor_register() 638 * API. It will also silent the zone by remove the .get_temp() and .get_trend() 639 * thermal zone device callbacks. 640 * Normally this function will not need to be called and the resource 641 * management code will ensure that the resource is freed. 642 */ 643 void devm_thermal_zone_of_sensor_unregister(struct device *dev, 644 struct thermal_zone_device *tzd) 645 { 646 WARN_ON(devres_release(dev, devm_thermal_zone_of_sensor_release, 647 devm_thermal_zone_of_sensor_match, tzd)); 648 } 649 EXPORT_SYMBOL_GPL(devm_thermal_zone_of_sensor_unregister); 650 651 /*** functions parsing device tree nodes ***/ 652 653 static int of_find_trip_id(struct device_node *np, struct device_node *trip) 654 { 655 struct device_node *trips; 656 struct device_node *t; 657 int i = 0; 658 659 trips = of_get_child_by_name(np, "trips"); 660 if (!trips) { 661 pr_err("Failed to find 'trips' node\n"); 662 return -EINVAL; 663 } 664 665 /* 666 * Find the trip id point associated with the cooling device map 667 */ 668 for_each_child_of_node(trips, t) { 669 670 if (t == trip) 671 goto out; 672 i++; 673 } 674 675 i = -ENXIO; 676 out: 677 of_node_put(trips); 678 679 return i; 680 } 681 682 /** 683 * thermal_of_populate_bind_params - parse and fill cooling map data 684 * @np: DT node containing a cooling-map node 685 * @__tbp: data structure to be filled with cooling map info 686 * @trips: array of thermal zone trip points 687 * @ntrips: number of trip points inside trips. 688 * 689 * This function parses a cooling-map type of node represented by 690 * @np parameter and fills the read data into @__tbp data structure. 691 * It needs the already parsed array of trip points of the thermal zone 692 * in consideration. 693 * 694 * Return: 0 on success, proper error code otherwise 695 */ 696 static int thermal_of_populate_bind_params(struct device_node *tz_np, 697 struct device_node *np, 698 struct __thermal_bind_params *__tbp) 699 { 700 struct of_phandle_args cooling_spec; 701 struct __thermal_cooling_bind_param *__tcbp; 702 struct device_node *trip; 703 int ret, i, count; 704 int trip_id; 705 u32 prop; 706 707 /* Default weight. Usage is optional */ 708 __tbp->usage = THERMAL_WEIGHT_DEFAULT; 709 ret = of_property_read_u32(np, "contribution", &prop); 710 if (ret == 0) 711 __tbp->usage = prop; 712 713 trip = of_parse_phandle(np, "trip", 0); 714 if (!trip) { 715 pr_err("missing trip property\n"); 716 return -ENODEV; 717 } 718 719 trip_id = of_find_trip_id(tz_np, trip); 720 if (trip_id < 0) { 721 ret = trip_id; 722 goto end; 723 } 724 725 __tbp->trip_id = trip_id; 726 727 count = of_count_phandle_with_args(np, "cooling-device", 728 "#cooling-cells"); 729 if (count <= 0) { 730 pr_err("Add a cooling_device property with at least one device\n"); 731 ret = -ENOENT; 732 goto end; 733 } 734 735 __tcbp = kcalloc(count, sizeof(*__tcbp), GFP_KERNEL); 736 if (!__tcbp) { 737 ret = -ENOMEM; 738 goto end; 739 } 740 741 for (i = 0; i < count; i++) { 742 ret = of_parse_phandle_with_args(np, "cooling-device", 743 "#cooling-cells", i, &cooling_spec); 744 if (ret < 0) { 745 pr_err("Invalid cooling-device entry\n"); 746 goto free_tcbp; 747 } 748 749 __tcbp[i].cooling_device = cooling_spec.np; 750 751 if (cooling_spec.args_count >= 2) { /* at least min and max */ 752 __tcbp[i].min = cooling_spec.args[0]; 753 __tcbp[i].max = cooling_spec.args[1]; 754 } else { 755 pr_err("wrong reference to cooling device, missing limits\n"); 756 } 757 } 758 759 __tbp->tcbp = __tcbp; 760 __tbp->count = count; 761 762 goto end; 763 764 free_tcbp: 765 for (i = i - 1; i >= 0; i--) 766 of_node_put(__tcbp[i].cooling_device); 767 kfree(__tcbp); 768 end: 769 of_node_put(trip); 770 771 return ret; 772 } 773 774 /* 775 * It maps 'enum thermal_trip_type' found in include/linux/thermal.h 776 * into the device tree binding of 'trip', property type. 777 */ 778 static const char * const trip_types[] = { 779 [THERMAL_TRIP_ACTIVE] = "active", 780 [THERMAL_TRIP_PASSIVE] = "passive", 781 [THERMAL_TRIP_HOT] = "hot", 782 [THERMAL_TRIP_CRITICAL] = "critical", 783 }; 784 785 /** 786 * thermal_of_get_trip_type - Get phy mode for given device_node 787 * @np: Pointer to the given device_node 788 * @type: Pointer to resulting trip type 789 * 790 * The function gets trip type string from property 'type', 791 * and store its index in trip_types table in @type, 792 * 793 * Return: 0 on success, or errno in error case. 794 */ 795 static int thermal_of_get_trip_type(struct device_node *np, 796 enum thermal_trip_type *type) 797 { 798 const char *t; 799 int err, i; 800 801 err = of_property_read_string(np, "type", &t); 802 if (err < 0) 803 return err; 804 805 for (i = 0; i < ARRAY_SIZE(trip_types); i++) 806 if (!strcasecmp(t, trip_types[i])) { 807 *type = i; 808 return 0; 809 } 810 811 return -ENODEV; 812 } 813 814 static int thermal_of_populate_trip(struct device_node *np, 815 struct thermal_trip *trip) 816 { 817 int prop; 818 int ret; 819 820 ret = of_property_read_u32(np, "temperature", &prop); 821 if (ret < 0) { 822 pr_err("missing temperature property\n"); 823 return ret; 824 } 825 trip->temperature = prop; 826 827 ret = of_property_read_u32(np, "hysteresis", &prop); 828 if (ret < 0) { 829 pr_err("missing hysteresis property\n"); 830 return ret; 831 } 832 trip->hysteresis = prop; 833 834 ret = thermal_of_get_trip_type(np, &trip->type); 835 if (ret < 0) { 836 pr_err("wrong trip type property\n"); 837 return ret; 838 } 839 840 return 0; 841 } 842 843 static struct thermal_trip *thermal_of_trips_init(struct device_node *np, int *ntrips) 844 { 845 struct thermal_trip *tt; 846 struct device_node *trips, *trip; 847 int ret, count; 848 849 trips = of_get_child_by_name(np, "trips"); 850 if (!trips) { 851 pr_err("Failed to find 'trips' node\n"); 852 return ERR_PTR(-EINVAL); 853 } 854 855 count = of_get_child_count(trips); 856 if (!count) { 857 pr_err("No trip point defined\n"); 858 ret = -EINVAL; 859 goto out_of_node_put; 860 } 861 862 tt = kzalloc(sizeof(*tt) * count, GFP_KERNEL); 863 if (!tt) { 864 ret = -ENOMEM; 865 goto out_of_node_put; 866 } 867 868 *ntrips = count; 869 870 count = 0; 871 for_each_child_of_node(trips, trip) { 872 ret = thermal_of_populate_trip(trip, &tt[count++]); 873 if (ret) 874 goto out_kfree; 875 } 876 877 of_node_put(trips); 878 879 return tt; 880 881 out_kfree: 882 kfree(tt); 883 *ntrips = 0; 884 out_of_node_put: 885 of_node_put(trips); 886 887 return ERR_PTR(ret); 888 } 889 890 /** 891 * thermal_of_build_thermal_zone - parse and fill one thermal zone data 892 * @np: DT node containing a thermal zone node 893 * 894 * This function parses a thermal zone type of node represented by 895 * @np parameter and fills the read data into a __thermal_zone data structure 896 * and return this pointer. 897 * 898 * TODO: Missing properties to parse: thermal-sensor-names 899 * 900 * Return: On success returns a valid struct __thermal_zone, 901 * otherwise, it returns a corresponding ERR_PTR(). Caller must 902 * check the return value with help of IS_ERR() helper. 903 */ 904 static struct __thermal_zone 905 __init *thermal_of_build_thermal_zone(struct device_node *np) 906 { 907 struct device_node *child = NULL, *gchild; 908 struct __thermal_zone *tz; 909 int ret, i; 910 u32 prop, coef[2]; 911 912 if (!np) { 913 pr_err("no thermal zone np\n"); 914 return ERR_PTR(-EINVAL); 915 } 916 917 tz = kzalloc(sizeof(*tz), GFP_KERNEL); 918 if (!tz) 919 return ERR_PTR(-ENOMEM); 920 921 ret = of_property_read_u32(np, "polling-delay-passive", &prop); 922 if (ret < 0) { 923 pr_err("%pOFn: missing polling-delay-passive property\n", np); 924 goto free_tz; 925 } 926 tz->passive_delay = prop; 927 928 ret = of_property_read_u32(np, "polling-delay", &prop); 929 if (ret < 0) { 930 pr_err("%pOFn: missing polling-delay property\n", np); 931 goto free_tz; 932 } 933 tz->polling_delay = prop; 934 935 /* 936 * REVIST: for now, the thermal framework supports only 937 * one sensor per thermal zone. Thus, we are considering 938 * only the first two values as slope and offset. 939 */ 940 ret = of_property_read_u32_array(np, "coefficients", coef, 2); 941 if (ret == 0) { 942 tz->slope = coef[0]; 943 tz->offset = coef[1]; 944 } else { 945 tz->slope = 1; 946 tz->offset = 0; 947 } 948 949 tz->trips = thermal_of_trips_init(np, &tz->ntrips); 950 if (IS_ERR(tz->trips)) { 951 ret = PTR_ERR(tz->trips); 952 goto finish; 953 } 954 955 /* cooling-maps */ 956 child = of_get_child_by_name(np, "cooling-maps"); 957 958 /* cooling-maps not provided */ 959 if (!child) 960 goto finish; 961 962 tz->num_tbps = of_get_child_count(child); 963 if (tz->num_tbps == 0) 964 goto finish; 965 966 tz->tbps = kcalloc(tz->num_tbps, sizeof(*tz->tbps), GFP_KERNEL); 967 if (!tz->tbps) { 968 ret = -ENOMEM; 969 goto free_trips; 970 } 971 972 i = 0; 973 for_each_child_of_node(child, gchild) { 974 ret = thermal_of_populate_bind_params(np, gchild, &tz->tbps[i++]); 975 if (ret) { 976 of_node_put(gchild); 977 goto free_tbps; 978 } 979 } 980 981 finish: 982 of_node_put(child); 983 984 return tz; 985 986 free_tbps: 987 for (i = i - 1; i >= 0; i--) { 988 struct __thermal_bind_params *tbp = tz->tbps + i; 989 int j; 990 991 for (j = 0; j < tbp->count; j++) 992 of_node_put(tbp->tcbp[j].cooling_device); 993 994 kfree(tbp->tcbp); 995 } 996 997 kfree(tz->tbps); 998 free_trips: 999 kfree(tz->trips); 1000 free_tz: 1001 kfree(tz); 1002 of_node_put(child); 1003 1004 return ERR_PTR(ret); 1005 } 1006 1007 static __init void of_thermal_free_zone(struct __thermal_zone *tz) 1008 { 1009 struct __thermal_bind_params *tbp; 1010 int i, j; 1011 1012 for (i = 0; i < tz->num_tbps; i++) { 1013 tbp = tz->tbps + i; 1014 1015 for (j = 0; j < tbp->count; j++) 1016 of_node_put(tbp->tcbp[j].cooling_device); 1017 1018 kfree(tbp->tcbp); 1019 } 1020 1021 kfree(tz->tbps); 1022 kfree(tz->trips); 1023 kfree(tz); 1024 } 1025 1026 /** 1027 * of_thermal_destroy_zones - remove all zones parsed and allocated resources 1028 * 1029 * Finds all zones parsed and added to the thermal framework and remove them 1030 * from the system, together with their resources. 1031 * 1032 */ 1033 static __init void of_thermal_destroy_zones(void) 1034 { 1035 struct device_node *np, *child; 1036 1037 np = of_find_node_by_name(NULL, "thermal-zones"); 1038 if (!np) { 1039 pr_debug("unable to find thermal zones\n"); 1040 return; 1041 } 1042 1043 for_each_available_child_of_node(np, child) { 1044 struct thermal_zone_device *zone; 1045 1046 zone = thermal_zone_get_zone_by_name(child->name); 1047 if (IS_ERR(zone)) 1048 continue; 1049 1050 thermal_zone_device_unregister(zone); 1051 kfree(zone->tzp); 1052 kfree(zone->ops); 1053 of_thermal_free_zone(zone->devdata); 1054 } 1055 of_node_put(np); 1056 } 1057 1058 static struct device_node *of_thermal_zone_find(struct device_node *sensor, int id) 1059 { 1060 struct device_node *np, *tz; 1061 struct of_phandle_args sensor_specs; 1062 1063 np = of_find_node_by_name(NULL, "thermal-zones"); 1064 if (!np) { 1065 pr_err("Unable to find thermal zones description\n"); 1066 return ERR_PTR(-EINVAL); 1067 } 1068 1069 /* 1070 * Search for each thermal zone, a defined sensor 1071 * corresponding to the one passed as parameter 1072 */ 1073 for_each_available_child_of_node(np, tz) { 1074 1075 int count, i; 1076 1077 count = of_count_phandle_with_args(tz, "thermal-sensors", 1078 "#thermal-sensor-cells"); 1079 if (count <= 0) { 1080 pr_err("%pOFn: missing thermal sensor\n", tz); 1081 tz = ERR_PTR(-EINVAL); 1082 goto out; 1083 } 1084 1085 for (i = 0; i < count; i++) { 1086 1087 int ret; 1088 1089 ret = of_parse_phandle_with_args(tz, "thermal-sensors", 1090 "#thermal-sensor-cells", 1091 i, &sensor_specs); 1092 if (ret < 0) { 1093 pr_err("%pOFn: Failed to read thermal-sensors cells: %d\n", tz, ret); 1094 tz = ERR_PTR(ret); 1095 goto out; 1096 } 1097 1098 if ((sensor == sensor_specs.np) && id == (sensor_specs.args_count ? 1099 sensor_specs.args[0] : 0)) { 1100 pr_debug("sensor %pOFn id=%d belongs to %pOFn\n", sensor, id, tz); 1101 goto out; 1102 } 1103 } 1104 } 1105 tz = ERR_PTR(-EINVAL); 1106 out: 1107 of_node_put(np); 1108 return tz; 1109 } 1110 1111 static int thermal_of_monitor_init(struct device_node *np, int *delay, int *pdelay) 1112 { 1113 int ret; 1114 1115 ret = of_property_read_u32(np, "polling-delay-passive", pdelay); 1116 if (ret < 0) { 1117 pr_err("%pOFn: missing polling-delay-passive property\n", np); 1118 return ret; 1119 } 1120 1121 ret = of_property_read_u32(np, "polling-delay", delay); 1122 if (ret < 0) { 1123 pr_err("%pOFn: missing polling-delay property\n", np); 1124 return ret; 1125 } 1126 1127 return 0; 1128 } 1129 1130 static struct thermal_zone_params *thermal_of_parameters_init(struct device_node *np) 1131 { 1132 struct thermal_zone_params *tzp; 1133 int coef[2]; 1134 int ncoef = ARRAY_SIZE(coef); 1135 int prop, ret; 1136 1137 tzp = kzalloc(sizeof(*tzp), GFP_KERNEL); 1138 if (!tzp) 1139 return ERR_PTR(-ENOMEM); 1140 1141 tzp->no_hwmon = true; 1142 1143 if (!of_property_read_u32(np, "sustainable-power", &prop)) 1144 tzp->sustainable_power = prop; 1145 1146 /* 1147 * For now, the thermal framework supports only one sensor per 1148 * thermal zone. Thus, we are considering only the first two 1149 * values as slope and offset. 1150 */ 1151 ret = of_property_read_u32_array(np, "coefficients", coef, ncoef); 1152 if (ret) { 1153 coef[0] = 1; 1154 coef[1] = 0; 1155 } 1156 1157 tzp->slope = coef[0]; 1158 tzp->offset = coef[1]; 1159 1160 return tzp; 1161 } 1162 1163 static struct device_node *thermal_of_zone_get_by_name(struct thermal_zone_device *tz) 1164 { 1165 struct device_node *np, *tz_np; 1166 1167 np = of_find_node_by_name(NULL, "thermal-zones"); 1168 if (!np) 1169 return ERR_PTR(-ENODEV); 1170 1171 tz_np = of_get_child_by_name(np, tz->type); 1172 1173 of_node_put(np); 1174 1175 if (!tz_np) 1176 return ERR_PTR(-ENODEV); 1177 1178 return tz_np; 1179 } 1180 1181 static int __thermal_of_unbind(struct device_node *map_np, int index, int trip_id, 1182 struct thermal_zone_device *tz, struct thermal_cooling_device *cdev) 1183 { 1184 struct of_phandle_args cooling_spec; 1185 int ret; 1186 1187 ret = of_parse_phandle_with_args(map_np, "cooling-device", "#cooling-cells", 1188 index, &cooling_spec); 1189 1190 of_node_put(cooling_spec.np); 1191 1192 if (ret < 0) { 1193 pr_err("Invalid cooling-device entry\n"); 1194 return ret; 1195 } 1196 1197 if (cooling_spec.args_count < 2) { 1198 pr_err("wrong reference to cooling device, missing limits\n"); 1199 return -EINVAL; 1200 } 1201 1202 if (cooling_spec.np != cdev->np) 1203 return 0; 1204 1205 ret = thermal_zone_unbind_cooling_device(tz, trip_id, cdev); 1206 if (ret) 1207 pr_err("Failed to unbind '%s' with '%s': %d\n", tz->type, cdev->type, ret); 1208 1209 return ret; 1210 } 1211 1212 static int __thermal_of_bind(struct device_node *map_np, int index, int trip_id, 1213 struct thermal_zone_device *tz, struct thermal_cooling_device *cdev) 1214 { 1215 struct of_phandle_args cooling_spec; 1216 int ret, weight = THERMAL_WEIGHT_DEFAULT; 1217 1218 of_property_read_u32(map_np, "contribution", &weight); 1219 1220 ret = of_parse_phandle_with_args(map_np, "cooling-device", "#cooling-cells", 1221 index, &cooling_spec); 1222 1223 of_node_put(cooling_spec.np); 1224 1225 if (ret < 0) { 1226 pr_err("Invalid cooling-device entry\n"); 1227 return ret; 1228 } 1229 1230 if (cooling_spec.args_count < 2) { 1231 pr_err("wrong reference to cooling device, missing limits\n"); 1232 return -EINVAL; 1233 } 1234 1235 if (cooling_spec.np != cdev->np) 1236 return 0; 1237 1238 ret = thermal_zone_bind_cooling_device(tz, trip_id, cdev, cooling_spec.args[1], 1239 cooling_spec.args[0], 1240 weight); 1241 if (ret) 1242 pr_err("Failed to bind '%s' with '%s': %d\n", tz->type, cdev->type, ret); 1243 1244 return ret; 1245 } 1246 1247 static int thermal_of_for_each_cooling_device(struct device_node *tz_np, struct device_node *map_np, 1248 struct thermal_zone_device *tz, struct thermal_cooling_device *cdev, 1249 int (*action)(struct device_node *, int, int, 1250 struct thermal_zone_device *, struct thermal_cooling_device *)) 1251 { 1252 struct device_node *tr_np; 1253 int count, i, trip_id; 1254 1255 tr_np = of_parse_phandle(map_np, "trip", 0); 1256 if (!tr_np) 1257 return -ENODEV; 1258 1259 trip_id = of_find_trip_id(tz_np, tr_np); 1260 if (trip_id < 0) 1261 return trip_id; 1262 1263 count = of_count_phandle_with_args(map_np, "cooling-device", "#cooling-cells"); 1264 if (count <= 0) { 1265 pr_err("Add a cooling_device property with at least one device\n"); 1266 return -ENOENT; 1267 } 1268 1269 /* 1270 * At this point, we don't want to bail out when there is an 1271 * error, we will try to bind/unbind as many as possible 1272 * cooling devices 1273 */ 1274 for (i = 0; i < count; i++) 1275 action(map_np, i, trip_id, tz, cdev); 1276 1277 return 0; 1278 } 1279 1280 static int thermal_of_for_each_cooling_maps(struct thermal_zone_device *tz, 1281 struct thermal_cooling_device *cdev, 1282 int (*action)(struct device_node *, int, int, 1283 struct thermal_zone_device *, struct thermal_cooling_device *)) 1284 { 1285 struct device_node *tz_np, *cm_np, *child; 1286 int ret = 0; 1287 1288 tz_np = thermal_of_zone_get_by_name(tz); 1289 if (IS_ERR(tz_np)) { 1290 pr_err("Failed to get node tz by name\n"); 1291 return PTR_ERR(tz_np); 1292 } 1293 1294 cm_np = of_get_child_by_name(tz_np, "cooling-maps"); 1295 if (!cm_np) 1296 goto out; 1297 1298 for_each_child_of_node(cm_np, child) { 1299 ret = thermal_of_for_each_cooling_device(tz_np, child, tz, cdev, action); 1300 if (ret) 1301 break; 1302 } 1303 1304 of_node_put(cm_np); 1305 out: 1306 of_node_put(tz_np); 1307 1308 return ret; 1309 } 1310 1311 static int thermal_of_bind(struct thermal_zone_device *tz, 1312 struct thermal_cooling_device *cdev) 1313 { 1314 return thermal_of_for_each_cooling_maps(tz, cdev, __thermal_of_bind); 1315 } 1316 1317 static int thermal_of_unbind(struct thermal_zone_device *tz, 1318 struct thermal_cooling_device *cdev) 1319 { 1320 return thermal_of_for_each_cooling_maps(tz, cdev, __thermal_of_unbind); 1321 } 1322 1323 /** 1324 * thermal_of_zone_unregister - Cleanup the specific allocated ressources 1325 * 1326 * This function disables the thermal zone and frees the different 1327 * ressources allocated specific to the thermal OF. 1328 * 1329 * @tz: a pointer to the thermal zone structure 1330 */ 1331 void thermal_of_zone_unregister(struct thermal_zone_device *tz) 1332 { 1333 thermal_zone_device_disable(tz); 1334 thermal_zone_device_unregister(tz); 1335 kfree(tz->trips); 1336 kfree(tz->tzp); 1337 kfree(tz->ops); 1338 } 1339 EXPORT_SYMBOL_GPL(thermal_of_zone_unregister); 1340 1341 /** 1342 * thermal_of_zone_register - Register a thermal zone with device node 1343 * sensor 1344 * 1345 * The thermal_of_zone_register() parses a device tree given a device 1346 * node sensor and identifier. It searches for the thermal zone 1347 * associated to the couple sensor/id and retrieves all the thermal 1348 * zone properties and registers new thermal zone with those 1349 * properties. 1350 * 1351 * @sensor: A device node pointer corresponding to the sensor in the device tree 1352 * @id: An integer as sensor identifier 1353 * @data: A private data to be stored in the thermal zone dedicated private area 1354 * @ops: A set of thermal sensor ops 1355 * 1356 * Return: a valid thermal zone structure pointer on success. 1357 * - EINVAL: if the device tree thermal description is malformed 1358 * - ENOMEM: if one structure can not be allocated 1359 * - Other negative errors are returned by the underlying called functions 1360 */ 1361 struct thermal_zone_device *thermal_of_zone_register(struct device_node *sensor, int id, void *data, 1362 const struct thermal_zone_device_ops *ops) 1363 { 1364 struct thermal_zone_device *tz; 1365 struct thermal_trip *trips; 1366 struct thermal_zone_params *tzp; 1367 struct thermal_zone_device_ops *of_ops; 1368 struct device_node *np; 1369 int delay, pdelay; 1370 int ntrips, mask; 1371 int ret; 1372 1373 of_ops = kmemdup(ops, sizeof(*ops), GFP_KERNEL); 1374 if (!of_ops) 1375 return ERR_PTR(-ENOMEM); 1376 1377 np = of_thermal_zone_find(sensor, id); 1378 if (IS_ERR(np)) { 1379 pr_err("Failed to find thermal zone for %pOFn id=%d\n", sensor, id); 1380 return ERR_CAST(np); 1381 } 1382 1383 trips = thermal_of_trips_init(np, &ntrips); 1384 if (IS_ERR(trips)) { 1385 pr_err("Failed to find trip points for %pOFn id=%d\n", sensor, id); 1386 return ERR_CAST(trips); 1387 } 1388 1389 ret = thermal_of_monitor_init(np, &delay, &pdelay); 1390 if (ret) { 1391 pr_err("Failed to initialize monitoring delays from %pOFn\n", np); 1392 goto out_kfree_trips; 1393 } 1394 1395 tzp = thermal_of_parameters_init(np); 1396 if (IS_ERR(tzp)) { 1397 ret = PTR_ERR(tzp); 1398 pr_err("Failed to initialize parameter from %pOFn: %d\n", np, ret); 1399 goto out_kfree_trips; 1400 } 1401 1402 of_ops->get_trip_type = of_ops->get_trip_type ? : of_thermal_get_trip_type; 1403 of_ops->get_trip_temp = of_ops->get_trip_temp ? : of_thermal_get_trip_temp; 1404 of_ops->get_trip_hyst = of_ops->get_trip_hyst ? : of_thermal_get_trip_hyst; 1405 of_ops->set_trip_hyst = of_ops->set_trip_hyst ? : of_thermal_set_trip_hyst; 1406 of_ops->get_crit_temp = of_ops->get_crit_temp ? : of_thermal_get_crit_temp; 1407 of_ops->bind = thermal_of_bind; 1408 of_ops->unbind = thermal_of_unbind; 1409 1410 mask = GENMASK_ULL((ntrips) - 1, 0); 1411 1412 tz = thermal_zone_device_register_with_trips(np->name, trips, ntrips, 1413 mask, data, of_ops, tzp, 1414 pdelay, delay); 1415 if (IS_ERR(tz)) { 1416 ret = PTR_ERR(tz); 1417 pr_err("Failed to register thermal zone %pOFn: %d\n", np, ret); 1418 goto out_kfree_tzp; 1419 } 1420 1421 ret = thermal_zone_device_enable(tz); 1422 if (ret) { 1423 pr_err("Failed to enabled thermal zone '%s', id=%d: %d\n", 1424 tz->type, tz->id, ret); 1425 thermal_of_zone_unregister(tz); 1426 return ERR_PTR(ret); 1427 } 1428 1429 return tz; 1430 1431 out_kfree_tzp: 1432 kfree(tzp); 1433 out_kfree_trips: 1434 kfree(trips); 1435 1436 return ERR_PTR(ret); 1437 } 1438 EXPORT_SYMBOL_GPL(thermal_of_zone_register); 1439 1440 static void devm_thermal_of_zone_release(struct device *dev, void *res) 1441 { 1442 thermal_of_zone_unregister(*(struct thermal_zone_device **)res); 1443 } 1444 1445 static int devm_thermal_of_zone_match(struct device *dev, void *res, 1446 void *data) 1447 { 1448 struct thermal_zone_device **r = res; 1449 1450 if (WARN_ON(!r || !*r)) 1451 return 0; 1452 1453 return *r == data; 1454 } 1455 1456 /** 1457 * devm_thermal_of_zone_register - register a thermal tied with the sensor life cycle 1458 * 1459 * This function is the device version of the thermal_of_zone_register() function. 1460 * 1461 * @dev: a device structure pointer to sensor to be tied with the thermal zone OF life cycle 1462 * @sensor_id: the sensor identifier 1463 * @data: a pointer to a private data to be stored in the thermal zone 'devdata' field 1464 * @ops: a pointer to the ops structure associated with the sensor 1465 */ 1466 struct thermal_zone_device *devm_thermal_of_zone_register(struct device *dev, int sensor_id, void *data, 1467 const struct thermal_zone_device_ops *ops) 1468 { 1469 struct thermal_zone_device **ptr, *tzd; 1470 1471 ptr = devres_alloc(devm_thermal_of_zone_release, sizeof(*ptr), 1472 GFP_KERNEL); 1473 if (!ptr) 1474 return ERR_PTR(-ENOMEM); 1475 1476 tzd = thermal_of_zone_register(dev->of_node, sensor_id, data, ops); 1477 if (IS_ERR(tzd)) { 1478 devres_free(ptr); 1479 return tzd; 1480 } 1481 1482 *ptr = tzd; 1483 devres_add(dev, ptr); 1484 1485 return tzd; 1486 } 1487 EXPORT_SYMBOL_GPL(devm_thermal_of_zone_register); 1488 1489 /** 1490 * devm_thermal_of_zone_unregister - Resource managed version of 1491 * thermal_of_zone_unregister(). 1492 * @dev: Device for which which resource was allocated. 1493 * @tz: a pointer to struct thermal_zone where the sensor is registered. 1494 * 1495 * This function removes the sensor callbacks and private data from the 1496 * thermal zone device registered with devm_thermal_zone_of_sensor_register() 1497 * API. It will also silent the zone by remove the .get_temp() and .get_trend() 1498 * thermal zone device callbacks. 1499 * Normally this function will not need to be called and the resource 1500 * management code will ensure that the resource is freed. 1501 */ 1502 void devm_thermal_of_zone_unregister(struct device *dev, struct thermal_zone_device *tz) 1503 { 1504 WARN_ON(devres_release(dev, devm_thermal_zone_of_sensor_release, 1505 devm_thermal_of_zone_match, tz)); 1506 } 1507 EXPORT_SYMBOL_GPL(devm_thermal_of_zone_unregister); 1508 1509 /** 1510 * of_parse_thermal_zones - parse device tree thermal data 1511 * 1512 * Initialization function that can be called by machine initialization 1513 * code to parse thermal data and populate the thermal framework 1514 * with hardware thermal zones info. This function only parses thermal zones. 1515 * Cooling devices and sensor devices nodes are supposed to be parsed 1516 * by their respective drivers. 1517 * 1518 * Return: 0 on success, proper error code otherwise 1519 * 1520 */ 1521 int __init of_parse_thermal_zones(void) 1522 { 1523 struct device_node *np, *child; 1524 struct __thermal_zone *tz; 1525 struct thermal_zone_device_ops *ops; 1526 1527 np = of_find_node_by_name(NULL, "thermal-zones"); 1528 if (!np) { 1529 pr_debug("unable to find thermal zones\n"); 1530 return 0; /* Run successfully on systems without thermal DT */ 1531 } 1532 1533 for_each_available_child_of_node(np, child) { 1534 struct thermal_zone_device *zone; 1535 struct thermal_zone_params *tzp; 1536 int i, mask = 0; 1537 u32 prop; 1538 1539 tz = thermal_of_build_thermal_zone(child); 1540 if (IS_ERR(tz)) { 1541 pr_err("failed to build thermal zone %pOFn: %ld\n", 1542 child, 1543 PTR_ERR(tz)); 1544 continue; 1545 } 1546 1547 ops = kmemdup(&of_thermal_ops, sizeof(*ops), GFP_KERNEL); 1548 if (!ops) 1549 goto exit_free; 1550 1551 tzp = kzalloc(sizeof(*tzp), GFP_KERNEL); 1552 if (!tzp) { 1553 kfree(ops); 1554 goto exit_free; 1555 } 1556 1557 /* No hwmon because there might be hwmon drivers registering */ 1558 tzp->no_hwmon = true; 1559 1560 if (!of_property_read_u32(child, "sustainable-power", &prop)) 1561 tzp->sustainable_power = prop; 1562 1563 for (i = 0; i < tz->ntrips; i++) 1564 mask |= 1 << i; 1565 1566 /* these two are left for temperature drivers to use */ 1567 tzp->slope = tz->slope; 1568 tzp->offset = tz->offset; 1569 1570 zone = thermal_zone_device_register_with_trips(child->name, tz->trips, tz->ntrips, 1571 mask, tz, ops, tzp, tz->passive_delay, 1572 tz->polling_delay); 1573 if (IS_ERR(zone)) { 1574 pr_err("Failed to build %pOFn zone %ld\n", child, 1575 PTR_ERR(zone)); 1576 kfree(tzp); 1577 kfree(ops); 1578 of_thermal_free_zone(tz); 1579 /* attempting to build remaining zones still */ 1580 } 1581 } 1582 of_node_put(np); 1583 1584 return 0; 1585 1586 exit_free: 1587 of_node_put(child); 1588 of_node_put(np); 1589 of_thermal_free_zone(tz); 1590 1591 /* no memory available, so free what we have built */ 1592 of_thermal_destroy_zones(); 1593 1594 return -ENOMEM; 1595 } 1596