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