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