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 = thermal_zone_device_is_enabled(tz); 53 54 return sprintf(buf, "%s\n", enabled ? "enabled" : "disabled"); 55 } 56 57 static ssize_t 58 mode_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 77 static ssize_t 78 trip_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 109 static ssize_t 110 trip_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 148 static ssize_t 149 trip_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 170 static ssize_t 171 trip_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 200 static ssize_t 201 trip_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 219 static ssize_t 220 passive_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 253 static ssize_t 254 passive_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 262 static ssize_t 263 policy_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 279 static ssize_t 280 policy_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 287 static ssize_t 288 available_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)) 295 static ssize_t 296 emul_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 } 319 static DEVICE_ATTR_WO(emul_temp); 320 #endif 321 322 static ssize_t 323 sustainable_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 334 static ssize_t 335 sustainable_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 384 create_s32_tzp_attr(k_po); 385 create_s32_tzp_attr(k_pu); 386 create_s32_tzp_attr(k_i); 387 create_s32_tzp_attr(k_d); 388 create_s32_tzp_attr(integral_cutoff); 389 create_s32_tzp_attr(slope); 390 create_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 */ 398 static DEVICE_ATTR_RO(type); 399 static DEVICE_ATTR_RO(temp); 400 static DEVICE_ATTR_RW(policy); 401 static DEVICE_ATTR_RO(available_policies); 402 static DEVICE_ATTR_RW(sustainable_power); 403 404 /* These thermal zone device attributes are created based on conditions */ 405 static DEVICE_ATTR_RW(mode); 406 static DEVICE_ATTR_RW(passive); 407 408 /* These attributes are unconditionally added to a thermal zone */ 409 static 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 428 static const struct attribute_group thermal_zone_attribute_group = { 429 .attrs = thermal_zone_dev_attrs, 430 }; 431 432 static struct attribute *thermal_zone_mode_attrs[] = { 433 &dev_attr_mode.attr, 434 NULL, 435 }; 436 437 static const 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 */ 442 static struct attribute *thermal_zone_passive_attrs[] = { 443 &dev_attr_passive.attr, 444 NULL, 445 }; 446 447 static 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 471 static const struct attribute_group thermal_zone_passive_attribute_group = { 472 .attrs = thermal_zone_passive_attrs, 473 .is_visible = thermal_zone_passive_is_visible, 474 }; 475 476 static 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 */ 493 static 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 */ 595 static 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 607 int 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 639 void 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 */ 651 static ssize_t 652 cdev_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 659 static 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 672 static 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 685 static ssize_t 686 cur_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 709 static struct device_attribute 710 dev_attr_cdev_type = __ATTR(type, 0444, cdev_type_show, NULL); 711 static DEVICE_ATTR_RO(max_state); 712 static DEVICE_ATTR_RW(cur_state); 713 714 static 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 721 static const struct attribute_group cooling_device_attr_group = { 722 .attrs = cooling_device_attrs, 723 }; 724 725 static 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 732 struct 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 742 static 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 752 void 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 spin_lock(&stats->lock); 758 759 if (stats->state == new_state) 760 goto unlock; 761 762 update_time_in_state(stats); 763 stats->trans_table[stats->state * stats->max_states + new_state]++; 764 stats->state = new_state; 765 stats->total_trans++; 766 767 unlock: 768 spin_unlock(&stats->lock); 769 } 770 771 static ssize_t total_trans_show(struct device *dev, 772 struct device_attribute *attr, char *buf) 773 { 774 struct thermal_cooling_device *cdev = to_cooling_device(dev); 775 struct cooling_dev_stats *stats = cdev->stats; 776 int ret; 777 778 spin_lock(&stats->lock); 779 ret = sprintf(buf, "%u\n", stats->total_trans); 780 spin_unlock(&stats->lock); 781 782 return ret; 783 } 784 785 static ssize_t 786 time_in_state_ms_show(struct device *dev, struct device_attribute *attr, 787 char *buf) 788 { 789 struct thermal_cooling_device *cdev = to_cooling_device(dev); 790 struct cooling_dev_stats *stats = cdev->stats; 791 ssize_t len = 0; 792 int i; 793 794 spin_lock(&stats->lock); 795 update_time_in_state(stats); 796 797 for (i = 0; i < stats->max_states; i++) { 798 len += sprintf(buf + len, "state%u\t%llu\n", i, 799 ktime_to_ms(stats->time_in_state[i])); 800 } 801 spin_unlock(&stats->lock); 802 803 return len; 804 } 805 806 static ssize_t 807 reset_store(struct device *dev, struct device_attribute *attr, const char *buf, 808 size_t count) 809 { 810 struct thermal_cooling_device *cdev = to_cooling_device(dev); 811 struct cooling_dev_stats *stats = cdev->stats; 812 int i, states = stats->max_states; 813 814 spin_lock(&stats->lock); 815 816 stats->total_trans = 0; 817 stats->last_time = ktime_get(); 818 memset(stats->trans_table, 0, 819 states * states * sizeof(*stats->trans_table)); 820 821 for (i = 0; i < stats->max_states; i++) 822 stats->time_in_state[i] = ktime_set(0, 0); 823 824 spin_unlock(&stats->lock); 825 826 return count; 827 } 828 829 static ssize_t trans_table_show(struct device *dev, 830 struct device_attribute *attr, char *buf) 831 { 832 struct thermal_cooling_device *cdev = to_cooling_device(dev); 833 struct cooling_dev_stats *stats = cdev->stats; 834 ssize_t len = 0; 835 int i, j; 836 837 len += snprintf(buf + len, PAGE_SIZE - len, " From : To\n"); 838 len += snprintf(buf + len, PAGE_SIZE - len, " : "); 839 for (i = 0; i < stats->max_states; i++) { 840 if (len >= PAGE_SIZE) 841 break; 842 len += snprintf(buf + len, PAGE_SIZE - len, "state%2u ", i); 843 } 844 if (len >= PAGE_SIZE) 845 return PAGE_SIZE; 846 847 len += snprintf(buf + len, PAGE_SIZE - len, "\n"); 848 849 for (i = 0; i < stats->max_states; i++) { 850 if (len >= PAGE_SIZE) 851 break; 852 853 len += snprintf(buf + len, PAGE_SIZE - len, "state%2u:", i); 854 855 for (j = 0; j < stats->max_states; j++) { 856 if (len >= PAGE_SIZE) 857 break; 858 len += snprintf(buf + len, PAGE_SIZE - len, "%8u ", 859 stats->trans_table[i * stats->max_states + j]); 860 } 861 if (len >= PAGE_SIZE) 862 break; 863 len += snprintf(buf + len, PAGE_SIZE - len, "\n"); 864 } 865 866 if (len >= PAGE_SIZE) { 867 pr_warn_once("Thermal transition table exceeds PAGE_SIZE. Disabling\n"); 868 return -EFBIG; 869 } 870 return len; 871 } 872 873 static DEVICE_ATTR_RO(total_trans); 874 static DEVICE_ATTR_RO(time_in_state_ms); 875 static DEVICE_ATTR_WO(reset); 876 static DEVICE_ATTR_RO(trans_table); 877 878 static struct attribute *cooling_device_stats_attrs[] = { 879 &dev_attr_total_trans.attr, 880 &dev_attr_time_in_state_ms.attr, 881 &dev_attr_reset.attr, 882 &dev_attr_trans_table.attr, 883 NULL 884 }; 885 886 static const struct attribute_group cooling_device_stats_attr_group = { 887 .attrs = cooling_device_stats_attrs, 888 .name = "stats" 889 }; 890 891 static void cooling_device_stats_setup(struct thermal_cooling_device *cdev) 892 { 893 struct cooling_dev_stats *stats; 894 unsigned long states; 895 int var; 896 897 if (cdev->ops->get_max_state(cdev, &states)) 898 return; 899 900 states++; /* Total number of states is highest state + 1 */ 901 902 var = sizeof(*stats); 903 var += sizeof(*stats->time_in_state) * states; 904 var += sizeof(*stats->trans_table) * states * states; 905 906 stats = kzalloc(var, GFP_KERNEL); 907 if (!stats) 908 return; 909 910 stats->time_in_state = (ktime_t *)(stats + 1); 911 stats->trans_table = (unsigned int *)(stats->time_in_state + states); 912 cdev->stats = stats; 913 stats->last_time = ktime_get(); 914 stats->max_states = states; 915 916 spin_lock_init(&stats->lock); 917 918 /* Fill the empty slot left in cooling_device_attr_groups */ 919 var = ARRAY_SIZE(cooling_device_attr_groups) - 2; 920 cooling_device_attr_groups[var] = &cooling_device_stats_attr_group; 921 } 922 923 static void cooling_device_stats_destroy(struct thermal_cooling_device *cdev) 924 { 925 kfree(cdev->stats); 926 cdev->stats = NULL; 927 } 928 929 #else 930 931 static inline void 932 cooling_device_stats_setup(struct thermal_cooling_device *cdev) {} 933 static inline void 934 cooling_device_stats_destroy(struct thermal_cooling_device *cdev) {} 935 936 #endif /* CONFIG_THERMAL_STATISTICS */ 937 938 void thermal_cooling_device_setup_sysfs(struct thermal_cooling_device *cdev) 939 { 940 cooling_device_stats_setup(cdev); 941 cdev->device.groups = cooling_device_attr_groups; 942 } 943 944 void thermal_cooling_device_destroy_sysfs(struct thermal_cooling_device *cdev) 945 { 946 cooling_device_stats_destroy(cdev); 947 } 948 949 /* these helper will be used only at the time of bindig */ 950 ssize_t 951 trip_point_show(struct device *dev, struct device_attribute *attr, char *buf) 952 { 953 struct thermal_instance *instance; 954 955 instance = 956 container_of(attr, struct thermal_instance, attr); 957 958 if (instance->trip == THERMAL_TRIPS_NONE) 959 return sprintf(buf, "-1\n"); 960 else 961 return sprintf(buf, "%d\n", instance->trip); 962 } 963 964 ssize_t 965 weight_show(struct device *dev, struct device_attribute *attr, char *buf) 966 { 967 struct thermal_instance *instance; 968 969 instance = container_of(attr, struct thermal_instance, weight_attr); 970 971 return sprintf(buf, "%d\n", instance->weight); 972 } 973 974 ssize_t weight_store(struct device *dev, struct device_attribute *attr, 975 const char *buf, size_t count) 976 { 977 struct thermal_instance *instance; 978 int ret, weight; 979 980 ret = kstrtoint(buf, 0, &weight); 981 if (ret) 982 return ret; 983 984 instance = container_of(attr, struct thermal_instance, weight_attr); 985 instance->weight = weight; 986 987 return count; 988 } 989