1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * thermal.c - sysfs interface of thermal devices 4 * 5 * Copyright (C) 2016 Eduardo Valentin <edubezval@gmail.com> 6 * 7 * Highly based on original thermal_core.c 8 * Copyright (C) 2008 Intel Corp 9 * Copyright (C) 2008 Zhang Rui <rui.zhang@intel.com> 10 * Copyright (C) 2008 Sujith Thomas <sujith.thomas@intel.com> 11 */ 12 13 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 14 15 #include <linux/container_of.h> 16 #include <linux/sysfs.h> 17 #include <linux/device.h> 18 #include <linux/err.h> 19 #include <linux/slab.h> 20 #include <linux/string.h> 21 #include <linux/jiffies.h> 22 23 #include "thermal_core.h" 24 25 /* sys I/F for thermal zone */ 26 27 static ssize_t 28 type_show(struct device *dev, struct device_attribute *attr, char *buf) 29 { 30 struct thermal_zone_device *tz = to_thermal_zone(dev); 31 32 return sprintf(buf, "%s\n", tz->type); 33 } 34 35 static ssize_t 36 temp_show(struct device *dev, struct device_attribute *attr, char *buf) 37 { 38 struct thermal_zone_device *tz = to_thermal_zone(dev); 39 int temperature, ret; 40 41 ret = thermal_zone_get_temp(tz, &temperature); 42 43 if (ret) 44 return ret; 45 46 return sprintf(buf, "%d\n", temperature); 47 } 48 49 static ssize_t 50 mode_show(struct device *dev, struct device_attribute *attr, char *buf) 51 { 52 struct thermal_zone_device *tz = to_thermal_zone(dev); 53 54 guard(thermal_zone)(tz); 55 56 if (tz->mode == THERMAL_DEVICE_ENABLED) 57 return sprintf(buf, "enabled\n"); 58 59 return sprintf(buf, "disabled\n"); 60 } 61 62 static ssize_t 63 mode_store(struct device *dev, struct device_attribute *attr, 64 const char *buf, size_t count) 65 { 66 struct thermal_zone_device *tz = to_thermal_zone(dev); 67 int result; 68 69 if (!strncmp(buf, "enabled", sizeof("enabled") - 1)) 70 result = thermal_zone_device_enable(tz); 71 else if (!strncmp(buf, "disabled", sizeof("disabled") - 1)) 72 result = thermal_zone_device_disable(tz); 73 else 74 result = -EINVAL; 75 76 if (result) 77 return result; 78 79 return count; 80 } 81 82 #define thermal_trip_of_attr(_ptr_, _attr_) \ 83 ({ \ 84 struct thermal_trip_desc *td; \ 85 \ 86 td = container_of(_ptr_, struct thermal_trip_desc, \ 87 trip_attrs._attr_.attr); \ 88 &td->trip; \ 89 }) 90 91 static ssize_t 92 trip_point_type_show(struct device *dev, struct device_attribute *attr, 93 char *buf) 94 { 95 struct thermal_trip *trip = thermal_trip_of_attr(attr, type); 96 97 return sprintf(buf, "%s\n", thermal_trip_type_name(trip->type)); 98 } 99 100 static ssize_t 101 trip_point_temp_store(struct device *dev, struct device_attribute *attr, 102 const char *buf, size_t count) 103 { 104 struct thermal_trip *trip = thermal_trip_of_attr(attr, temp); 105 struct thermal_zone_device *tz = to_thermal_zone(dev); 106 int temp; 107 108 if (kstrtoint(buf, 10, &temp)) 109 return -EINVAL; 110 111 guard(thermal_zone)(tz); 112 113 if (temp == trip->temperature) 114 return count; 115 116 /* Arrange the condition to avoid integer overflows. */ 117 if (temp != THERMAL_TEMP_INVALID && 118 temp <= trip->hysteresis + THERMAL_TEMP_INVALID) 119 return -EINVAL; 120 121 if (tz->ops.set_trip_temp) { 122 int ret; 123 124 ret = tz->ops.set_trip_temp(tz, trip, temp); 125 if (ret) 126 return ret; 127 } 128 129 thermal_zone_set_trip_temp(tz, trip, temp); 130 131 __thermal_zone_device_update(tz, THERMAL_TRIP_CHANGED); 132 133 return count; 134 } 135 136 static ssize_t 137 trip_point_temp_show(struct device *dev, struct device_attribute *attr, 138 char *buf) 139 { 140 struct thermal_trip *trip = thermal_trip_of_attr(attr, temp); 141 142 return sprintf(buf, "%d\n", READ_ONCE(trip->temperature)); 143 } 144 145 static ssize_t 146 trip_point_hyst_store(struct device *dev, struct device_attribute *attr, 147 const char *buf, size_t count) 148 { 149 struct thermal_trip *trip = thermal_trip_of_attr(attr, hyst); 150 struct thermal_zone_device *tz = to_thermal_zone(dev); 151 int hyst; 152 153 if (kstrtoint(buf, 10, &hyst) || hyst < 0) 154 return -EINVAL; 155 156 guard(thermal_zone)(tz); 157 158 if (hyst == trip->hysteresis) 159 return count; 160 161 /* 162 * Allow the hysteresis to be updated when the temperature is invalid 163 * to allow user space to avoid having to adjust hysteresis after a 164 * valid temperature has been set, but in that case just change the 165 * value and do nothing else. 166 */ 167 if (trip->temperature == THERMAL_TEMP_INVALID) { 168 WRITE_ONCE(trip->hysteresis, hyst); 169 return count; 170 } 171 172 if (trip->temperature - hyst <= THERMAL_TEMP_INVALID) 173 return -EINVAL; 174 175 thermal_zone_set_trip_hyst(tz, trip, hyst); 176 177 __thermal_zone_device_update(tz, THERMAL_TRIP_CHANGED); 178 179 return count; 180 } 181 182 static ssize_t 183 trip_point_hyst_show(struct device *dev, struct device_attribute *attr, 184 char *buf) 185 { 186 struct thermal_trip *trip = thermal_trip_of_attr(attr, hyst); 187 188 return sprintf(buf, "%d\n", READ_ONCE(trip->hysteresis)); 189 } 190 191 static ssize_t 192 policy_store(struct device *dev, struct device_attribute *attr, 193 const char *buf, size_t count) 194 { 195 struct thermal_zone_device *tz = to_thermal_zone(dev); 196 char name[THERMAL_NAME_LENGTH]; 197 int ret; 198 199 snprintf(name, sizeof(name), "%s", buf); 200 201 ret = thermal_zone_device_set_policy(tz, name); 202 if (!ret) 203 ret = count; 204 205 return ret; 206 } 207 208 static ssize_t 209 policy_show(struct device *dev, struct device_attribute *devattr, char *buf) 210 { 211 struct thermal_zone_device *tz = to_thermal_zone(dev); 212 213 return sprintf(buf, "%s\n", tz->governor->name); 214 } 215 216 static ssize_t 217 available_policies_show(struct device *dev, struct device_attribute *devattr, 218 char *buf) 219 { 220 return thermal_build_list_of_policies(buf); 221 } 222 223 #if (IS_ENABLED(CONFIG_THERMAL_EMULATION)) 224 static ssize_t 225 emul_temp_store(struct device *dev, struct device_attribute *attr, 226 const char *buf, size_t count) 227 { 228 struct thermal_zone_device *tz = to_thermal_zone(dev); 229 int temperature; 230 231 if (kstrtoint(buf, 10, &temperature)) 232 return -EINVAL; 233 234 guard(thermal_zone)(tz); 235 236 if (tz->ops.set_emul_temp) { 237 int ret; 238 239 ret = tz->ops.set_emul_temp(tz, temperature); 240 if (ret) 241 return ret; 242 } else { 243 tz->emul_temperature = temperature; 244 } 245 246 __thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED); 247 248 return count; 249 } 250 static DEVICE_ATTR_WO(emul_temp); 251 #endif 252 253 static ssize_t 254 sustainable_power_show(struct device *dev, struct device_attribute *devattr, 255 char *buf) 256 { 257 struct thermal_zone_device *tz = to_thermal_zone(dev); 258 259 if (tz->tzp) 260 return sprintf(buf, "%u\n", tz->tzp->sustainable_power); 261 else 262 return -EIO; 263 } 264 265 static ssize_t 266 sustainable_power_store(struct device *dev, struct device_attribute *devattr, 267 const char *buf, size_t count) 268 { 269 struct thermal_zone_device *tz = to_thermal_zone(dev); 270 u32 sustainable_power; 271 272 if (!tz->tzp) 273 return -EIO; 274 275 if (kstrtou32(buf, 10, &sustainable_power)) 276 return -EINVAL; 277 278 tz->tzp->sustainable_power = sustainable_power; 279 280 return count; 281 } 282 283 #define create_s32_tzp_attr(name) \ 284 static ssize_t \ 285 name##_show(struct device *dev, struct device_attribute *devattr, \ 286 char *buf) \ 287 { \ 288 struct thermal_zone_device *tz = to_thermal_zone(dev); \ 289 \ 290 if (tz->tzp) \ 291 return sprintf(buf, "%d\n", tz->tzp->name); \ 292 else \ 293 return -EIO; \ 294 } \ 295 \ 296 static ssize_t \ 297 name##_store(struct device *dev, struct device_attribute *devattr, \ 298 const char *buf, size_t count) \ 299 { \ 300 struct thermal_zone_device *tz = to_thermal_zone(dev); \ 301 s32 value; \ 302 \ 303 if (!tz->tzp) \ 304 return -EIO; \ 305 \ 306 if (kstrtos32(buf, 10, &value)) \ 307 return -EINVAL; \ 308 \ 309 tz->tzp->name = value; \ 310 \ 311 return count; \ 312 } \ 313 static DEVICE_ATTR_RW(name) 314 315 create_s32_tzp_attr(k_po); 316 create_s32_tzp_attr(k_pu); 317 create_s32_tzp_attr(k_i); 318 create_s32_tzp_attr(k_d); 319 create_s32_tzp_attr(integral_cutoff); 320 create_s32_tzp_attr(slope); 321 create_s32_tzp_attr(offset); 322 #undef create_s32_tzp_attr 323 324 /* 325 * These are thermal zone device attributes that will always be present. 326 * All the attributes created for tzp (create_s32_tzp_attr) also are always 327 * present on the sysfs interface. 328 */ 329 static DEVICE_ATTR_RO(type); 330 static DEVICE_ATTR_RO(temp); 331 static DEVICE_ATTR_RW(policy); 332 static DEVICE_ATTR_RO(available_policies); 333 static DEVICE_ATTR_RW(sustainable_power); 334 335 /* These thermal zone device attributes are created based on conditions */ 336 static DEVICE_ATTR_RW(mode); 337 338 /* These attributes are unconditionally added to a thermal zone */ 339 static struct attribute *thermal_zone_dev_attrs[] = { 340 &dev_attr_type.attr, 341 &dev_attr_temp.attr, 342 #if (IS_ENABLED(CONFIG_THERMAL_EMULATION)) 343 &dev_attr_emul_temp.attr, 344 #endif 345 &dev_attr_policy.attr, 346 &dev_attr_available_policies.attr, 347 &dev_attr_sustainable_power.attr, 348 &dev_attr_k_po.attr, 349 &dev_attr_k_pu.attr, 350 &dev_attr_k_i.attr, 351 &dev_attr_k_d.attr, 352 &dev_attr_integral_cutoff.attr, 353 &dev_attr_slope.attr, 354 &dev_attr_offset.attr, 355 NULL, 356 }; 357 358 static const struct attribute_group thermal_zone_attribute_group = { 359 .attrs = thermal_zone_dev_attrs, 360 }; 361 362 static struct attribute *thermal_zone_mode_attrs[] = { 363 &dev_attr_mode.attr, 364 NULL, 365 }; 366 367 static const struct attribute_group thermal_zone_mode_attribute_group = { 368 .attrs = thermal_zone_mode_attrs, 369 }; 370 371 static const struct attribute_group *thermal_zone_attribute_groups[] = { 372 &thermal_zone_attribute_group, 373 &thermal_zone_mode_attribute_group, 374 /* This is not NULL terminated as we create the group dynamically */ 375 }; 376 377 /** 378 * create_trip_attrs() - create attributes for trip points 379 * @tz: the thermal zone device 380 * 381 * helper function to instantiate sysfs entries for every trip 382 * point and its properties of a struct thermal_zone_device. 383 * 384 * Return: 0 on success, the proper error value otherwise. 385 */ 386 static int create_trip_attrs(struct thermal_zone_device *tz) 387 { 388 struct thermal_trip_desc *td; 389 struct attribute **attrs; 390 int i; 391 392 attrs = kcalloc(tz->num_trips * 3 + 1, sizeof(*attrs), GFP_KERNEL); 393 if (!attrs) 394 return -ENOMEM; 395 396 i = 0; 397 for_each_trip_desc(tz, td) { 398 struct thermal_trip_attrs *trip_attrs = &td->trip_attrs; 399 400 /* create trip type attribute */ 401 snprintf(trip_attrs->type.name, THERMAL_NAME_LENGTH, 402 "trip_point_%d_type", i); 403 404 sysfs_attr_init(&trip_attrs->type.attr.attr); 405 trip_attrs->type.attr.attr.name = trip_attrs->type.name; 406 trip_attrs->type.attr.attr.mode = S_IRUGO; 407 trip_attrs->type.attr.show = trip_point_type_show; 408 attrs[i] = &trip_attrs->type.attr.attr; 409 410 /* create trip temp attribute */ 411 snprintf(trip_attrs->temp.name, THERMAL_NAME_LENGTH, 412 "trip_point_%d_temp", i); 413 414 sysfs_attr_init(&trip_attrs->temp.attr.attr); 415 trip_attrs->temp.attr.attr.name = trip_attrs->temp.name; 416 trip_attrs->temp.attr.attr.mode = S_IRUGO; 417 trip_attrs->temp.attr.show = trip_point_temp_show; 418 if (td->trip.flags & THERMAL_TRIP_FLAG_RW_TEMP) { 419 trip_attrs->temp.attr.attr.mode |= S_IWUSR; 420 trip_attrs->temp.attr.store = trip_point_temp_store; 421 } 422 attrs[i + tz->num_trips] = &trip_attrs->temp.attr.attr; 423 424 snprintf(trip_attrs->hyst.name, THERMAL_NAME_LENGTH, 425 "trip_point_%d_hyst", i); 426 427 sysfs_attr_init(&trip_attrs->hyst.attr.attr); 428 trip_attrs->hyst.attr.attr.name = trip_attrs->hyst.name; 429 trip_attrs->hyst.attr.attr.mode = S_IRUGO; 430 trip_attrs->hyst.attr.show = trip_point_hyst_show; 431 if (td->trip.flags & THERMAL_TRIP_FLAG_RW_HYST) { 432 trip_attrs->hyst.attr.attr.mode |= S_IWUSR; 433 trip_attrs->hyst.attr.store = trip_point_hyst_store; 434 } 435 attrs[i + 2 * tz->num_trips] = &trip_attrs->hyst.attr.attr; 436 i++; 437 } 438 attrs[tz->num_trips * 3] = NULL; 439 440 tz->trips_attribute_group.attrs = attrs; 441 442 return 0; 443 } 444 445 /** 446 * destroy_trip_attrs() - destroy attributes for trip points 447 * @tz: the thermal zone device 448 * 449 * helper function to free resources allocated by create_trip_attrs() 450 */ 451 static void destroy_trip_attrs(struct thermal_zone_device *tz) 452 { 453 if (tz) 454 kfree(tz->trips_attribute_group.attrs); 455 } 456 457 int thermal_zone_create_device_groups(struct thermal_zone_device *tz) 458 { 459 const struct attribute_group **groups; 460 int i, size, result; 461 462 /* we need one extra for trips and the NULL to terminate the array */ 463 size = ARRAY_SIZE(thermal_zone_attribute_groups) + 2; 464 /* This also takes care of API requirement to be NULL terminated */ 465 groups = kcalloc(size, sizeof(*groups), GFP_KERNEL); 466 if (!groups) 467 return -ENOMEM; 468 469 for (i = 0; i < size - 2; i++) 470 groups[i] = thermal_zone_attribute_groups[i]; 471 472 if (tz->num_trips) { 473 result = create_trip_attrs(tz); 474 if (result) { 475 kfree(groups); 476 477 return result; 478 } 479 480 groups[size - 2] = &tz->trips_attribute_group; 481 } 482 483 tz->device.groups = groups; 484 485 return 0; 486 } 487 488 void thermal_zone_destroy_device_groups(struct thermal_zone_device *tz) 489 { 490 if (!tz) 491 return; 492 493 if (tz->num_trips) 494 destroy_trip_attrs(tz); 495 496 kfree(tz->device.groups); 497 } 498 499 /* sys I/F for cooling device */ 500 static ssize_t 501 cdev_type_show(struct device *dev, struct device_attribute *attr, char *buf) 502 { 503 struct thermal_cooling_device *cdev = to_cooling_device(dev); 504 505 return sprintf(buf, "%s\n", cdev->type); 506 } 507 508 static ssize_t max_state_show(struct device *dev, struct device_attribute *attr, 509 char *buf) 510 { 511 struct thermal_cooling_device *cdev = to_cooling_device(dev); 512 513 return sprintf(buf, "%ld\n", cdev->max_state); 514 } 515 516 static ssize_t cur_state_show(struct device *dev, struct device_attribute *attr, 517 char *buf) 518 { 519 struct thermal_cooling_device *cdev = to_cooling_device(dev); 520 unsigned long state; 521 int ret; 522 523 ret = cdev->ops->get_cur_state(cdev, &state); 524 if (ret) 525 return ret; 526 return sprintf(buf, "%ld\n", state); 527 } 528 529 static ssize_t 530 cur_state_store(struct device *dev, struct device_attribute *attr, 531 const char *buf, size_t count) 532 { 533 struct thermal_cooling_device *cdev = to_cooling_device(dev); 534 unsigned long state; 535 int result; 536 537 if (sscanf(buf, "%ld\n", &state) != 1) 538 return -EINVAL; 539 540 if ((long)state < 0) 541 return -EINVAL; 542 543 /* Requested state should be less than max_state + 1 */ 544 if (state > cdev->max_state) 545 return -EINVAL; 546 547 guard(cooling_dev)(cdev); 548 549 result = cdev->ops->set_cur_state(cdev, state); 550 if (result) 551 return result; 552 553 thermal_cooling_device_stats_update(cdev, state); 554 555 return count; 556 } 557 558 static struct device_attribute 559 dev_attr_cdev_type = __ATTR(type, 0444, cdev_type_show, NULL); 560 static DEVICE_ATTR_RO(max_state); 561 static DEVICE_ATTR_RW(cur_state); 562 563 static struct attribute *cooling_device_attrs[] = { 564 &dev_attr_cdev_type.attr, 565 &dev_attr_max_state.attr, 566 &dev_attr_cur_state.attr, 567 NULL, 568 }; 569 570 static const struct attribute_group cooling_device_attr_group = { 571 .attrs = cooling_device_attrs, 572 }; 573 574 static const struct attribute_group *cooling_device_attr_groups[] = { 575 &cooling_device_attr_group, 576 NULL, /* Space allocated for cooling_device_stats_attr_group */ 577 NULL, 578 }; 579 580 #ifdef CONFIG_THERMAL_STATISTICS 581 struct cooling_dev_stats { 582 spinlock_t lock; 583 unsigned int total_trans; 584 unsigned long state; 585 ktime_t last_time; 586 ktime_t *time_in_state; 587 unsigned int *trans_table; 588 }; 589 590 static void update_time_in_state(struct cooling_dev_stats *stats) 591 { 592 ktime_t now = ktime_get(), delta; 593 594 delta = ktime_sub(now, stats->last_time); 595 stats->time_in_state[stats->state] = 596 ktime_add(stats->time_in_state[stats->state], delta); 597 stats->last_time = now; 598 } 599 600 void thermal_cooling_device_stats_update(struct thermal_cooling_device *cdev, 601 unsigned long new_state) 602 { 603 struct cooling_dev_stats *stats = cdev->stats; 604 605 lockdep_assert_held(&cdev->lock); 606 607 if (!stats) 608 return; 609 610 spin_lock(&stats->lock); 611 612 if (stats->state == new_state) 613 goto unlock; 614 615 update_time_in_state(stats); 616 stats->trans_table[stats->state * (cdev->max_state + 1) + new_state]++; 617 stats->state = new_state; 618 stats->total_trans++; 619 620 unlock: 621 spin_unlock(&stats->lock); 622 } 623 624 static ssize_t total_trans_show(struct device *dev, 625 struct device_attribute *attr, char *buf) 626 { 627 struct thermal_cooling_device *cdev = to_cooling_device(dev); 628 struct cooling_dev_stats *stats; 629 int ret; 630 631 guard(cooling_dev)(cdev); 632 633 stats = cdev->stats; 634 if (!stats) 635 return 0; 636 637 spin_lock(&stats->lock); 638 ret = sprintf(buf, "%u\n", stats->total_trans); 639 spin_unlock(&stats->lock); 640 641 return ret; 642 } 643 644 static ssize_t 645 time_in_state_ms_show(struct device *dev, struct device_attribute *attr, 646 char *buf) 647 { 648 struct thermal_cooling_device *cdev = to_cooling_device(dev); 649 struct cooling_dev_stats *stats; 650 ssize_t len = 0; 651 int i; 652 653 guard(cooling_dev)(cdev); 654 655 stats = cdev->stats; 656 if (!stats) 657 return 0; 658 659 spin_lock(&stats->lock); 660 661 update_time_in_state(stats); 662 663 for (i = 0; i <= cdev->max_state; i++) { 664 len += sprintf(buf + len, "state%u\t%llu\n", i, 665 ktime_to_ms(stats->time_in_state[i])); 666 } 667 spin_unlock(&stats->lock); 668 669 return len; 670 } 671 672 static ssize_t 673 reset_store(struct device *dev, struct device_attribute *attr, const char *buf, 674 size_t count) 675 { 676 struct thermal_cooling_device *cdev = to_cooling_device(dev); 677 struct cooling_dev_stats *stats; 678 int i, states; 679 680 guard(cooling_dev)(cdev); 681 682 stats = cdev->stats; 683 if (!stats) 684 return count; 685 686 states = cdev->max_state + 1; 687 688 spin_lock(&stats->lock); 689 690 stats->total_trans = 0; 691 stats->last_time = ktime_get(); 692 memset(stats->trans_table, 0, 693 states * states * sizeof(*stats->trans_table)); 694 695 for (i = 0; i < states; i++) 696 stats->time_in_state[i] = ktime_set(0, 0); 697 698 spin_unlock(&stats->lock); 699 700 return count; 701 } 702 703 static ssize_t trans_table_show(struct device *dev, 704 struct device_attribute *attr, char *buf) 705 { 706 struct thermal_cooling_device *cdev = to_cooling_device(dev); 707 struct cooling_dev_stats *stats; 708 ssize_t len = 0; 709 int i, j; 710 711 guard(cooling_dev)(cdev); 712 713 stats = cdev->stats; 714 if (!stats) 715 return -ENODATA; 716 717 len += snprintf(buf + len, PAGE_SIZE - len, " From : To\n"); 718 len += snprintf(buf + len, PAGE_SIZE - len, " : "); 719 for (i = 0; i <= cdev->max_state; i++) { 720 if (len >= PAGE_SIZE) 721 break; 722 len += snprintf(buf + len, PAGE_SIZE - len, "state%2u ", i); 723 } 724 if (len >= PAGE_SIZE) 725 return PAGE_SIZE; 726 727 len += snprintf(buf + len, PAGE_SIZE - len, "\n"); 728 729 for (i = 0; i <= cdev->max_state; i++) { 730 if (len >= PAGE_SIZE) 731 break; 732 733 len += snprintf(buf + len, PAGE_SIZE - len, "state%2u:", i); 734 735 for (j = 0; j <= cdev->max_state; j++) { 736 if (len >= PAGE_SIZE) 737 break; 738 len += snprintf(buf + len, PAGE_SIZE - len, "%8u ", 739 stats->trans_table[i * (cdev->max_state + 1) + j]); 740 } 741 if (len >= PAGE_SIZE) 742 break; 743 len += snprintf(buf + len, PAGE_SIZE - len, "\n"); 744 } 745 746 if (len >= PAGE_SIZE) { 747 pr_warn_once("Thermal transition table exceeds PAGE_SIZE. Disabling\n"); 748 len = -EFBIG; 749 } 750 751 return len; 752 } 753 754 static DEVICE_ATTR_RO(total_trans); 755 static DEVICE_ATTR_RO(time_in_state_ms); 756 static DEVICE_ATTR_WO(reset); 757 static DEVICE_ATTR_RO(trans_table); 758 759 static struct attribute *cooling_device_stats_attrs[] = { 760 &dev_attr_total_trans.attr, 761 &dev_attr_time_in_state_ms.attr, 762 &dev_attr_reset.attr, 763 &dev_attr_trans_table.attr, 764 NULL 765 }; 766 767 static const struct attribute_group cooling_device_stats_attr_group = { 768 .attrs = cooling_device_stats_attrs, 769 .name = "stats" 770 }; 771 772 static void cooling_device_stats_setup(struct thermal_cooling_device *cdev) 773 { 774 const struct attribute_group *stats_attr_group = NULL; 775 struct cooling_dev_stats *stats; 776 /* Total number of states is highest state + 1 */ 777 unsigned long states = cdev->max_state + 1; 778 int var; 779 780 var = sizeof(*stats); 781 var += sizeof(*stats->time_in_state) * states; 782 var += sizeof(*stats->trans_table) * states * states; 783 784 stats = kzalloc(var, GFP_KERNEL); 785 if (!stats) 786 goto out; 787 788 stats->time_in_state = (ktime_t *)(stats + 1); 789 stats->trans_table = (unsigned int *)(stats->time_in_state + states); 790 cdev->stats = stats; 791 stats->last_time = ktime_get(); 792 793 spin_lock_init(&stats->lock); 794 795 stats_attr_group = &cooling_device_stats_attr_group; 796 797 out: 798 /* Fill the empty slot left in cooling_device_attr_groups */ 799 var = ARRAY_SIZE(cooling_device_attr_groups) - 2; 800 cooling_device_attr_groups[var] = stats_attr_group; 801 } 802 803 static void cooling_device_stats_destroy(struct thermal_cooling_device *cdev) 804 { 805 kfree(cdev->stats); 806 cdev->stats = NULL; 807 } 808 809 #else 810 811 static inline void 812 cooling_device_stats_setup(struct thermal_cooling_device *cdev) {} 813 static inline void 814 cooling_device_stats_destroy(struct thermal_cooling_device *cdev) {} 815 816 #endif /* CONFIG_THERMAL_STATISTICS */ 817 818 void thermal_cooling_device_setup_sysfs(struct thermal_cooling_device *cdev) 819 { 820 cooling_device_stats_setup(cdev); 821 cdev->device.groups = cooling_device_attr_groups; 822 } 823 824 void thermal_cooling_device_destroy_sysfs(struct thermal_cooling_device *cdev) 825 { 826 cooling_device_stats_destroy(cdev); 827 } 828 829 void thermal_cooling_device_stats_reinit(struct thermal_cooling_device *cdev) 830 { 831 lockdep_assert_held(&cdev->lock); 832 833 cooling_device_stats_destroy(cdev); 834 cooling_device_stats_setup(cdev); 835 } 836 837 /* these helper will be used only at the time of bindig */ 838 ssize_t 839 trip_point_show(struct device *dev, struct device_attribute *attr, char *buf) 840 { 841 struct thermal_zone_device *tz = to_thermal_zone(dev); 842 struct thermal_instance *instance; 843 844 instance = container_of(attr, struct thermal_instance, attr); 845 846 return sprintf(buf, "%d\n", thermal_zone_trip_id(tz, instance->trip)); 847 } 848 849 ssize_t 850 weight_show(struct device *dev, struct device_attribute *attr, char *buf) 851 { 852 struct thermal_instance *instance; 853 854 instance = container_of(attr, struct thermal_instance, weight_attr); 855 856 return sprintf(buf, "%d\n", instance->weight); 857 } 858 859 ssize_t weight_store(struct device *dev, struct device_attribute *attr, 860 const char *buf, size_t count) 861 { 862 struct thermal_zone_device *tz = to_thermal_zone(dev); 863 struct thermal_instance *instance; 864 int ret, weight; 865 866 ret = kstrtoint(buf, 0, &weight); 867 if (ret) 868 return ret; 869 870 instance = container_of(attr, struct thermal_instance, weight_attr); 871 872 /* Don't race with governors using the 'weight' value */ 873 guard(thermal_zone)(tz); 874 875 instance->weight = weight; 876 877 thermal_governor_update_tz(tz, THERMAL_INSTANCE_WEIGHT_CHANGED); 878 879 return count; 880 } 881