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/string_choices.h> 22 #include <linux/jiffies.h> 23 24 #include "thermal_core.h" 25 26 /* sys I/F for thermal zone */ 27 28 static ssize_t 29 type_show(struct device *dev, struct device_attribute *attr, char *buf) 30 { 31 struct thermal_zone_device *tz = to_thermal_zone(dev); 32 33 return sysfs_emit(buf, "%s\n", tz->type); 34 } 35 36 static ssize_t 37 temp_show(struct device *dev, struct device_attribute *attr, char *buf) 38 { 39 struct thermal_zone_device *tz = to_thermal_zone(dev); 40 int temperature, ret; 41 42 ret = thermal_zone_get_temp(tz, &temperature); 43 44 if (!ret) 45 return sysfs_emit(buf, "%d\n", temperature); 46 47 if (ret == -EAGAIN) 48 return -ENODATA; 49 50 return ret; 51 } 52 53 static ssize_t 54 mode_show(struct device *dev, struct device_attribute *attr, char *buf) 55 { 56 struct thermal_zone_device *tz = to_thermal_zone(dev); 57 58 guard(thermal_zone)(tz); 59 60 return sysfs_emit(buf, "%s\n", 61 str_enabled_disabled(tz->mode == THERMAL_DEVICE_ENABLED)); 62 } 63 64 static ssize_t 65 mode_store(struct device *dev, struct device_attribute *attr, 66 const char *buf, size_t count) 67 { 68 struct thermal_zone_device *tz = to_thermal_zone(dev); 69 int result; 70 71 if (!strncmp(buf, "enabled", sizeof("enabled") - 1)) 72 result = thermal_zone_device_enable(tz); 73 else if (!strncmp(buf, "disabled", sizeof("disabled") - 1)) 74 result = thermal_zone_device_disable(tz); 75 else 76 result = -EINVAL; 77 78 if (result) 79 return result; 80 81 return count; 82 } 83 84 #define thermal_trip_of_attr(_ptr_, _attr_) \ 85 ({ \ 86 struct thermal_trip_desc *td; \ 87 \ 88 td = container_of(_ptr_, struct thermal_trip_desc, \ 89 trip_attrs._attr_.attr); \ 90 &td->trip; \ 91 }) 92 93 static ssize_t 94 trip_point_type_show(struct device *dev, struct device_attribute *attr, 95 char *buf) 96 { 97 struct thermal_trip *trip = thermal_trip_of_attr(attr, type); 98 99 return sysfs_emit(buf, "%s\n", thermal_trip_type_name(trip->type)); 100 } 101 102 static ssize_t 103 trip_point_temp_store(struct device *dev, struct device_attribute *attr, 104 const char *buf, size_t count) 105 { 106 struct thermal_trip *trip = thermal_trip_of_attr(attr, temp); 107 struct thermal_zone_device *tz = to_thermal_zone(dev); 108 int temp; 109 110 if (kstrtoint(buf, 10, &temp)) 111 return -EINVAL; 112 113 guard(thermal_zone)(tz); 114 115 if (temp == trip->temperature) 116 return count; 117 118 /* Arrange the condition to avoid integer overflows. */ 119 if (temp != THERMAL_TEMP_INVALID && 120 temp <= trip->hysteresis + THERMAL_TEMP_INVALID) 121 return -EINVAL; 122 123 if (tz->ops.set_trip_temp) { 124 int ret; 125 126 ret = tz->ops.set_trip_temp(tz, trip, temp); 127 if (ret) 128 return ret; 129 } 130 131 thermal_zone_set_trip_temp(tz, trip, temp); 132 133 __thermal_zone_device_update(tz, THERMAL_TRIP_CHANGED); 134 135 return count; 136 } 137 138 static ssize_t 139 trip_point_temp_show(struct device *dev, struct device_attribute *attr, 140 char *buf) 141 { 142 struct thermal_trip *trip = thermal_trip_of_attr(attr, temp); 143 144 return sysfs_emit(buf, "%d\n", READ_ONCE(trip->temperature)); 145 } 146 147 static ssize_t 148 trip_point_hyst_store(struct device *dev, struct device_attribute *attr, 149 const char *buf, size_t count) 150 { 151 struct thermal_trip *trip = thermal_trip_of_attr(attr, hyst); 152 struct thermal_zone_device *tz = to_thermal_zone(dev); 153 int hyst; 154 155 if (kstrtoint(buf, 10, &hyst) || hyst < 0) 156 return -EINVAL; 157 158 guard(thermal_zone)(tz); 159 160 if (hyst == trip->hysteresis) 161 return count; 162 163 /* 164 * Allow the hysteresis to be updated when the temperature is invalid 165 * to allow user space to avoid having to adjust hysteresis after a 166 * valid temperature has been set, but in that case just change the 167 * value and do nothing else. 168 */ 169 if (trip->temperature == THERMAL_TEMP_INVALID) { 170 WRITE_ONCE(trip->hysteresis, hyst); 171 return count; 172 } 173 174 if (trip->temperature - hyst <= THERMAL_TEMP_INVALID) 175 return -EINVAL; 176 177 thermal_zone_set_trip_hyst(tz, trip, hyst); 178 179 __thermal_zone_device_update(tz, THERMAL_TRIP_CHANGED); 180 181 return count; 182 } 183 184 static ssize_t 185 trip_point_hyst_show(struct device *dev, struct device_attribute *attr, 186 char *buf) 187 { 188 struct thermal_trip *trip = thermal_trip_of_attr(attr, hyst); 189 190 return sysfs_emit(buf, "%d\n", READ_ONCE(trip->hysteresis)); 191 } 192 193 static ssize_t 194 policy_store(struct device *dev, struct device_attribute *attr, 195 const char *buf, size_t count) 196 { 197 struct thermal_zone_device *tz = to_thermal_zone(dev); 198 char name[THERMAL_NAME_LENGTH]; 199 int ret; 200 201 strscpy(name, buf); 202 203 ret = thermal_zone_device_set_policy(tz, name); 204 if (!ret) 205 ret = count; 206 207 return ret; 208 } 209 210 static ssize_t 211 policy_show(struct device *dev, struct device_attribute *devattr, char *buf) 212 { 213 struct thermal_zone_device *tz = to_thermal_zone(dev); 214 215 return sysfs_emit(buf, "%s\n", tz->governor->name); 216 } 217 218 static ssize_t 219 available_policies_show(struct device *dev, struct device_attribute *devattr, 220 char *buf) 221 { 222 return thermal_build_list_of_policies(buf); 223 } 224 225 #if (IS_ENABLED(CONFIG_THERMAL_EMULATION)) 226 static ssize_t 227 emul_temp_store(struct device *dev, struct device_attribute *attr, 228 const char *buf, size_t count) 229 { 230 struct thermal_zone_device *tz = to_thermal_zone(dev); 231 int temperature; 232 233 if (kstrtoint(buf, 10, &temperature)) 234 return -EINVAL; 235 236 guard(thermal_zone)(tz); 237 238 if (tz->ops.set_emul_temp) { 239 int ret; 240 241 ret = tz->ops.set_emul_temp(tz, temperature); 242 if (ret) 243 return ret; 244 } else { 245 tz->emul_temperature = temperature; 246 } 247 248 __thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED); 249 250 return count; 251 } 252 static DEVICE_ATTR_WO(emul_temp); 253 #endif 254 255 static ssize_t 256 sustainable_power_show(struct device *dev, struct device_attribute *devattr, 257 char *buf) 258 { 259 struct thermal_zone_device *tz = to_thermal_zone(dev); 260 261 if (tz->tzp) 262 return sysfs_emit(buf, "%u\n", tz->tzp->sustainable_power); 263 else 264 return -EIO; 265 } 266 267 static ssize_t 268 sustainable_power_store(struct device *dev, struct device_attribute *devattr, 269 const char *buf, size_t count) 270 { 271 struct thermal_zone_device *tz = to_thermal_zone(dev); 272 u32 sustainable_power; 273 274 if (!tz->tzp) 275 return -EIO; 276 277 if (kstrtou32(buf, 10, &sustainable_power)) 278 return -EINVAL; 279 280 tz->tzp->sustainable_power = sustainable_power; 281 282 return count; 283 } 284 285 #define create_s32_tzp_attr(name) \ 286 static ssize_t \ 287 name##_show(struct device *dev, struct device_attribute *devattr, \ 288 char *buf) \ 289 { \ 290 struct thermal_zone_device *tz = to_thermal_zone(dev); \ 291 \ 292 if (tz->tzp) \ 293 return sysfs_emit(buf, "%d\n", tz->tzp->name); \ 294 else \ 295 return -EIO; \ 296 } \ 297 \ 298 static ssize_t \ 299 name##_store(struct device *dev, struct device_attribute *devattr, \ 300 const char *buf, size_t count) \ 301 { \ 302 struct thermal_zone_device *tz = to_thermal_zone(dev); \ 303 s32 value; \ 304 \ 305 if (!tz->tzp) \ 306 return -EIO; \ 307 \ 308 if (kstrtos32(buf, 10, &value)) \ 309 return -EINVAL; \ 310 \ 311 tz->tzp->name = value; \ 312 \ 313 return count; \ 314 } \ 315 static DEVICE_ATTR_RW(name) 316 317 create_s32_tzp_attr(k_po); 318 create_s32_tzp_attr(k_pu); 319 create_s32_tzp_attr(k_i); 320 create_s32_tzp_attr(k_d); 321 create_s32_tzp_attr(integral_cutoff); 322 create_s32_tzp_attr(slope); 323 create_s32_tzp_attr(offset); 324 #undef create_s32_tzp_attr 325 326 /* 327 * These are thermal zone device attributes that will always be present. 328 * All the attributes created for tzp (create_s32_tzp_attr) also are always 329 * present on the sysfs interface. 330 */ 331 static DEVICE_ATTR_RO(type); 332 static DEVICE_ATTR_RO(temp); 333 static DEVICE_ATTR_RW(policy); 334 static DEVICE_ATTR_RO(available_policies); 335 static DEVICE_ATTR_RW(sustainable_power); 336 337 /* These thermal zone device attributes are created based on conditions */ 338 static DEVICE_ATTR_RW(mode); 339 340 /* These attributes are unconditionally added to a thermal zone */ 341 static struct attribute *thermal_zone_dev_attrs[] = { 342 &dev_attr_type.attr, 343 &dev_attr_temp.attr, 344 #if (IS_ENABLED(CONFIG_THERMAL_EMULATION)) 345 &dev_attr_emul_temp.attr, 346 #endif 347 &dev_attr_policy.attr, 348 &dev_attr_available_policies.attr, 349 &dev_attr_sustainable_power.attr, 350 &dev_attr_k_po.attr, 351 &dev_attr_k_pu.attr, 352 &dev_attr_k_i.attr, 353 &dev_attr_k_d.attr, 354 &dev_attr_integral_cutoff.attr, 355 &dev_attr_slope.attr, 356 &dev_attr_offset.attr, 357 NULL, 358 }; 359 360 static const struct attribute_group thermal_zone_attribute_group = { 361 .attrs = thermal_zone_dev_attrs, 362 }; 363 364 static struct attribute *thermal_zone_mode_attrs[] = { 365 &dev_attr_mode.attr, 366 NULL, 367 }; 368 369 static const struct attribute_group thermal_zone_mode_attribute_group = { 370 .attrs = thermal_zone_mode_attrs, 371 }; 372 373 static const struct attribute_group *thermal_zone_attribute_groups[] = { 374 &thermal_zone_attribute_group, 375 &thermal_zone_mode_attribute_group, 376 /* This is not NULL terminated as we create the group dynamically */ 377 }; 378 379 /** 380 * create_trip_attrs() - create attributes for trip points 381 * @tz: the thermal zone device 382 * 383 * helper function to instantiate sysfs entries for every trip 384 * point and its properties of a struct thermal_zone_device. 385 * 386 * Return: 0 on success, the proper error value otherwise. 387 */ 388 static int create_trip_attrs(struct thermal_zone_device *tz) 389 { 390 struct thermal_trip_desc *td; 391 struct attribute **attrs; 392 int i; 393 394 attrs = kzalloc_objs(*attrs, tz->num_trips * 3 + 1); 395 if (!attrs) 396 return -ENOMEM; 397 398 i = 0; 399 for_each_trip_desc(tz, td) { 400 struct thermal_trip_attrs *trip_attrs = &td->trip_attrs; 401 402 /* create trip type attribute */ 403 snprintf(trip_attrs->type.name, THERMAL_NAME_LENGTH, 404 "trip_point_%d_type", i); 405 406 sysfs_attr_init(&trip_attrs->type.attr.attr); 407 trip_attrs->type.attr.attr.name = trip_attrs->type.name; 408 trip_attrs->type.attr.attr.mode = S_IRUGO; 409 trip_attrs->type.attr.show = trip_point_type_show; 410 attrs[i] = &trip_attrs->type.attr.attr; 411 412 /* create trip temp attribute */ 413 snprintf(trip_attrs->temp.name, THERMAL_NAME_LENGTH, 414 "trip_point_%d_temp", i); 415 416 sysfs_attr_init(&trip_attrs->temp.attr.attr); 417 trip_attrs->temp.attr.attr.name = trip_attrs->temp.name; 418 trip_attrs->temp.attr.attr.mode = S_IRUGO; 419 trip_attrs->temp.attr.show = trip_point_temp_show; 420 if (td->trip.flags & THERMAL_TRIP_FLAG_RW_TEMP) { 421 trip_attrs->temp.attr.attr.mode |= S_IWUSR; 422 trip_attrs->temp.attr.store = trip_point_temp_store; 423 } 424 attrs[i + tz->num_trips] = &trip_attrs->temp.attr.attr; 425 426 snprintf(trip_attrs->hyst.name, THERMAL_NAME_LENGTH, 427 "trip_point_%d_hyst", i); 428 429 sysfs_attr_init(&trip_attrs->hyst.attr.attr); 430 trip_attrs->hyst.attr.attr.name = trip_attrs->hyst.name; 431 trip_attrs->hyst.attr.attr.mode = S_IRUGO; 432 trip_attrs->hyst.attr.show = trip_point_hyst_show; 433 if (td->trip.flags & THERMAL_TRIP_FLAG_RW_HYST) { 434 trip_attrs->hyst.attr.attr.mode |= S_IWUSR; 435 trip_attrs->hyst.attr.store = trip_point_hyst_store; 436 } 437 attrs[i + 2 * tz->num_trips] = &trip_attrs->hyst.attr.attr; 438 i++; 439 } 440 attrs[tz->num_trips * 3] = NULL; 441 442 tz->trips_attribute_group.attrs = attrs; 443 444 return 0; 445 } 446 447 /** 448 * destroy_trip_attrs() - destroy attributes for trip points 449 * @tz: the thermal zone device 450 * 451 * helper function to free resources allocated by create_trip_attrs() 452 */ 453 static void destroy_trip_attrs(struct thermal_zone_device *tz) 454 { 455 if (tz) 456 kfree(tz->trips_attribute_group.attrs); 457 } 458 459 int thermal_zone_create_device_groups(struct thermal_zone_device *tz) 460 { 461 const struct attribute_group **groups; 462 int i, size, result; 463 464 /* we need one extra for trips and the NULL to terminate the array */ 465 size = ARRAY_SIZE(thermal_zone_attribute_groups) + 2; 466 /* This also takes care of API requirement to be NULL terminated */ 467 groups = kzalloc_objs(*groups, size); 468 if (!groups) 469 return -ENOMEM; 470 471 for (i = 0; i < size - 2; i++) 472 groups[i] = thermal_zone_attribute_groups[i]; 473 474 if (tz->num_trips) { 475 result = create_trip_attrs(tz); 476 if (result) { 477 kfree(groups); 478 479 return result; 480 } 481 482 groups[size - 2] = &tz->trips_attribute_group; 483 } 484 485 tz->device.groups = groups; 486 487 return 0; 488 } 489 490 void thermal_zone_destroy_device_groups(struct thermal_zone_device *tz) 491 { 492 if (!tz) 493 return; 494 495 if (tz->num_trips) 496 destroy_trip_attrs(tz); 497 498 kfree(tz->device.groups); 499 } 500 501 /* sys I/F for cooling device */ 502 static ssize_t 503 cdev_type_show(struct device *dev, struct device_attribute *attr, char *buf) 504 { 505 struct thermal_cooling_device *cdev = to_cooling_device(dev); 506 507 return sysfs_emit(buf, "%s\n", cdev->type); 508 } 509 510 static ssize_t max_state_show(struct device *dev, struct device_attribute *attr, 511 char *buf) 512 { 513 struct thermal_cooling_device *cdev = to_cooling_device(dev); 514 515 return sysfs_emit(buf, "%ld\n", cdev->max_state); 516 } 517 518 static ssize_t cur_state_show(struct device *dev, struct device_attribute *attr, 519 char *buf) 520 { 521 struct thermal_cooling_device *cdev = to_cooling_device(dev); 522 unsigned long state; 523 int ret; 524 525 ret = cdev->ops->get_cur_state(cdev, &state); 526 if (ret) 527 return ret; 528 return sysfs_emit(buf, "%ld\n", state); 529 } 530 531 static ssize_t 532 cur_state_store(struct device *dev, struct device_attribute *attr, 533 const char *buf, size_t count) 534 { 535 struct thermal_cooling_device *cdev = to_cooling_device(dev); 536 unsigned long state; 537 int result; 538 539 result = kstrtoul(buf, 10, &state); 540 if (result < 0) 541 return result; 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 = sysfs_emit(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 += sysfs_emit_at(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 sysfs_emit(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 sysfs_emit(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