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