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

Configure Feed

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

at v2.6.32-rc2 1018 lines 24 kB view raw
1/* 2 * A hwmon driver for ACPI 4.0 power meters 3 * Copyright (C) 2009 IBM 4 * 5 * Author: Darrick J. Wong <djwong@us.ibm.com> 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 */ 21 22#include <linux/module.h> 23#include <linux/hwmon.h> 24#include <linux/hwmon-sysfs.h> 25#include <linux/jiffies.h> 26#include <linux/mutex.h> 27#include <linux/dmi.h> 28#include <linux/kdev_t.h> 29#include <linux/sched.h> 30#include <linux/time.h> 31#include <acpi/acpi_drivers.h> 32#include <acpi/acpi_bus.h> 33 34#define ACPI_POWER_METER_NAME "power_meter" 35ACPI_MODULE_NAME(ACPI_POWER_METER_NAME); 36#define ACPI_POWER_METER_DEVICE_NAME "Power Meter" 37#define ACPI_POWER_METER_CLASS "power_meter_resource" 38 39#define NUM_SENSORS 17 40 41#define POWER_METER_CAN_MEASURE (1 << 0) 42#define POWER_METER_CAN_TRIP (1 << 1) 43#define POWER_METER_CAN_CAP (1 << 2) 44#define POWER_METER_CAN_NOTIFY (1 << 3) 45#define POWER_METER_IS_BATTERY (1 << 8) 46#define UNKNOWN_HYSTERESIS 0xFFFFFFFF 47 48#define METER_NOTIFY_CONFIG 0x80 49#define METER_NOTIFY_TRIP 0x81 50#define METER_NOTIFY_CAP 0x82 51#define METER_NOTIFY_CAPPING 0x83 52#define METER_NOTIFY_INTERVAL 0x84 53 54#define POWER_AVERAGE_NAME "power1_average" 55#define POWER_CAP_NAME "power1_cap" 56#define POWER_AVG_INTERVAL_NAME "power1_average_interval" 57#define POWER_ALARM_NAME "power1_alarm" 58 59static int cap_in_hardware; 60static int force_cap_on; 61 62static int can_cap_in_hardware(void) 63{ 64 return force_cap_on || cap_in_hardware; 65} 66 67static struct acpi_device_id power_meter_ids[] = { 68 {"ACPI000D", 0}, 69 {"", 0}, 70}; 71MODULE_DEVICE_TABLE(acpi, power_meter_ids); 72 73struct acpi_power_meter_capabilities { 74 acpi_integer flags; 75 acpi_integer units; 76 acpi_integer type; 77 acpi_integer accuracy; 78 acpi_integer sampling_time; 79 acpi_integer min_avg_interval; 80 acpi_integer max_avg_interval; 81 acpi_integer hysteresis; 82 acpi_integer configurable_cap; 83 acpi_integer min_cap; 84 acpi_integer max_cap; 85}; 86 87struct acpi_power_meter_resource { 88 struct acpi_device *acpi_dev; 89 acpi_bus_id name; 90 struct mutex lock; 91 struct device *hwmon_dev; 92 struct acpi_power_meter_capabilities caps; 93 acpi_string model_number; 94 acpi_string serial_number; 95 acpi_string oem_info; 96 acpi_integer power; 97 acpi_integer cap; 98 acpi_integer avg_interval; 99 int sensors_valid; 100 unsigned long sensors_last_updated; 101 struct sensor_device_attribute sensors[NUM_SENSORS]; 102 int num_sensors; 103 int trip[2]; 104 int num_domain_devices; 105 struct acpi_device **domain_devices; 106 struct kobject *holders_dir; 107}; 108 109struct ro_sensor_template { 110 char *label; 111 ssize_t (*show)(struct device *dev, 112 struct device_attribute *devattr, 113 char *buf); 114 int index; 115}; 116 117struct rw_sensor_template { 118 char *label; 119 ssize_t (*show)(struct device *dev, 120 struct device_attribute *devattr, 121 char *buf); 122 ssize_t (*set)(struct device *dev, 123 struct device_attribute *devattr, 124 const char *buf, size_t count); 125 int index; 126}; 127 128/* Averaging interval */ 129static int update_avg_interval(struct acpi_power_meter_resource *resource) 130{ 131 unsigned long long data; 132 acpi_status status; 133 134 status = acpi_evaluate_integer(resource->acpi_dev->handle, "_GAI", 135 NULL, &data); 136 if (ACPI_FAILURE(status)) { 137 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _GAI")); 138 return -ENODEV; 139 } 140 141 resource->avg_interval = data; 142 return 0; 143} 144 145static ssize_t show_avg_interval(struct device *dev, 146 struct device_attribute *devattr, 147 char *buf) 148{ 149 struct acpi_device *acpi_dev = to_acpi_device(dev); 150 struct acpi_power_meter_resource *resource = acpi_dev->driver_data; 151 152 mutex_lock(&resource->lock); 153 update_avg_interval(resource); 154 mutex_unlock(&resource->lock); 155 156 return sprintf(buf, "%llu\n", resource->avg_interval); 157} 158 159static ssize_t set_avg_interval(struct device *dev, 160 struct device_attribute *devattr, 161 const char *buf, size_t count) 162{ 163 struct acpi_device *acpi_dev = to_acpi_device(dev); 164 struct acpi_power_meter_resource *resource = acpi_dev->driver_data; 165 union acpi_object arg0 = { ACPI_TYPE_INTEGER }; 166 struct acpi_object_list args = { 1, &arg0 }; 167 int res; 168 unsigned long temp; 169 unsigned long long data; 170 acpi_status status; 171 172 res = strict_strtoul(buf, 10, &temp); 173 if (res) 174 return res; 175 176 if (temp > resource->caps.max_avg_interval || 177 temp < resource->caps.min_avg_interval) 178 return -EINVAL; 179 arg0.integer.value = temp; 180 181 mutex_lock(&resource->lock); 182 status = acpi_evaluate_integer(resource->acpi_dev->handle, "_PAI", 183 &args, &data); 184 if (!ACPI_FAILURE(status)) 185 resource->avg_interval = temp; 186 mutex_unlock(&resource->lock); 187 188 if (ACPI_FAILURE(status)) { 189 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PAI")); 190 return -EINVAL; 191 } 192 193 /* _PAI returns 0 on success, nonzero otherwise */ 194 if (data) 195 return -EINVAL; 196 197 return count; 198} 199 200/* Cap functions */ 201static int update_cap(struct acpi_power_meter_resource *resource) 202{ 203 unsigned long long data; 204 acpi_status status; 205 206 status = acpi_evaluate_integer(resource->acpi_dev->handle, "_GHL", 207 NULL, &data); 208 if (ACPI_FAILURE(status)) { 209 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _GHL")); 210 return -ENODEV; 211 } 212 213 resource->cap = data; 214 return 0; 215} 216 217static ssize_t show_cap(struct device *dev, 218 struct device_attribute *devattr, 219 char *buf) 220{ 221 struct acpi_device *acpi_dev = to_acpi_device(dev); 222 struct acpi_power_meter_resource *resource = acpi_dev->driver_data; 223 224 mutex_lock(&resource->lock); 225 update_cap(resource); 226 mutex_unlock(&resource->lock); 227 228 return sprintf(buf, "%llu\n", resource->cap * 1000); 229} 230 231static ssize_t set_cap(struct device *dev, struct device_attribute *devattr, 232 const char *buf, size_t count) 233{ 234 struct acpi_device *acpi_dev = to_acpi_device(dev); 235 struct acpi_power_meter_resource *resource = acpi_dev->driver_data; 236 union acpi_object arg0 = { ACPI_TYPE_INTEGER }; 237 struct acpi_object_list args = { 1, &arg0 }; 238 int res; 239 unsigned long temp; 240 unsigned long long data; 241 acpi_status status; 242 243 res = strict_strtoul(buf, 10, &temp); 244 if (res) 245 return res; 246 247 temp /= 1000; 248 if (temp > resource->caps.max_cap || temp < resource->caps.min_cap) 249 return -EINVAL; 250 arg0.integer.value = temp; 251 252 mutex_lock(&resource->lock); 253 status = acpi_evaluate_integer(resource->acpi_dev->handle, "_SHL", 254 &args, &data); 255 if (!ACPI_FAILURE(status)) 256 resource->cap = temp; 257 mutex_unlock(&resource->lock); 258 259 if (ACPI_FAILURE(status)) { 260 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _SHL")); 261 return -EINVAL; 262 } 263 264 /* _SHL returns 0 on success, nonzero otherwise */ 265 if (data) 266 return -EINVAL; 267 268 return count; 269} 270 271/* Power meter trip points */ 272static int set_acpi_trip(struct acpi_power_meter_resource *resource) 273{ 274 union acpi_object arg_objs[] = { 275 {ACPI_TYPE_INTEGER}, 276 {ACPI_TYPE_INTEGER} 277 }; 278 struct acpi_object_list args = { 2, arg_objs }; 279 unsigned long long data; 280 acpi_status status; 281 282 /* Both trip levels must be set */ 283 if (resource->trip[0] < 0 || resource->trip[1] < 0) 284 return 0; 285 286 /* This driver stores min, max; ACPI wants max, min. */ 287 arg_objs[0].integer.value = resource->trip[1]; 288 arg_objs[1].integer.value = resource->trip[0]; 289 290 status = acpi_evaluate_integer(resource->acpi_dev->handle, "_PTP", 291 &args, &data); 292 if (ACPI_FAILURE(status)) { 293 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PTP")); 294 return -EINVAL; 295 } 296 297 return data; 298} 299 300static ssize_t set_trip(struct device *dev, struct device_attribute *devattr, 301 const char *buf, size_t count) 302{ 303 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 304 struct acpi_device *acpi_dev = to_acpi_device(dev); 305 struct acpi_power_meter_resource *resource = acpi_dev->driver_data; 306 int res; 307 unsigned long temp; 308 309 res = strict_strtoul(buf, 10, &temp); 310 if (res) 311 return res; 312 313 temp /= 1000; 314 if (temp < 0) 315 return -EINVAL; 316 317 mutex_lock(&resource->lock); 318 resource->trip[attr->index - 7] = temp; 319 res = set_acpi_trip(resource); 320 mutex_unlock(&resource->lock); 321 322 if (res) 323 return res; 324 325 return count; 326} 327 328/* Power meter */ 329static int update_meter(struct acpi_power_meter_resource *resource) 330{ 331 unsigned long long data; 332 acpi_status status; 333 unsigned long local_jiffies = jiffies; 334 335 if (time_before(local_jiffies, resource->sensors_last_updated + 336 msecs_to_jiffies(resource->caps.sampling_time)) && 337 resource->sensors_valid) 338 return 0; 339 340 status = acpi_evaluate_integer(resource->acpi_dev->handle, "_PMM", 341 NULL, &data); 342 if (ACPI_FAILURE(status)) { 343 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PMM")); 344 return -ENODEV; 345 } 346 347 resource->power = data; 348 resource->sensors_valid = 1; 349 resource->sensors_last_updated = jiffies; 350 return 0; 351} 352 353static ssize_t show_power(struct device *dev, 354 struct device_attribute *devattr, 355 char *buf) 356{ 357 struct acpi_device *acpi_dev = to_acpi_device(dev); 358 struct acpi_power_meter_resource *resource = acpi_dev->driver_data; 359 360 mutex_lock(&resource->lock); 361 update_meter(resource); 362 mutex_unlock(&resource->lock); 363 364 return sprintf(buf, "%llu\n", resource->power * 1000); 365} 366 367/* Miscellaneous */ 368static ssize_t show_str(struct device *dev, 369 struct device_attribute *devattr, 370 char *buf) 371{ 372 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 373 struct acpi_device *acpi_dev = to_acpi_device(dev); 374 struct acpi_power_meter_resource *resource = acpi_dev->driver_data; 375 acpi_string val; 376 377 switch (attr->index) { 378 case 0: 379 val = resource->model_number; 380 break; 381 case 1: 382 val = resource->serial_number; 383 break; 384 case 2: 385 val = resource->oem_info; 386 break; 387 default: 388 BUG(); 389 } 390 391 return sprintf(buf, "%s\n", val); 392} 393 394static ssize_t show_val(struct device *dev, 395 struct device_attribute *devattr, 396 char *buf) 397{ 398 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 399 struct acpi_device *acpi_dev = to_acpi_device(dev); 400 struct acpi_power_meter_resource *resource = acpi_dev->driver_data; 401 acpi_integer val = 0; 402 403 switch (attr->index) { 404 case 0: 405 val = resource->caps.min_avg_interval; 406 break; 407 case 1: 408 val = resource->caps.max_avg_interval; 409 break; 410 case 2: 411 val = resource->caps.min_cap * 1000; 412 break; 413 case 3: 414 val = resource->caps.max_cap * 1000; 415 break; 416 case 4: 417 if (resource->caps.hysteresis == UNKNOWN_HYSTERESIS) 418 return sprintf(buf, "unknown\n"); 419 420 val = resource->caps.hysteresis * 1000; 421 break; 422 case 5: 423 if (resource->caps.flags & POWER_METER_IS_BATTERY) 424 val = 1; 425 else 426 val = 0; 427 break; 428 case 6: 429 if (resource->power > resource->cap) 430 val = 1; 431 else 432 val = 0; 433 break; 434 case 7: 435 case 8: 436 if (resource->trip[attr->index - 7] < 0) 437 return sprintf(buf, "unknown\n"); 438 439 val = resource->trip[attr->index - 7] * 1000; 440 break; 441 default: 442 BUG(); 443 } 444 445 return sprintf(buf, "%llu\n", val); 446} 447 448static ssize_t show_accuracy(struct device *dev, 449 struct device_attribute *devattr, 450 char *buf) 451{ 452 struct acpi_device *acpi_dev = to_acpi_device(dev); 453 struct acpi_power_meter_resource *resource = acpi_dev->driver_data; 454 unsigned int acc = resource->caps.accuracy; 455 456 return sprintf(buf, "%u.%u%%\n", acc / 1000, acc % 1000); 457} 458 459static ssize_t show_name(struct device *dev, 460 struct device_attribute *devattr, 461 char *buf) 462{ 463 return sprintf(buf, "%s\n", ACPI_POWER_METER_NAME); 464} 465 466/* Sensor descriptions. If you add a sensor, update NUM_SENSORS above! */ 467static struct ro_sensor_template meter_ro_attrs[] = { 468{POWER_AVERAGE_NAME, show_power, 0}, 469{"power1_accuracy", show_accuracy, 0}, 470{"power1_average_interval_min", show_val, 0}, 471{"power1_average_interval_max", show_val, 1}, 472{"power1_is_battery", show_val, 5}, 473{NULL, NULL, 0}, 474}; 475 476static struct rw_sensor_template meter_rw_attrs[] = { 477{POWER_AVG_INTERVAL_NAME, show_avg_interval, set_avg_interval, 0}, 478{NULL, NULL, NULL, 0}, 479}; 480 481static struct ro_sensor_template misc_cap_attrs[] = { 482{"power1_cap_min", show_val, 2}, 483{"power1_cap_max", show_val, 3}, 484{"power1_cap_hyst", show_val, 4}, 485{POWER_ALARM_NAME, show_val, 6}, 486{NULL, NULL, 0}, 487}; 488 489static struct ro_sensor_template ro_cap_attrs[] = { 490{POWER_CAP_NAME, show_cap, 0}, 491{NULL, NULL, 0}, 492}; 493 494static struct rw_sensor_template rw_cap_attrs[] = { 495{POWER_CAP_NAME, show_cap, set_cap, 0}, 496{NULL, NULL, NULL, 0}, 497}; 498 499static struct rw_sensor_template trip_attrs[] = { 500{"power1_average_min", show_val, set_trip, 7}, 501{"power1_average_max", show_val, set_trip, 8}, 502{NULL, NULL, NULL, 0}, 503}; 504 505static struct ro_sensor_template misc_attrs[] = { 506{"name", show_name, 0}, 507{"power1_model_number", show_str, 0}, 508{"power1_oem_info", show_str, 2}, 509{"power1_serial_number", show_str, 1}, 510{NULL, NULL, 0}, 511}; 512 513/* Read power domain data */ 514static void remove_domain_devices(struct acpi_power_meter_resource *resource) 515{ 516 int i; 517 518 if (!resource->num_domain_devices) 519 return; 520 521 for (i = 0; i < resource->num_domain_devices; i++) { 522 struct acpi_device *obj = resource->domain_devices[i]; 523 if (!obj) 524 continue; 525 526 sysfs_remove_link(resource->holders_dir, 527 kobject_name(&obj->dev.kobj)); 528 put_device(&obj->dev); 529 } 530 531 kfree(resource->domain_devices); 532 kobject_put(resource->holders_dir); 533} 534 535static int read_domain_devices(struct acpi_power_meter_resource *resource) 536{ 537 int res = 0; 538 int i; 539 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 540 union acpi_object *pss; 541 acpi_status status; 542 543 status = acpi_evaluate_object(resource->acpi_dev->handle, "_PMD", NULL, 544 &buffer); 545 if (ACPI_FAILURE(status)) { 546 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PMD")); 547 return -ENODEV; 548 } 549 550 pss = buffer.pointer; 551 if (!pss || 552 pss->type != ACPI_TYPE_PACKAGE) { 553 dev_err(&resource->acpi_dev->dev, ACPI_POWER_METER_NAME 554 "Invalid _PMD data\n"); 555 res = -EFAULT; 556 goto end; 557 } 558 559 if (!pss->package.count) 560 goto end; 561 562 resource->domain_devices = kzalloc(sizeof(struct acpi_device *) * 563 pss->package.count, GFP_KERNEL); 564 if (!resource->domain_devices) { 565 res = -ENOMEM; 566 goto end; 567 } 568 569 resource->holders_dir = kobject_create_and_add("measures", 570 &resource->acpi_dev->dev.kobj); 571 if (!resource->holders_dir) { 572 res = -ENOMEM; 573 goto exit_free; 574 } 575 576 resource->num_domain_devices = pss->package.count; 577 578 for (i = 0; i < pss->package.count; i++) { 579 struct acpi_device *obj; 580 union acpi_object *element = &(pss->package.elements[i]); 581 582 /* Refuse non-references */ 583 if (element->type != ACPI_TYPE_LOCAL_REFERENCE) 584 continue; 585 586 /* Create a symlink to domain objects */ 587 resource->domain_devices[i] = NULL; 588 status = acpi_bus_get_device(element->reference.handle, 589 &resource->domain_devices[i]); 590 if (ACPI_FAILURE(status)) 591 continue; 592 593 obj = resource->domain_devices[i]; 594 get_device(&obj->dev); 595 596 res = sysfs_create_link(resource->holders_dir, &obj->dev.kobj, 597 kobject_name(&obj->dev.kobj)); 598 if (res) { 599 put_device(&obj->dev); 600 resource->domain_devices[i] = NULL; 601 } 602 } 603 604 res = 0; 605 goto end; 606 607exit_free: 608 kfree(resource->domain_devices); 609end: 610 kfree(buffer.pointer); 611 return res; 612} 613 614/* Registration and deregistration */ 615static int register_ro_attrs(struct acpi_power_meter_resource *resource, 616 struct ro_sensor_template *ro) 617{ 618 struct device *dev = &resource->acpi_dev->dev; 619 struct sensor_device_attribute *sensors = 620 &resource->sensors[resource->num_sensors]; 621 int res = 0; 622 623 while (ro->label) { 624 sensors->dev_attr.attr.name = ro->label; 625 sensors->dev_attr.attr.mode = S_IRUGO; 626 sensors->dev_attr.show = ro->show; 627 sensors->index = ro->index; 628 629 res = device_create_file(dev, &sensors->dev_attr); 630 if (res) { 631 sensors->dev_attr.attr.name = NULL; 632 goto error; 633 } 634 sensors++; 635 resource->num_sensors++; 636 ro++; 637 } 638 639error: 640 return res; 641} 642 643static int register_rw_attrs(struct acpi_power_meter_resource *resource, 644 struct rw_sensor_template *rw) 645{ 646 struct device *dev = &resource->acpi_dev->dev; 647 struct sensor_device_attribute *sensors = 648 &resource->sensors[resource->num_sensors]; 649 int res = 0; 650 651 while (rw->label) { 652 sensors->dev_attr.attr.name = rw->label; 653 sensors->dev_attr.attr.mode = S_IRUGO | S_IWUSR; 654 sensors->dev_attr.show = rw->show; 655 sensors->dev_attr.store = rw->set; 656 sensors->index = rw->index; 657 658 res = device_create_file(dev, &sensors->dev_attr); 659 if (res) { 660 sensors->dev_attr.attr.name = NULL; 661 goto error; 662 } 663 sensors++; 664 resource->num_sensors++; 665 rw++; 666 } 667 668error: 669 return res; 670} 671 672static void remove_attrs(struct acpi_power_meter_resource *resource) 673{ 674 int i; 675 676 for (i = 0; i < resource->num_sensors; i++) { 677 if (!resource->sensors[i].dev_attr.attr.name) 678 continue; 679 device_remove_file(&resource->acpi_dev->dev, 680 &resource->sensors[i].dev_attr); 681 } 682 683 remove_domain_devices(resource); 684 685 resource->num_sensors = 0; 686} 687 688static int setup_attrs(struct acpi_power_meter_resource *resource) 689{ 690 int res = 0; 691 692 res = read_domain_devices(resource); 693 if (res) 694 return res; 695 696 if (resource->caps.flags & POWER_METER_CAN_MEASURE) { 697 res = register_ro_attrs(resource, meter_ro_attrs); 698 if (res) 699 goto error; 700 res = register_rw_attrs(resource, meter_rw_attrs); 701 if (res) 702 goto error; 703 } 704 705 if (resource->caps.flags & POWER_METER_CAN_CAP) { 706 if (!can_cap_in_hardware()) { 707 dev_err(&resource->acpi_dev->dev, 708 "Ignoring unsafe software power cap!\n"); 709 goto skip_unsafe_cap; 710 } 711 712 if (resource->caps.configurable_cap) { 713 res = register_rw_attrs(resource, rw_cap_attrs); 714 if (res) 715 goto error; 716 } else { 717 res = register_ro_attrs(resource, ro_cap_attrs); 718 if (res) 719 goto error; 720 } 721 res = register_ro_attrs(resource, misc_cap_attrs); 722 if (res) 723 goto error; 724 } 725skip_unsafe_cap: 726 727 if (resource->caps.flags & POWER_METER_CAN_TRIP) { 728 res = register_rw_attrs(resource, trip_attrs); 729 if (res) 730 goto error; 731 } 732 733 res = register_ro_attrs(resource, misc_attrs); 734 if (res) 735 goto error; 736 737 return res; 738error: 739 remove_domain_devices(resource); 740 remove_attrs(resource); 741 return res; 742} 743 744static void free_capabilities(struct acpi_power_meter_resource *resource) 745{ 746 acpi_string *str; 747 int i; 748 749 str = &resource->model_number; 750 for (i = 0; i < 3; i++, str++) 751 kfree(*str); 752} 753 754static int read_capabilities(struct acpi_power_meter_resource *resource) 755{ 756 int res = 0; 757 int i; 758 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 759 struct acpi_buffer state = { 0, NULL }; 760 struct acpi_buffer format = { sizeof("NNNNNNNNNNN"), "NNNNNNNNNNN" }; 761 union acpi_object *pss; 762 acpi_string *str; 763 acpi_status status; 764 765 status = acpi_evaluate_object(resource->acpi_dev->handle, "_PMC", NULL, 766 &buffer); 767 if (ACPI_FAILURE(status)) { 768 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PMC")); 769 return -ENODEV; 770 } 771 772 pss = buffer.pointer; 773 if (!pss || 774 pss->type != ACPI_TYPE_PACKAGE || 775 pss->package.count != 14) { 776 dev_err(&resource->acpi_dev->dev, ACPI_POWER_METER_NAME 777 "Invalid _PMC data\n"); 778 res = -EFAULT; 779 goto end; 780 } 781 782 /* Grab all the integer data at once */ 783 state.length = sizeof(struct acpi_power_meter_capabilities); 784 state.pointer = &resource->caps; 785 786 status = acpi_extract_package(pss, &format, &state); 787 if (ACPI_FAILURE(status)) { 788 ACPI_EXCEPTION((AE_INFO, status, "Invalid data")); 789 res = -EFAULT; 790 goto end; 791 } 792 793 if (resource->caps.units) { 794 dev_err(&resource->acpi_dev->dev, ACPI_POWER_METER_NAME 795 "Unknown units %llu.\n", 796 resource->caps.units); 797 res = -EINVAL; 798 goto end; 799 } 800 801 /* Grab the string data */ 802 str = &resource->model_number; 803 804 for (i = 11; i < 14; i++) { 805 union acpi_object *element = &(pss->package.elements[i]); 806 807 if (element->type != ACPI_TYPE_STRING) { 808 res = -EINVAL; 809 goto error; 810 } 811 812 *str = kzalloc(sizeof(u8) * (element->string.length + 1), 813 GFP_KERNEL); 814 if (!*str) { 815 res = -ENOMEM; 816 goto error; 817 } 818 819 strncpy(*str, element->string.pointer, element->string.length); 820 str++; 821 } 822 823 dev_info(&resource->acpi_dev->dev, "Found ACPI power meter.\n"); 824 goto end; 825error: 826 str = &resource->model_number; 827 for (i = 0; i < 3; i++, str++) 828 kfree(*str); 829end: 830 kfree(buffer.pointer); 831 return res; 832} 833 834/* Handle ACPI event notifications */ 835static void acpi_power_meter_notify(struct acpi_device *device, u32 event) 836{ 837 struct acpi_power_meter_resource *resource; 838 int res; 839 840 if (!device || !acpi_driver_data(device)) 841 return; 842 843 resource = acpi_driver_data(device); 844 845 mutex_lock(&resource->lock); 846 switch (event) { 847 case METER_NOTIFY_CONFIG: 848 free_capabilities(resource); 849 res = read_capabilities(resource); 850 if (res) 851 break; 852 853 remove_attrs(resource); 854 setup_attrs(resource); 855 break; 856 case METER_NOTIFY_TRIP: 857 sysfs_notify(&device->dev.kobj, NULL, POWER_AVERAGE_NAME); 858 update_meter(resource); 859 break; 860 case METER_NOTIFY_CAP: 861 sysfs_notify(&device->dev.kobj, NULL, POWER_CAP_NAME); 862 update_cap(resource); 863 break; 864 case METER_NOTIFY_INTERVAL: 865 sysfs_notify(&device->dev.kobj, NULL, POWER_AVG_INTERVAL_NAME); 866 update_avg_interval(resource); 867 break; 868 case METER_NOTIFY_CAPPING: 869 sysfs_notify(&device->dev.kobj, NULL, POWER_ALARM_NAME); 870 dev_info(&device->dev, "Capping in progress.\n"); 871 break; 872 default: 873 BUG(); 874 } 875 mutex_unlock(&resource->lock); 876 877 acpi_bus_generate_netlink_event(ACPI_POWER_METER_CLASS, 878 dev_name(&device->dev), event, 0); 879} 880 881static int acpi_power_meter_add(struct acpi_device *device) 882{ 883 int res; 884 struct acpi_power_meter_resource *resource; 885 886 if (!device) 887 return -EINVAL; 888 889 resource = kzalloc(sizeof(struct acpi_power_meter_resource), 890 GFP_KERNEL); 891 if (!resource) 892 return -ENOMEM; 893 894 resource->sensors_valid = 0; 895 resource->acpi_dev = device; 896 mutex_init(&resource->lock); 897 strcpy(acpi_device_name(device), ACPI_POWER_METER_DEVICE_NAME); 898 strcpy(acpi_device_class(device), ACPI_POWER_METER_CLASS); 899 device->driver_data = resource; 900 901 free_capabilities(resource); 902 res = read_capabilities(resource); 903 if (res) 904 goto exit_free; 905 906 resource->trip[0] = resource->trip[1] = -1; 907 908 res = setup_attrs(resource); 909 if (res) 910 goto exit_free; 911 912 resource->hwmon_dev = hwmon_device_register(&device->dev); 913 if (IS_ERR(resource->hwmon_dev)) { 914 res = PTR_ERR(resource->hwmon_dev); 915 goto exit_remove; 916 } 917 918 res = 0; 919 goto exit; 920 921exit_remove: 922 remove_attrs(resource); 923exit_free: 924 kfree(resource); 925exit: 926 return res; 927} 928 929static int acpi_power_meter_remove(struct acpi_device *device, int type) 930{ 931 struct acpi_power_meter_resource *resource; 932 933 if (!device || !acpi_driver_data(device)) 934 return -EINVAL; 935 936 resource = acpi_driver_data(device); 937 hwmon_device_unregister(resource->hwmon_dev); 938 939 free_capabilities(resource); 940 remove_attrs(resource); 941 942 kfree(resource); 943 return 0; 944} 945 946static int acpi_power_meter_resume(struct acpi_device *device) 947{ 948 struct acpi_power_meter_resource *resource; 949 950 if (!device || !acpi_driver_data(device)) 951 return -EINVAL; 952 953 resource = acpi_driver_data(device); 954 free_capabilities(resource); 955 read_capabilities(resource); 956 957 return 0; 958} 959 960static struct acpi_driver acpi_power_meter_driver = { 961 .name = "power_meter", 962 .class = ACPI_POWER_METER_CLASS, 963 .ids = power_meter_ids, 964 .ops = { 965 .add = acpi_power_meter_add, 966 .remove = acpi_power_meter_remove, 967 .resume = acpi_power_meter_resume, 968 .notify = acpi_power_meter_notify, 969 }, 970}; 971 972/* Module init/exit routines */ 973static int __init enable_cap_knobs(const struct dmi_system_id *d) 974{ 975 cap_in_hardware = 1; 976 return 0; 977} 978 979static struct dmi_system_id __initdata pm_dmi_table[] = { 980 { 981 enable_cap_knobs, "IBM Active Energy Manager", 982 { 983 DMI_MATCH(DMI_SYS_VENDOR, "IBM") 984 }, 985 }, 986 {} 987}; 988 989static int __init acpi_power_meter_init(void) 990{ 991 int result; 992 993 if (acpi_disabled) 994 return -ENODEV; 995 996 dmi_check_system(pm_dmi_table); 997 998 result = acpi_bus_register_driver(&acpi_power_meter_driver); 999 if (result < 0) 1000 return -ENODEV; 1001 1002 return 0; 1003} 1004 1005static void __exit acpi_power_meter_exit(void) 1006{ 1007 acpi_bus_unregister_driver(&acpi_power_meter_driver); 1008} 1009 1010MODULE_AUTHOR("Darrick J. Wong <djwong@us.ibm.com>"); 1011MODULE_DESCRIPTION("ACPI 4.0 power meter driver"); 1012MODULE_LICENSE("GPL"); 1013 1014module_param(force_cap_on, bool, 0644); 1015MODULE_PARM_DESC(force_cap_on, "Enable power cap even it is unsafe to do so."); 1016 1017module_init(acpi_power_meter_init); 1018module_exit(acpi_power_meter_exit);