brintos

brintos / linux-shallow public Read only

0
0
Text · 23.9 KiB · 6c8a9c8 Raw
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