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