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