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