Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at 55fa6091d83160ca772fc37cebae45d42695a708 1337 lines 35 kB view raw
1/* 2 * thermal.c - Generic Thermal Management Sysfs support. 3 * 4 * Copyright (C) 2008 Intel Corp 5 * Copyright (C) 2008 Zhang Rui <rui.zhang@intel.com> 6 * Copyright (C) 2008 Sujith Thomas <sujith.thomas@intel.com> 7 * 8 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License as published by 12 * the Free Software Foundation; version 2 of the License. 13 * 14 * This program is distributed in the hope that it will be useful, but 15 * WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 * General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License along 20 * with this program; if not, write to the Free Software Foundation, Inc., 21 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 22 * 23 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 24 */ 25 26#include <linux/module.h> 27#include <linux/device.h> 28#include <linux/err.h> 29#include <linux/slab.h> 30#include <linux/kdev_t.h> 31#include <linux/idr.h> 32#include <linux/thermal.h> 33#include <linux/spinlock.h> 34#include <linux/reboot.h> 35#include <net/netlink.h> 36#include <net/genetlink.h> 37 38MODULE_AUTHOR("Zhang Rui"); 39MODULE_DESCRIPTION("Generic thermal management sysfs support"); 40MODULE_LICENSE("GPL"); 41 42#define PREFIX "Thermal: " 43 44struct thermal_cooling_device_instance { 45 int id; 46 char name[THERMAL_NAME_LENGTH]; 47 struct thermal_zone_device *tz; 48 struct thermal_cooling_device *cdev; 49 int trip; 50 char attr_name[THERMAL_NAME_LENGTH]; 51 struct device_attribute attr; 52 struct list_head node; 53}; 54 55static DEFINE_IDR(thermal_tz_idr); 56static DEFINE_IDR(thermal_cdev_idr); 57static DEFINE_MUTEX(thermal_idr_lock); 58 59static LIST_HEAD(thermal_tz_list); 60static LIST_HEAD(thermal_cdev_list); 61static DEFINE_MUTEX(thermal_list_lock); 62 63static unsigned int thermal_event_seqnum; 64 65static int get_idr(struct idr *idr, struct mutex *lock, int *id) 66{ 67 int err; 68 69 again: 70 if (unlikely(idr_pre_get(idr, GFP_KERNEL) == 0)) 71 return -ENOMEM; 72 73 if (lock) 74 mutex_lock(lock); 75 err = idr_get_new(idr, NULL, id); 76 if (lock) 77 mutex_unlock(lock); 78 if (unlikely(err == -EAGAIN)) 79 goto again; 80 else if (unlikely(err)) 81 return err; 82 83 *id = *id & MAX_ID_MASK; 84 return 0; 85} 86 87static void release_idr(struct idr *idr, struct mutex *lock, int id) 88{ 89 if (lock) 90 mutex_lock(lock); 91 idr_remove(idr, id); 92 if (lock) 93 mutex_unlock(lock); 94} 95 96/* sys I/F for thermal zone */ 97 98#define to_thermal_zone(_dev) \ 99 container_of(_dev, struct thermal_zone_device, device) 100 101static ssize_t 102type_show(struct device *dev, struct device_attribute *attr, char *buf) 103{ 104 struct thermal_zone_device *tz = to_thermal_zone(dev); 105 106 return sprintf(buf, "%s\n", tz->type); 107} 108 109static ssize_t 110temp_show(struct device *dev, struct device_attribute *attr, char *buf) 111{ 112 struct thermal_zone_device *tz = to_thermal_zone(dev); 113 long temperature; 114 int ret; 115 116 if (!tz->ops->get_temp) 117 return -EPERM; 118 119 ret = tz->ops->get_temp(tz, &temperature); 120 121 if (ret) 122 return ret; 123 124 return sprintf(buf, "%ld\n", temperature); 125} 126 127static ssize_t 128mode_show(struct device *dev, struct device_attribute *attr, char *buf) 129{ 130 struct thermal_zone_device *tz = to_thermal_zone(dev); 131 enum thermal_device_mode mode; 132 int result; 133 134 if (!tz->ops->get_mode) 135 return -EPERM; 136 137 result = tz->ops->get_mode(tz, &mode); 138 if (result) 139 return result; 140 141 return sprintf(buf, "%s\n", mode == THERMAL_DEVICE_ENABLED ? "enabled" 142 : "disabled"); 143} 144 145static ssize_t 146mode_store(struct device *dev, struct device_attribute *attr, 147 const char *buf, size_t count) 148{ 149 struct thermal_zone_device *tz = to_thermal_zone(dev); 150 int result; 151 152 if (!tz->ops->set_mode) 153 return -EPERM; 154 155 if (!strncmp(buf, "enabled", sizeof("enabled"))) 156 result = tz->ops->set_mode(tz, THERMAL_DEVICE_ENABLED); 157 else if (!strncmp(buf, "disabled", sizeof("disabled"))) 158 result = tz->ops->set_mode(tz, THERMAL_DEVICE_DISABLED); 159 else 160 result = -EINVAL; 161 162 if (result) 163 return result; 164 165 return count; 166} 167 168static ssize_t 169trip_point_type_show(struct device *dev, struct device_attribute *attr, 170 char *buf) 171{ 172 struct thermal_zone_device *tz = to_thermal_zone(dev); 173 enum thermal_trip_type type; 174 int trip, result; 175 176 if (!tz->ops->get_trip_type) 177 return -EPERM; 178 179 if (!sscanf(attr->attr.name, "trip_point_%d_type", &trip)) 180 return -EINVAL; 181 182 result = tz->ops->get_trip_type(tz, trip, &type); 183 if (result) 184 return result; 185 186 switch (type) { 187 case THERMAL_TRIP_CRITICAL: 188 return sprintf(buf, "critical\n"); 189 case THERMAL_TRIP_HOT: 190 return sprintf(buf, "hot\n"); 191 case THERMAL_TRIP_PASSIVE: 192 return sprintf(buf, "passive\n"); 193 case THERMAL_TRIP_ACTIVE: 194 return sprintf(buf, "active\n"); 195 default: 196 return sprintf(buf, "unknown\n"); 197 } 198} 199 200static ssize_t 201trip_point_temp_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 long temperature; 207 208 if (!tz->ops->get_trip_temp) 209 return -EPERM; 210 211 if (!sscanf(attr->attr.name, "trip_point_%d_temp", &trip)) 212 return -EINVAL; 213 214 ret = tz->ops->get_trip_temp(tz, trip, &temperature); 215 216 if (ret) 217 return ret; 218 219 return sprintf(buf, "%ld\n", temperature); 220} 221 222static ssize_t 223passive_store(struct device *dev, struct device_attribute *attr, 224 const char *buf, size_t count) 225{ 226 struct thermal_zone_device *tz = to_thermal_zone(dev); 227 struct thermal_cooling_device *cdev = NULL; 228 int state; 229 230 if (!sscanf(buf, "%d\n", &state)) 231 return -EINVAL; 232 233 /* sanity check: values below 1000 millicelcius don't make sense 234 * and can cause the system to go into a thermal heart attack 235 */ 236 if (state && state < 1000) 237 return -EINVAL; 238 239 if (state && !tz->forced_passive) { 240 mutex_lock(&thermal_list_lock); 241 list_for_each_entry(cdev, &thermal_cdev_list, node) { 242 if (!strncmp("Processor", cdev->type, 243 sizeof("Processor"))) 244 thermal_zone_bind_cooling_device(tz, 245 THERMAL_TRIPS_NONE, 246 cdev); 247 } 248 mutex_unlock(&thermal_list_lock); 249 if (!tz->passive_delay) 250 tz->passive_delay = 1000; 251 } else if (!state && tz->forced_passive) { 252 mutex_lock(&thermal_list_lock); 253 list_for_each_entry(cdev, &thermal_cdev_list, node) { 254 if (!strncmp("Processor", cdev->type, 255 sizeof("Processor"))) 256 thermal_zone_unbind_cooling_device(tz, 257 THERMAL_TRIPS_NONE, 258 cdev); 259 } 260 mutex_unlock(&thermal_list_lock); 261 tz->passive_delay = 0; 262 } 263 264 tz->tc1 = 1; 265 tz->tc2 = 1; 266 267 tz->forced_passive = state; 268 269 thermal_zone_device_update(tz); 270 271 return count; 272} 273 274static ssize_t 275passive_show(struct device *dev, struct device_attribute *attr, 276 char *buf) 277{ 278 struct thermal_zone_device *tz = to_thermal_zone(dev); 279 280 return sprintf(buf, "%d\n", tz->forced_passive); 281} 282 283static DEVICE_ATTR(type, 0444, type_show, NULL); 284static DEVICE_ATTR(temp, 0444, temp_show, NULL); 285static DEVICE_ATTR(mode, 0644, mode_show, mode_store); 286static DEVICE_ATTR(passive, S_IRUGO | S_IWUSR, passive_show, \ 287 passive_store); 288 289static struct device_attribute trip_point_attrs[] = { 290 __ATTR(trip_point_0_type, 0444, trip_point_type_show, NULL), 291 __ATTR(trip_point_0_temp, 0444, trip_point_temp_show, NULL), 292 __ATTR(trip_point_1_type, 0444, trip_point_type_show, NULL), 293 __ATTR(trip_point_1_temp, 0444, trip_point_temp_show, NULL), 294 __ATTR(trip_point_2_type, 0444, trip_point_type_show, NULL), 295 __ATTR(trip_point_2_temp, 0444, trip_point_temp_show, NULL), 296 __ATTR(trip_point_3_type, 0444, trip_point_type_show, NULL), 297 __ATTR(trip_point_3_temp, 0444, trip_point_temp_show, NULL), 298 __ATTR(trip_point_4_type, 0444, trip_point_type_show, NULL), 299 __ATTR(trip_point_4_temp, 0444, trip_point_temp_show, NULL), 300 __ATTR(trip_point_5_type, 0444, trip_point_type_show, NULL), 301 __ATTR(trip_point_5_temp, 0444, trip_point_temp_show, NULL), 302 __ATTR(trip_point_6_type, 0444, trip_point_type_show, NULL), 303 __ATTR(trip_point_6_temp, 0444, trip_point_temp_show, NULL), 304 __ATTR(trip_point_7_type, 0444, trip_point_type_show, NULL), 305 __ATTR(trip_point_7_temp, 0444, trip_point_temp_show, NULL), 306 __ATTR(trip_point_8_type, 0444, trip_point_type_show, NULL), 307 __ATTR(trip_point_8_temp, 0444, trip_point_temp_show, NULL), 308 __ATTR(trip_point_9_type, 0444, trip_point_type_show, NULL), 309 __ATTR(trip_point_9_temp, 0444, trip_point_temp_show, NULL), 310 __ATTR(trip_point_10_type, 0444, trip_point_type_show, NULL), 311 __ATTR(trip_point_10_temp, 0444, trip_point_temp_show, NULL), 312 __ATTR(trip_point_11_type, 0444, trip_point_type_show, NULL), 313 __ATTR(trip_point_11_temp, 0444, trip_point_temp_show, NULL), 314}; 315 316#define TRIP_POINT_ATTR_ADD(_dev, _index, result) \ 317do { \ 318 result = device_create_file(_dev, \ 319 &trip_point_attrs[_index * 2]); \ 320 if (result) \ 321 break; \ 322 result = device_create_file(_dev, \ 323 &trip_point_attrs[_index * 2 + 1]); \ 324} while (0) 325 326#define TRIP_POINT_ATTR_REMOVE(_dev, _index) \ 327do { \ 328 device_remove_file(_dev, &trip_point_attrs[_index * 2]); \ 329 device_remove_file(_dev, &trip_point_attrs[_index * 2 + 1]); \ 330} while (0) 331 332/* sys I/F for cooling device */ 333#define to_cooling_device(_dev) \ 334 container_of(_dev, struct thermal_cooling_device, device) 335 336static ssize_t 337thermal_cooling_device_type_show(struct device *dev, 338 struct device_attribute *attr, char *buf) 339{ 340 struct thermal_cooling_device *cdev = to_cooling_device(dev); 341 342 return sprintf(buf, "%s\n", cdev->type); 343} 344 345static ssize_t 346thermal_cooling_device_max_state_show(struct device *dev, 347 struct device_attribute *attr, char *buf) 348{ 349 struct thermal_cooling_device *cdev = to_cooling_device(dev); 350 unsigned long state; 351 int ret; 352 353 ret = cdev->ops->get_max_state(cdev, &state); 354 if (ret) 355 return ret; 356 return sprintf(buf, "%ld\n", state); 357} 358 359static ssize_t 360thermal_cooling_device_cur_state_show(struct device *dev, 361 struct device_attribute *attr, char *buf) 362{ 363 struct thermal_cooling_device *cdev = to_cooling_device(dev); 364 unsigned long state; 365 int ret; 366 367 ret = cdev->ops->get_cur_state(cdev, &state); 368 if (ret) 369 return ret; 370 return sprintf(buf, "%ld\n", state); 371} 372 373static ssize_t 374thermal_cooling_device_cur_state_store(struct device *dev, 375 struct device_attribute *attr, 376 const char *buf, size_t count) 377{ 378 struct thermal_cooling_device *cdev = to_cooling_device(dev); 379 unsigned long state; 380 int result; 381 382 if (!sscanf(buf, "%ld\n", &state)) 383 return -EINVAL; 384 385 if ((long)state < 0) 386 return -EINVAL; 387 388 result = cdev->ops->set_cur_state(cdev, state); 389 if (result) 390 return result; 391 return count; 392} 393 394static struct device_attribute dev_attr_cdev_type = 395__ATTR(type, 0444, thermal_cooling_device_type_show, NULL); 396static DEVICE_ATTR(max_state, 0444, 397 thermal_cooling_device_max_state_show, NULL); 398static DEVICE_ATTR(cur_state, 0644, 399 thermal_cooling_device_cur_state_show, 400 thermal_cooling_device_cur_state_store); 401 402static ssize_t 403thermal_cooling_device_trip_point_show(struct device *dev, 404 struct device_attribute *attr, char *buf) 405{ 406 struct thermal_cooling_device_instance *instance; 407 408 instance = 409 container_of(attr, struct thermal_cooling_device_instance, attr); 410 411 if (instance->trip == THERMAL_TRIPS_NONE) 412 return sprintf(buf, "-1\n"); 413 else 414 return sprintf(buf, "%d\n", instance->trip); 415} 416 417/* Device management */ 418 419#if defined(CONFIG_THERMAL_HWMON) 420 421/* hwmon sys I/F */ 422#include <linux/hwmon.h> 423static LIST_HEAD(thermal_hwmon_list); 424 425static ssize_t 426name_show(struct device *dev, struct device_attribute *attr, char *buf) 427{ 428 struct thermal_hwmon_device *hwmon = dev_get_drvdata(dev); 429 return sprintf(buf, "%s\n", hwmon->type); 430} 431static DEVICE_ATTR(name, 0444, name_show, NULL); 432 433static ssize_t 434temp_input_show(struct device *dev, struct device_attribute *attr, char *buf) 435{ 436 long temperature; 437 int ret; 438 struct thermal_hwmon_attr *hwmon_attr 439 = container_of(attr, struct thermal_hwmon_attr, attr); 440 struct thermal_zone_device *tz 441 = container_of(hwmon_attr, struct thermal_zone_device, 442 temp_input); 443 444 ret = tz->ops->get_temp(tz, &temperature); 445 446 if (ret) 447 return ret; 448 449 return sprintf(buf, "%ld\n", temperature); 450} 451 452static ssize_t 453temp_crit_show(struct device *dev, struct device_attribute *attr, 454 char *buf) 455{ 456 struct thermal_hwmon_attr *hwmon_attr 457 = container_of(attr, struct thermal_hwmon_attr, attr); 458 struct thermal_zone_device *tz 459 = container_of(hwmon_attr, struct thermal_zone_device, 460 temp_crit); 461 long temperature; 462 int ret; 463 464 ret = tz->ops->get_trip_temp(tz, 0, &temperature); 465 if (ret) 466 return ret; 467 468 return sprintf(buf, "%ld\n", temperature); 469} 470 471 472static int 473thermal_add_hwmon_sysfs(struct thermal_zone_device *tz) 474{ 475 struct thermal_hwmon_device *hwmon; 476 int new_hwmon_device = 1; 477 int result; 478 479 mutex_lock(&thermal_list_lock); 480 list_for_each_entry(hwmon, &thermal_hwmon_list, node) 481 if (!strcmp(hwmon->type, tz->type)) { 482 new_hwmon_device = 0; 483 mutex_unlock(&thermal_list_lock); 484 goto register_sys_interface; 485 } 486 mutex_unlock(&thermal_list_lock); 487 488 hwmon = kzalloc(sizeof(struct thermal_hwmon_device), GFP_KERNEL); 489 if (!hwmon) 490 return -ENOMEM; 491 492 INIT_LIST_HEAD(&hwmon->tz_list); 493 strlcpy(hwmon->type, tz->type, THERMAL_NAME_LENGTH); 494 hwmon->device = hwmon_device_register(NULL); 495 if (IS_ERR(hwmon->device)) { 496 result = PTR_ERR(hwmon->device); 497 goto free_mem; 498 } 499 dev_set_drvdata(hwmon->device, hwmon); 500 result = device_create_file(hwmon->device, &dev_attr_name); 501 if (result) 502 goto unregister_hwmon_device; 503 504 register_sys_interface: 505 tz->hwmon = hwmon; 506 hwmon->count++; 507 508 snprintf(tz->temp_input.name, THERMAL_NAME_LENGTH, 509 "temp%d_input", hwmon->count); 510 tz->temp_input.attr.attr.name = tz->temp_input.name; 511 tz->temp_input.attr.attr.mode = 0444; 512 tz->temp_input.attr.show = temp_input_show; 513 sysfs_attr_init(&tz->temp_input.attr.attr); 514 result = device_create_file(hwmon->device, &tz->temp_input.attr); 515 if (result) 516 goto unregister_hwmon_device; 517 518 if (tz->ops->get_crit_temp) { 519 unsigned long temperature; 520 if (!tz->ops->get_crit_temp(tz, &temperature)) { 521 snprintf(tz->temp_crit.name, THERMAL_NAME_LENGTH, 522 "temp%d_crit", hwmon->count); 523 tz->temp_crit.attr.attr.name = tz->temp_crit.name; 524 tz->temp_crit.attr.attr.mode = 0444; 525 tz->temp_crit.attr.show = temp_crit_show; 526 sysfs_attr_init(&tz->temp_crit.attr.attr); 527 result = device_create_file(hwmon->device, 528 &tz->temp_crit.attr); 529 if (result) 530 goto unregister_hwmon_device; 531 } 532 } 533 534 mutex_lock(&thermal_list_lock); 535 if (new_hwmon_device) 536 list_add_tail(&hwmon->node, &thermal_hwmon_list); 537 list_add_tail(&tz->hwmon_node, &hwmon->tz_list); 538 mutex_unlock(&thermal_list_lock); 539 540 return 0; 541 542 unregister_hwmon_device: 543 device_remove_file(hwmon->device, &tz->temp_crit.attr); 544 device_remove_file(hwmon->device, &tz->temp_input.attr); 545 if (new_hwmon_device) { 546 device_remove_file(hwmon->device, &dev_attr_name); 547 hwmon_device_unregister(hwmon->device); 548 } 549 free_mem: 550 if (new_hwmon_device) 551 kfree(hwmon); 552 553 return result; 554} 555 556static void 557thermal_remove_hwmon_sysfs(struct thermal_zone_device *tz) 558{ 559 struct thermal_hwmon_device *hwmon = tz->hwmon; 560 561 tz->hwmon = NULL; 562 device_remove_file(hwmon->device, &tz->temp_input.attr); 563 device_remove_file(hwmon->device, &tz->temp_crit.attr); 564 565 mutex_lock(&thermal_list_lock); 566 list_del(&tz->hwmon_node); 567 if (!list_empty(&hwmon->tz_list)) { 568 mutex_unlock(&thermal_list_lock); 569 return; 570 } 571 list_del(&hwmon->node); 572 mutex_unlock(&thermal_list_lock); 573 574 device_remove_file(hwmon->device, &dev_attr_name); 575 hwmon_device_unregister(hwmon->device); 576 kfree(hwmon); 577} 578#else 579static int 580thermal_add_hwmon_sysfs(struct thermal_zone_device *tz) 581{ 582 return 0; 583} 584 585static void 586thermal_remove_hwmon_sysfs(struct thermal_zone_device *tz) 587{ 588} 589#endif 590 591static void thermal_zone_device_set_polling(struct thermal_zone_device *tz, 592 int delay) 593{ 594 cancel_delayed_work(&(tz->poll_queue)); 595 596 if (!delay) 597 return; 598 599 if (delay > 1000) 600 schedule_delayed_work(&(tz->poll_queue), 601 round_jiffies(msecs_to_jiffies(delay))); 602 else 603 schedule_delayed_work(&(tz->poll_queue), 604 msecs_to_jiffies(delay)); 605} 606 607static void thermal_zone_device_passive(struct thermal_zone_device *tz, 608 int temp, int trip_temp, int trip) 609{ 610 int trend = 0; 611 struct thermal_cooling_device_instance *instance; 612 struct thermal_cooling_device *cdev; 613 long state, max_state; 614 615 /* 616 * Above Trip? 617 * ----------- 618 * Calculate the thermal trend (using the passive cooling equation) 619 * and modify the performance limit for all passive cooling devices 620 * accordingly. Note that we assume symmetry. 621 */ 622 if (temp >= trip_temp) { 623 tz->passive = true; 624 625 trend = (tz->tc1 * (temp - tz->last_temperature)) + 626 (tz->tc2 * (temp - trip_temp)); 627 628 /* Heating up? */ 629 if (trend > 0) { 630 list_for_each_entry(instance, &tz->cooling_devices, 631 node) { 632 if (instance->trip != trip) 633 continue; 634 cdev = instance->cdev; 635 cdev->ops->get_cur_state(cdev, &state); 636 cdev->ops->get_max_state(cdev, &max_state); 637 if (state++ < max_state) 638 cdev->ops->set_cur_state(cdev, state); 639 } 640 } else if (trend < 0) { /* Cooling off? */ 641 list_for_each_entry(instance, &tz->cooling_devices, 642 node) { 643 if (instance->trip != trip) 644 continue; 645 cdev = instance->cdev; 646 cdev->ops->get_cur_state(cdev, &state); 647 cdev->ops->get_max_state(cdev, &max_state); 648 if (state > 0) 649 cdev->ops->set_cur_state(cdev, --state); 650 } 651 } 652 return; 653 } 654 655 /* 656 * Below Trip? 657 * ----------- 658 * Implement passive cooling hysteresis to slowly increase performance 659 * and avoid thrashing around the passive trip point. Note that we 660 * assume symmetry. 661 */ 662 list_for_each_entry(instance, &tz->cooling_devices, node) { 663 if (instance->trip != trip) 664 continue; 665 cdev = instance->cdev; 666 cdev->ops->get_cur_state(cdev, &state); 667 cdev->ops->get_max_state(cdev, &max_state); 668 if (state > 0) 669 cdev->ops->set_cur_state(cdev, --state); 670 if (state == 0) 671 tz->passive = false; 672 } 673} 674 675static void thermal_zone_device_check(struct work_struct *work) 676{ 677 struct thermal_zone_device *tz = container_of(work, struct 678 thermal_zone_device, 679 poll_queue.work); 680 thermal_zone_device_update(tz); 681} 682 683/** 684 * thermal_zone_bind_cooling_device - bind a cooling device to a thermal zone 685 * @tz: thermal zone device 686 * @trip: indicates which trip point the cooling devices is 687 * associated with in this thermal zone. 688 * @cdev: thermal cooling device 689 * 690 * This function is usually called in the thermal zone device .bind callback. 691 */ 692int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz, 693 int trip, 694 struct thermal_cooling_device *cdev) 695{ 696 struct thermal_cooling_device_instance *dev; 697 struct thermal_cooling_device_instance *pos; 698 struct thermal_zone_device *pos1; 699 struct thermal_cooling_device *pos2; 700 int result; 701 702 if (trip >= tz->trips || (trip < 0 && trip != THERMAL_TRIPS_NONE)) 703 return -EINVAL; 704 705 list_for_each_entry(pos1, &thermal_tz_list, node) { 706 if (pos1 == tz) 707 break; 708 } 709 list_for_each_entry(pos2, &thermal_cdev_list, node) { 710 if (pos2 == cdev) 711 break; 712 } 713 714 if (tz != pos1 || cdev != pos2) 715 return -EINVAL; 716 717 dev = 718 kzalloc(sizeof(struct thermal_cooling_device_instance), GFP_KERNEL); 719 if (!dev) 720 return -ENOMEM; 721 dev->tz = tz; 722 dev->cdev = cdev; 723 dev->trip = trip; 724 result = get_idr(&tz->idr, &tz->lock, &dev->id); 725 if (result) 726 goto free_mem; 727 728 sprintf(dev->name, "cdev%d", dev->id); 729 result = 730 sysfs_create_link(&tz->device.kobj, &cdev->device.kobj, dev->name); 731 if (result) 732 goto release_idr; 733 734 sprintf(dev->attr_name, "cdev%d_trip_point", dev->id); 735 sysfs_attr_init(&dev->attr.attr); 736 dev->attr.attr.name = dev->attr_name; 737 dev->attr.attr.mode = 0444; 738 dev->attr.show = thermal_cooling_device_trip_point_show; 739 result = device_create_file(&tz->device, &dev->attr); 740 if (result) 741 goto remove_symbol_link; 742 743 mutex_lock(&tz->lock); 744 list_for_each_entry(pos, &tz->cooling_devices, node) 745 if (pos->tz == tz && pos->trip == trip && pos->cdev == cdev) { 746 result = -EEXIST; 747 break; 748 } 749 if (!result) 750 list_add_tail(&dev->node, &tz->cooling_devices); 751 mutex_unlock(&tz->lock); 752 753 if (!result) 754 return 0; 755 756 device_remove_file(&tz->device, &dev->attr); 757 remove_symbol_link: 758 sysfs_remove_link(&tz->device.kobj, dev->name); 759 release_idr: 760 release_idr(&tz->idr, &tz->lock, dev->id); 761 free_mem: 762 kfree(dev); 763 return result; 764} 765 766EXPORT_SYMBOL(thermal_zone_bind_cooling_device); 767 768/** 769 * thermal_zone_unbind_cooling_device - unbind a cooling device from a thermal zone 770 * @tz: thermal zone device 771 * @trip: indicates which trip point the cooling devices is 772 * associated with in this thermal zone. 773 * @cdev: thermal cooling device 774 * 775 * This function is usually called in the thermal zone device .unbind callback. 776 */ 777int thermal_zone_unbind_cooling_device(struct thermal_zone_device *tz, 778 int trip, 779 struct thermal_cooling_device *cdev) 780{ 781 struct thermal_cooling_device_instance *pos, *next; 782 783 mutex_lock(&tz->lock); 784 list_for_each_entry_safe(pos, next, &tz->cooling_devices, node) { 785 if (pos->tz == tz && pos->trip == trip && pos->cdev == cdev) { 786 list_del(&pos->node); 787 mutex_unlock(&tz->lock); 788 goto unbind; 789 } 790 } 791 mutex_unlock(&tz->lock); 792 793 return -ENODEV; 794 795 unbind: 796 device_remove_file(&tz->device, &pos->attr); 797 sysfs_remove_link(&tz->device.kobj, pos->name); 798 release_idr(&tz->idr, &tz->lock, pos->id); 799 kfree(pos); 800 return 0; 801} 802 803EXPORT_SYMBOL(thermal_zone_unbind_cooling_device); 804 805static void thermal_release(struct device *dev) 806{ 807 struct thermal_zone_device *tz; 808 struct thermal_cooling_device *cdev; 809 810 if (!strncmp(dev_name(dev), "thermal_zone", sizeof "thermal_zone" - 1)) { 811 tz = to_thermal_zone(dev); 812 kfree(tz); 813 } else { 814 cdev = to_cooling_device(dev); 815 kfree(cdev); 816 } 817} 818 819static struct class thermal_class = { 820 .name = "thermal", 821 .dev_release = thermal_release, 822}; 823 824/** 825 * thermal_cooling_device_register - register a new thermal cooling device 826 * @type: the thermal cooling device type. 827 * @devdata: device private data. 828 * @ops: standard thermal cooling devices callbacks. 829 */ 830struct thermal_cooling_device *thermal_cooling_device_register( 831 char *type, void *devdata, const struct thermal_cooling_device_ops *ops) 832{ 833 struct thermal_cooling_device *cdev; 834 struct thermal_zone_device *pos; 835 int result; 836 837 if (strlen(type) >= THERMAL_NAME_LENGTH) 838 return ERR_PTR(-EINVAL); 839 840 if (!ops || !ops->get_max_state || !ops->get_cur_state || 841 !ops->set_cur_state) 842 return ERR_PTR(-EINVAL); 843 844 cdev = kzalloc(sizeof(struct thermal_cooling_device), GFP_KERNEL); 845 if (!cdev) 846 return ERR_PTR(-ENOMEM); 847 848 result = get_idr(&thermal_cdev_idr, &thermal_idr_lock, &cdev->id); 849 if (result) { 850 kfree(cdev); 851 return ERR_PTR(result); 852 } 853 854 strcpy(cdev->type, type); 855 cdev->ops = ops; 856 cdev->device.class = &thermal_class; 857 cdev->devdata = devdata; 858 dev_set_name(&cdev->device, "cooling_device%d", cdev->id); 859 result = device_register(&cdev->device); 860 if (result) { 861 release_idr(&thermal_cdev_idr, &thermal_idr_lock, cdev->id); 862 kfree(cdev); 863 return ERR_PTR(result); 864 } 865 866 /* sys I/F */ 867 if (type) { 868 result = device_create_file(&cdev->device, &dev_attr_cdev_type); 869 if (result) 870 goto unregister; 871 } 872 873 result = device_create_file(&cdev->device, &dev_attr_max_state); 874 if (result) 875 goto unregister; 876 877 result = device_create_file(&cdev->device, &dev_attr_cur_state); 878 if (result) 879 goto unregister; 880 881 mutex_lock(&thermal_list_lock); 882 list_add(&cdev->node, &thermal_cdev_list); 883 list_for_each_entry(pos, &thermal_tz_list, node) { 884 if (!pos->ops->bind) 885 continue; 886 result = pos->ops->bind(pos, cdev); 887 if (result) 888 break; 889 890 } 891 mutex_unlock(&thermal_list_lock); 892 893 if (!result) 894 return cdev; 895 896 unregister: 897 release_idr(&thermal_cdev_idr, &thermal_idr_lock, cdev->id); 898 device_unregister(&cdev->device); 899 return ERR_PTR(result); 900} 901 902EXPORT_SYMBOL(thermal_cooling_device_register); 903 904/** 905 * thermal_cooling_device_unregister - removes the registered thermal cooling device 906 * @cdev: the thermal cooling device to remove. 907 * 908 * thermal_cooling_device_unregister() must be called when the device is no 909 * longer needed. 910 */ 911void thermal_cooling_device_unregister(struct 912 thermal_cooling_device 913 *cdev) 914{ 915 struct thermal_zone_device *tz; 916 struct thermal_cooling_device *pos = NULL; 917 918 if (!cdev) 919 return; 920 921 mutex_lock(&thermal_list_lock); 922 list_for_each_entry(pos, &thermal_cdev_list, node) 923 if (pos == cdev) 924 break; 925 if (pos != cdev) { 926 /* thermal cooling device not found */ 927 mutex_unlock(&thermal_list_lock); 928 return; 929 } 930 list_del(&cdev->node); 931 list_for_each_entry(tz, &thermal_tz_list, node) { 932 if (!tz->ops->unbind) 933 continue; 934 tz->ops->unbind(tz, cdev); 935 } 936 mutex_unlock(&thermal_list_lock); 937 if (cdev->type[0]) 938 device_remove_file(&cdev->device, &dev_attr_cdev_type); 939 device_remove_file(&cdev->device, &dev_attr_max_state); 940 device_remove_file(&cdev->device, &dev_attr_cur_state); 941 942 release_idr(&thermal_cdev_idr, &thermal_idr_lock, cdev->id); 943 device_unregister(&cdev->device); 944 return; 945} 946 947EXPORT_SYMBOL(thermal_cooling_device_unregister); 948 949/** 950 * thermal_zone_device_update - force an update of a thermal zone's state 951 * @ttz: the thermal zone to update 952 */ 953 954void thermal_zone_device_update(struct thermal_zone_device *tz) 955{ 956 int count, ret = 0; 957 long temp, trip_temp; 958 enum thermal_trip_type trip_type; 959 struct thermal_cooling_device_instance *instance; 960 struct thermal_cooling_device *cdev; 961 962 mutex_lock(&tz->lock); 963 964 if (tz->ops->get_temp(tz, &temp)) { 965 /* get_temp failed - retry it later */ 966 printk(KERN_WARNING PREFIX "failed to read out thermal zone " 967 "%d\n", tz->id); 968 goto leave; 969 } 970 971 for (count = 0; count < tz->trips; count++) { 972 tz->ops->get_trip_type(tz, count, &trip_type); 973 tz->ops->get_trip_temp(tz, count, &trip_temp); 974 975 switch (trip_type) { 976 case THERMAL_TRIP_CRITICAL: 977 if (temp >= trip_temp) { 978 if (tz->ops->notify) 979 ret = tz->ops->notify(tz, count, 980 trip_type); 981 if (!ret) { 982 printk(KERN_EMERG 983 "Critical temperature reached (%ld C), shutting down.\n", 984 temp/1000); 985 orderly_poweroff(true); 986 } 987 } 988 break; 989 case THERMAL_TRIP_HOT: 990 if (temp >= trip_temp) 991 if (tz->ops->notify) 992 tz->ops->notify(tz, count, trip_type); 993 break; 994 case THERMAL_TRIP_ACTIVE: 995 list_for_each_entry(instance, &tz->cooling_devices, 996 node) { 997 if (instance->trip != count) 998 continue; 999 1000 cdev = instance->cdev; 1001 1002 if (temp >= trip_temp) 1003 cdev->ops->set_cur_state(cdev, 1); 1004 else 1005 cdev->ops->set_cur_state(cdev, 0); 1006 } 1007 break; 1008 case THERMAL_TRIP_PASSIVE: 1009 if (temp >= trip_temp || tz->passive) 1010 thermal_zone_device_passive(tz, temp, 1011 trip_temp, count); 1012 break; 1013 } 1014 } 1015 1016 if (tz->forced_passive) 1017 thermal_zone_device_passive(tz, temp, tz->forced_passive, 1018 THERMAL_TRIPS_NONE); 1019 1020 tz->last_temperature = temp; 1021 1022 leave: 1023 if (tz->passive) 1024 thermal_zone_device_set_polling(tz, tz->passive_delay); 1025 else if (tz->polling_delay) 1026 thermal_zone_device_set_polling(tz, tz->polling_delay); 1027 else 1028 thermal_zone_device_set_polling(tz, 0); 1029 mutex_unlock(&tz->lock); 1030} 1031EXPORT_SYMBOL(thermal_zone_device_update); 1032 1033/** 1034 * thermal_zone_device_register - register a new thermal zone device 1035 * @type: the thermal zone device type 1036 * @trips: the number of trip points the thermal zone support 1037 * @devdata: private device data 1038 * @ops: standard thermal zone device callbacks 1039 * @tc1: thermal coefficient 1 for passive calculations 1040 * @tc2: thermal coefficient 2 for passive calculations 1041 * @passive_delay: number of milliseconds to wait between polls when 1042 * performing passive cooling 1043 * @polling_delay: number of milliseconds to wait between polls when checking 1044 * whether trip points have been crossed (0 for interrupt 1045 * driven systems) 1046 * 1047 * thermal_zone_device_unregister() must be called when the device is no 1048 * longer needed. The passive cooling formula uses tc1 and tc2 as described in 1049 * section 11.1.5.1 of the ACPI specification 3.0. 1050 */ 1051struct thermal_zone_device *thermal_zone_device_register(char *type, 1052 int trips, void *devdata, 1053 const struct thermal_zone_device_ops *ops, 1054 int tc1, int tc2, int passive_delay, int polling_delay) 1055{ 1056 struct thermal_zone_device *tz; 1057 struct thermal_cooling_device *pos; 1058 enum thermal_trip_type trip_type; 1059 int result; 1060 int count; 1061 int passive = 0; 1062 1063 if (strlen(type) >= THERMAL_NAME_LENGTH) 1064 return ERR_PTR(-EINVAL); 1065 1066 if (trips > THERMAL_MAX_TRIPS || trips < 0) 1067 return ERR_PTR(-EINVAL); 1068 1069 if (!ops || !ops->get_temp) 1070 return ERR_PTR(-EINVAL); 1071 1072 tz = kzalloc(sizeof(struct thermal_zone_device), GFP_KERNEL); 1073 if (!tz) 1074 return ERR_PTR(-ENOMEM); 1075 1076 INIT_LIST_HEAD(&tz->cooling_devices); 1077 idr_init(&tz->idr); 1078 mutex_init(&tz->lock); 1079 result = get_idr(&thermal_tz_idr, &thermal_idr_lock, &tz->id); 1080 if (result) { 1081 kfree(tz); 1082 return ERR_PTR(result); 1083 } 1084 1085 strcpy(tz->type, type); 1086 tz->ops = ops; 1087 tz->device.class = &thermal_class; 1088 tz->devdata = devdata; 1089 tz->trips = trips; 1090 tz->tc1 = tc1; 1091 tz->tc2 = tc2; 1092 tz->passive_delay = passive_delay; 1093 tz->polling_delay = polling_delay; 1094 1095 dev_set_name(&tz->device, "thermal_zone%d", tz->id); 1096 result = device_register(&tz->device); 1097 if (result) { 1098 release_idr(&thermal_tz_idr, &thermal_idr_lock, tz->id); 1099 kfree(tz); 1100 return ERR_PTR(result); 1101 } 1102 1103 /* sys I/F */ 1104 if (type) { 1105 result = device_create_file(&tz->device, &dev_attr_type); 1106 if (result) 1107 goto unregister; 1108 } 1109 1110 result = device_create_file(&tz->device, &dev_attr_temp); 1111 if (result) 1112 goto unregister; 1113 1114 if (ops->get_mode) { 1115 result = device_create_file(&tz->device, &dev_attr_mode); 1116 if (result) 1117 goto unregister; 1118 } 1119 1120 for (count = 0; count < trips; count++) { 1121 TRIP_POINT_ATTR_ADD(&tz->device, count, result); 1122 if (result) 1123 goto unregister; 1124 tz->ops->get_trip_type(tz, count, &trip_type); 1125 if (trip_type == THERMAL_TRIP_PASSIVE) 1126 passive = 1; 1127 } 1128 1129 if (!passive) 1130 result = device_create_file(&tz->device, 1131 &dev_attr_passive); 1132 1133 if (result) 1134 goto unregister; 1135 1136 result = thermal_add_hwmon_sysfs(tz); 1137 if (result) 1138 goto unregister; 1139 1140 mutex_lock(&thermal_list_lock); 1141 list_add_tail(&tz->node, &thermal_tz_list); 1142 if (ops->bind) 1143 list_for_each_entry(pos, &thermal_cdev_list, node) { 1144 result = ops->bind(tz, pos); 1145 if (result) 1146 break; 1147 } 1148 mutex_unlock(&thermal_list_lock); 1149 1150 INIT_DELAYED_WORK(&(tz->poll_queue), thermal_zone_device_check); 1151 1152 thermal_zone_device_update(tz); 1153 1154 if (!result) 1155 return tz; 1156 1157 unregister: 1158 release_idr(&thermal_tz_idr, &thermal_idr_lock, tz->id); 1159 device_unregister(&tz->device); 1160 return ERR_PTR(result); 1161} 1162 1163EXPORT_SYMBOL(thermal_zone_device_register); 1164 1165/** 1166 * thermal_device_unregister - removes the registered thermal zone device 1167 * @tz: the thermal zone device to remove 1168 */ 1169void thermal_zone_device_unregister(struct thermal_zone_device *tz) 1170{ 1171 struct thermal_cooling_device *cdev; 1172 struct thermal_zone_device *pos = NULL; 1173 int count; 1174 1175 if (!tz) 1176 return; 1177 1178 mutex_lock(&thermal_list_lock); 1179 list_for_each_entry(pos, &thermal_tz_list, node) 1180 if (pos == tz) 1181 break; 1182 if (pos != tz) { 1183 /* thermal zone device not found */ 1184 mutex_unlock(&thermal_list_lock); 1185 return; 1186 } 1187 list_del(&tz->node); 1188 if (tz->ops->unbind) 1189 list_for_each_entry(cdev, &thermal_cdev_list, node) 1190 tz->ops->unbind(tz, cdev); 1191 mutex_unlock(&thermal_list_lock); 1192 1193 thermal_zone_device_set_polling(tz, 0); 1194 1195 if (tz->type[0]) 1196 device_remove_file(&tz->device, &dev_attr_type); 1197 device_remove_file(&tz->device, &dev_attr_temp); 1198 if (tz->ops->get_mode) 1199 device_remove_file(&tz->device, &dev_attr_mode); 1200 1201 for (count = 0; count < tz->trips; count++) 1202 TRIP_POINT_ATTR_REMOVE(&tz->device, count); 1203 1204 thermal_remove_hwmon_sysfs(tz); 1205 release_idr(&thermal_tz_idr, &thermal_idr_lock, tz->id); 1206 idr_destroy(&tz->idr); 1207 mutex_destroy(&tz->lock); 1208 device_unregister(&tz->device); 1209 return; 1210} 1211 1212EXPORT_SYMBOL(thermal_zone_device_unregister); 1213 1214#ifdef CONFIG_NET 1215static struct genl_family thermal_event_genl_family = { 1216 .id = GENL_ID_GENERATE, 1217 .name = THERMAL_GENL_FAMILY_NAME, 1218 .version = THERMAL_GENL_VERSION, 1219 .maxattr = THERMAL_GENL_ATTR_MAX, 1220}; 1221 1222static struct genl_multicast_group thermal_event_mcgrp = { 1223 .name = THERMAL_GENL_MCAST_GROUP_NAME, 1224}; 1225 1226int generate_netlink_event(u32 orig, enum events event) 1227{ 1228 struct sk_buff *skb; 1229 struct nlattr *attr; 1230 struct thermal_genl_event *thermal_event; 1231 void *msg_header; 1232 int size; 1233 int result; 1234 1235 /* allocate memory */ 1236 size = nla_total_size(sizeof(struct thermal_genl_event)) + \ 1237 nla_total_size(0); 1238 1239 skb = genlmsg_new(size, GFP_ATOMIC); 1240 if (!skb) 1241 return -ENOMEM; 1242 1243 /* add the genetlink message header */ 1244 msg_header = genlmsg_put(skb, 0, thermal_event_seqnum++, 1245 &thermal_event_genl_family, 0, 1246 THERMAL_GENL_CMD_EVENT); 1247 if (!msg_header) { 1248 nlmsg_free(skb); 1249 return -ENOMEM; 1250 } 1251 1252 /* fill the data */ 1253 attr = nla_reserve(skb, THERMAL_GENL_ATTR_EVENT, \ 1254 sizeof(struct thermal_genl_event)); 1255 1256 if (!attr) { 1257 nlmsg_free(skb); 1258 return -EINVAL; 1259 } 1260 1261 thermal_event = nla_data(attr); 1262 if (!thermal_event) { 1263 nlmsg_free(skb); 1264 return -EINVAL; 1265 } 1266 1267 memset(thermal_event, 0, sizeof(struct thermal_genl_event)); 1268 1269 thermal_event->orig = orig; 1270 thermal_event->event = event; 1271 1272 /* send multicast genetlink message */ 1273 result = genlmsg_end(skb, msg_header); 1274 if (result < 0) { 1275 nlmsg_free(skb); 1276 return result; 1277 } 1278 1279 result = genlmsg_multicast(skb, 0, thermal_event_mcgrp.id, GFP_ATOMIC); 1280 if (result) 1281 printk(KERN_INFO "failed to send netlink event:%d", result); 1282 1283 return result; 1284} 1285EXPORT_SYMBOL(generate_netlink_event); 1286 1287static int genetlink_init(void) 1288{ 1289 int result; 1290 1291 result = genl_register_family(&thermal_event_genl_family); 1292 if (result) 1293 return result; 1294 1295 result = genl_register_mc_group(&thermal_event_genl_family, 1296 &thermal_event_mcgrp); 1297 if (result) 1298 genl_unregister_family(&thermal_event_genl_family); 1299 return result; 1300} 1301 1302static void genetlink_exit(void) 1303{ 1304 genl_unregister_family(&thermal_event_genl_family); 1305} 1306#else /* !CONFIG_NET */ 1307static inline int genetlink_init(void) { return 0; } 1308static inline void genetlink_exit(void) {} 1309#endif /* !CONFIG_NET */ 1310 1311static int __init thermal_init(void) 1312{ 1313 int result = 0; 1314 1315 result = class_register(&thermal_class); 1316 if (result) { 1317 idr_destroy(&thermal_tz_idr); 1318 idr_destroy(&thermal_cdev_idr); 1319 mutex_destroy(&thermal_idr_lock); 1320 mutex_destroy(&thermal_list_lock); 1321 } 1322 result = genetlink_init(); 1323 return result; 1324} 1325 1326static void __exit thermal_exit(void) 1327{ 1328 class_unregister(&thermal_class); 1329 idr_destroy(&thermal_tz_idr); 1330 idr_destroy(&thermal_cdev_idr); 1331 mutex_destroy(&thermal_idr_lock); 1332 mutex_destroy(&thermal_list_lock); 1333 genetlink_exit(); 1334} 1335 1336fs_initcall(thermal_init); 1337module_exit(thermal_exit);