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 if (sscanf(buf, "%ld\n", &state) != 1) 540 return -EINVAL; 541 542 if ((long)state < 0) 543 return -EINVAL; 544 545 /* Requested state should be less than max_state + 1 */ 546 if (state > cdev->max_state) 547 return -EINVAL; 548 549 guard(cooling_dev)(cdev); 550 551 result = cdev->ops->set_cur_state(cdev, state); 552 if (result) 553 return result; 554 555 thermal_cooling_device_stats_update(cdev, state); 556 557 return count; 558 } 559 560 static struct device_attribute 561 dev_attr_cdev_type = __ATTR(type, 0444, cdev_type_show, NULL); 562 static DEVICE_ATTR_RO(max_state); 563 static DEVICE_ATTR_RW(cur_state); 564 565 static struct attribute *cooling_device_attrs[] = { 566 &dev_attr_cdev_type.attr, 567 &dev_attr_max_state.attr, 568 &dev_attr_cur_state.attr, 569 NULL, 570 }; 571 572 static const struct attribute_group cooling_device_attr_group = { 573 .attrs = cooling_device_attrs, 574 }; 575 576 static const struct attribute_group *cooling_device_attr_groups[] = { 577 &cooling_device_attr_group, 578 NULL, /* Space allocated for cooling_device_stats_attr_group */ 579 NULL, 580 }; 581 582 #ifdef CONFIG_THERMAL_STATISTICS 583 struct cooling_dev_stats { 584 spinlock_t lock; 585 unsigned int total_trans; 586 unsigned long state; 587 ktime_t last_time; 588 ktime_t *time_in_state; 589 unsigned int *trans_table; 590 }; 591 592 static void update_time_in_state(struct cooling_dev_stats *stats) 593 { 594 ktime_t now = ktime_get(), delta; 595 596 delta = ktime_sub(now, stats->last_time); 597 stats->time_in_state[stats->state] = 598 ktime_add(stats->time_in_state[stats->state], delta); 599 stats->last_time = now; 600 } 601 602 void thermal_cooling_device_stats_update(struct thermal_cooling_device *cdev, 603 unsigned long new_state) 604 { 605 struct cooling_dev_stats *stats = cdev->stats; 606 607 lockdep_assert_held(&cdev->lock); 608 609 if (!stats) 610 return; 611 612 spin_lock(&stats->lock); 613 614 if (stats->state == new_state) 615 goto unlock; 616 617 update_time_in_state(stats); 618 stats->trans_table[stats->state * (cdev->max_state + 1) + new_state]++; 619 stats->state = new_state; 620 stats->total_trans++; 621 622 unlock: 623 spin_unlock(&stats->lock); 624 } 625 626 static ssize_t total_trans_show(struct device *dev, 627 struct device_attribute *attr, char *buf) 628 { 629 struct thermal_cooling_device *cdev = to_cooling_device(dev); 630 struct cooling_dev_stats *stats; 631 int ret; 632 633 guard(cooling_dev)(cdev); 634 635 stats = cdev->stats; 636 if (!stats) 637 return 0; 638 639 spin_lock(&stats->lock); 640 ret = sysfs_emit(buf, "%u\n", stats->total_trans); 641 spin_unlock(&stats->lock); 642 643 return ret; 644 } 645 646 static ssize_t 647 time_in_state_ms_show(struct device *dev, struct device_attribute *attr, 648 char *buf) 649 { 650 struct thermal_cooling_device *cdev = to_cooling_device(dev); 651 struct cooling_dev_stats *stats; 652 ssize_t len = 0; 653 int i; 654 655 guard(cooling_dev)(cdev); 656 657 stats = cdev->stats; 658 if (!stats) 659 return 0; 660 661 spin_lock(&stats->lock); 662 663 update_time_in_state(stats); 664 665 for (i = 0; i <= cdev->max_state; i++) { 666 len += sysfs_emit_at(buf, len, "state%u\t%llu\n", i, 667 ktime_to_ms(stats->time_in_state[i])); 668 } 669 spin_unlock(&stats->lock); 670 671 return len; 672 } 673 674 static ssize_t 675 reset_store(struct device *dev, struct device_attribute *attr, const char *buf, 676 size_t count) 677 { 678 struct thermal_cooling_device *cdev = to_cooling_device(dev); 679 struct cooling_dev_stats *stats; 680 int i, states; 681 682 guard(cooling_dev)(cdev); 683 684 stats = cdev->stats; 685 if (!stats) 686 return count; 687 688 states = cdev->max_state + 1; 689 690 spin_lock(&stats->lock); 691 692 stats->total_trans = 0; 693 stats->last_time = ktime_get(); 694 memset(stats->trans_table, 0, 695 states * states * sizeof(*stats->trans_table)); 696 697 for (i = 0; i < states; i++) 698 stats->time_in_state[i] = ktime_set(0, 0); 699 700 spin_unlock(&stats->lock); 701 702 return count; 703 } 704 705 static ssize_t trans_table_show(struct device *dev, 706 struct device_attribute *attr, char *buf) 707 { 708 struct thermal_cooling_device *cdev = to_cooling_device(dev); 709 struct cooling_dev_stats *stats; 710 ssize_t len = 0; 711 int i, j; 712 713 guard(cooling_dev)(cdev); 714 715 stats = cdev->stats; 716 if (!stats) 717 return -ENODATA; 718 719 len += snprintf(buf + len, PAGE_SIZE - len, " From : To\n"); 720 len += snprintf(buf + len, PAGE_SIZE - len, " : "); 721 for (i = 0; i <= cdev->max_state; i++) { 722 if (len >= PAGE_SIZE) 723 break; 724 len += snprintf(buf + len, PAGE_SIZE - len, "state%2u ", i); 725 } 726 if (len >= PAGE_SIZE) 727 return PAGE_SIZE; 728 729 len += snprintf(buf + len, PAGE_SIZE - len, "\n"); 730 731 for (i = 0; i <= cdev->max_state; i++) { 732 if (len >= PAGE_SIZE) 733 break; 734 735 len += snprintf(buf + len, PAGE_SIZE - len, "state%2u:", i); 736 737 for (j = 0; j <= cdev->max_state; j++) { 738 if (len >= PAGE_SIZE) 739 break; 740 len += snprintf(buf + len, PAGE_SIZE - len, "%8u ", 741 stats->trans_table[i * (cdev->max_state + 1) + j]); 742 } 743 if (len >= PAGE_SIZE) 744 break; 745 len += snprintf(buf + len, PAGE_SIZE - len, "\n"); 746 } 747 748 if (len >= PAGE_SIZE) { 749 pr_warn_once("Thermal transition table exceeds PAGE_SIZE. Disabling\n"); 750 len = -EFBIG; 751 } 752 753 return len; 754 } 755 756 static DEVICE_ATTR_RO(total_trans); 757 static DEVICE_ATTR_RO(time_in_state_ms); 758 static DEVICE_ATTR_WO(reset); 759 static DEVICE_ATTR_RO(trans_table); 760 761 static struct attribute *cooling_device_stats_attrs[] = { 762 &dev_attr_total_trans.attr, 763 &dev_attr_time_in_state_ms.attr, 764 &dev_attr_reset.attr, 765 &dev_attr_trans_table.attr, 766 NULL 767 }; 768 769 static const struct attribute_group cooling_device_stats_attr_group = { 770 .attrs = cooling_device_stats_attrs, 771 .name = "stats" 772 }; 773 774 static void cooling_device_stats_setup(struct thermal_cooling_device *cdev) 775 { 776 const struct attribute_group *stats_attr_group = NULL; 777 struct cooling_dev_stats *stats; 778 /* Total number of states is highest state + 1 */ 779 unsigned long states = cdev->max_state + 1; 780 int var; 781 782 var = sizeof(*stats); 783 var += sizeof(*stats->time_in_state) * states; 784 var += sizeof(*stats->trans_table) * states * states; 785 786 stats = kzalloc(var, GFP_KERNEL); 787 if (!stats) 788 goto out; 789 790 stats->time_in_state = (ktime_t *)(stats + 1); 791 stats->trans_table = (unsigned int *)(stats->time_in_state + states); 792 cdev->stats = stats; 793 stats->last_time = ktime_get(); 794 795 spin_lock_init(&stats->lock); 796 797 stats_attr_group = &cooling_device_stats_attr_group; 798 799 out: 800 /* Fill the empty slot left in cooling_device_attr_groups */ 801 var = ARRAY_SIZE(cooling_device_attr_groups) - 2; 802 cooling_device_attr_groups[var] = stats_attr_group; 803 } 804 805 static void cooling_device_stats_destroy(struct thermal_cooling_device *cdev) 806 { 807 kfree(cdev->stats); 808 cdev->stats = NULL; 809 } 810 811 #else 812 813 static inline void 814 cooling_device_stats_setup(struct thermal_cooling_device *cdev) {} 815 static inline void 816 cooling_device_stats_destroy(struct thermal_cooling_device *cdev) {} 817 818 #endif /* CONFIG_THERMAL_STATISTICS */ 819 820 void thermal_cooling_device_setup_sysfs(struct thermal_cooling_device *cdev) 821 { 822 cooling_device_stats_setup(cdev); 823 cdev->device.groups = cooling_device_attr_groups; 824 } 825 826 void thermal_cooling_device_destroy_sysfs(struct thermal_cooling_device *cdev) 827 { 828 cooling_device_stats_destroy(cdev); 829 } 830 831 void thermal_cooling_device_stats_reinit(struct thermal_cooling_device *cdev) 832 { 833 lockdep_assert_held(&cdev->lock); 834 835 cooling_device_stats_destroy(cdev); 836 cooling_device_stats_setup(cdev); 837 } 838 839 /* these helper will be used only at the time of bindig */ 840 ssize_t 841 trip_point_show(struct device *dev, struct device_attribute *attr, char *buf) 842 { 843 struct thermal_zone_device *tz = to_thermal_zone(dev); 844 struct thermal_instance *instance; 845 846 instance = container_of(attr, struct thermal_instance, attr); 847 848 return sysfs_emit(buf, "%d\n", thermal_zone_trip_id(tz, instance->trip)); 849 } 850 851 ssize_t 852 weight_show(struct device *dev, struct device_attribute *attr, char *buf) 853 { 854 struct thermal_instance *instance; 855 856 instance = container_of(attr, struct thermal_instance, weight_attr); 857 858 return sysfs_emit(buf, "%d\n", instance->weight); 859 } 860 861 ssize_t weight_store(struct device *dev, struct device_attribute *attr, 862 const char *buf, size_t count) 863 { 864 struct thermal_zone_device *tz = to_thermal_zone(dev); 865 struct thermal_instance *instance; 866 int ret, weight; 867 868 ret = kstrtoint(buf, 0, &weight); 869 if (ret) 870 return ret; 871 872 instance = container_of(attr, struct thermal_instance, weight_attr); 873 874 /* Don't race with governors using the 'weight' value */ 875 guard(thermal_zone)(tz); 876 877 instance->weight = weight; 878 879 thermal_governor_update_tz(tz, THERMAL_INSTANCE_WEIGHT_CHANGED); 880 881 return count; 882 } 883