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