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