Commit 7d0333653840b0c692f55f1aaaa71d626fb00870

Authored by Jean Delvare
Committed by Jean Delvare
1 parent 629c58bac0

Move ACPI power meter driver to hwmon

As discussed earlier, the ACPI power meter driver would better live
in drivers/hwmon, as its only purpose is to create hwmon-style
interfaces for ACPI 4.0 power meter devices. Users are more likely to
look for it there, and less likely to accidentally hide it by
unselecting its dependencies.

Signed-off-by: Jean Delvare <khali@linux-fr.org>
Acked-by: "Darrick J. Wong" <djwong@us.ibm.com>
Acked-by: Guenter Roeck <guenter.roeck@ericsson.com>
Cc: Len Brown <lenb@kernel.org>

Showing 6 changed files with 1034 additions and 1035 deletions Side-by-side Diff

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