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