aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/battery.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/battery.c')
-rw-r--r--drivers/acpi/battery.c93
1 files changed, 72 insertions, 21 deletions
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index 58d2c91ba62b..3026e3fa83ef 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -32,6 +32,7 @@
32#include <linux/jiffies.h> 32#include <linux/jiffies.h>
33#include <linux/async.h> 33#include <linux/async.h>
34#include <linux/dmi.h> 34#include <linux/dmi.h>
35#include <linux/slab.h>
35 36
36#ifdef CONFIG_ACPI_PROCFS_POWER 37#ifdef CONFIG_ACPI_PROCFS_POWER
37#include <linux/proc_fs.h> 38#include <linux/proc_fs.h>
@@ -54,6 +55,7 @@
54#define ACPI_BATTERY_DEVICE_NAME "Battery" 55#define ACPI_BATTERY_DEVICE_NAME "Battery"
55#define ACPI_BATTERY_NOTIFY_STATUS 0x80 56#define ACPI_BATTERY_NOTIFY_STATUS 0x80
56#define ACPI_BATTERY_NOTIFY_INFO 0x81 57#define ACPI_BATTERY_NOTIFY_INFO 0x81
58#define ACPI_BATTERY_NOTIFY_THRESHOLD 0x82
57 59
58#define _COMPONENT ACPI_BATTERY_COMPONENT 60#define _COMPONENT ACPI_BATTERY_COMPONENT
59 61
@@ -88,10 +90,15 @@ static const struct acpi_device_id battery_device_ids[] = {
88 90
89MODULE_DEVICE_TABLE(acpi, battery_device_ids); 91MODULE_DEVICE_TABLE(acpi, battery_device_ids);
90 92
91/* For buggy DSDTs that report negative 16-bit values for either charging 93enum {
92 * or discharging current and/or report 0 as 65536 due to bad math. 94 ACPI_BATTERY_ALARM_PRESENT,
93 */ 95 ACPI_BATTERY_XINFO_PRESENT,
94#define QUIRK_SIGNED16_CURRENT 0x0001 96 /* For buggy DSDTs that report negative 16-bit values for either
97 * charging or discharging current and/or report 0 as 65536
98 * due to bad math.
99 */
100 ACPI_BATTERY_QUIRK_SIGNED16_CURRENT,
101};
95 102
96struct acpi_battery { 103struct acpi_battery {
97 struct mutex lock; 104 struct mutex lock;
@@ -109,6 +116,12 @@ struct acpi_battery {
109 int design_voltage; 116 int design_voltage;
110 int design_capacity_warning; 117 int design_capacity_warning;
111 int design_capacity_low; 118 int design_capacity_low;
119 int cycle_count;
120 int measurement_accuracy;
121 int max_sampling_time;
122 int min_sampling_time;
123 int max_averaging_interval;
124 int min_averaging_interval;
112 int capacity_granularity_1; 125 int capacity_granularity_1;
113 int capacity_granularity_2; 126 int capacity_granularity_2;
114 int alarm; 127 int alarm;
@@ -118,8 +131,7 @@ struct acpi_battery {
118 char oem_info[32]; 131 char oem_info[32];
119 int state; 132 int state;
120 int power_unit; 133 int power_unit;
121 u8 alarm_present; 134 unsigned long flags;
122 long quirks;
123}; 135};
124 136
125#define to_acpi_battery(x) container_of(x, struct acpi_battery, bat); 137#define to_acpi_battery(x) container_of(x, struct acpi_battery, bat);
@@ -198,6 +210,9 @@ static int acpi_battery_get_property(struct power_supply *psy,
198 case POWER_SUPPLY_PROP_TECHNOLOGY: 210 case POWER_SUPPLY_PROP_TECHNOLOGY:
199 val->intval = acpi_battery_technology(battery); 211 val->intval = acpi_battery_technology(battery);
200 break; 212 break;
213 case POWER_SUPPLY_PROP_CYCLE_COUNT:
214 val->intval = battery->cycle_count;
215 break;
201 case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: 216 case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
202 val->intval = battery->design_voltage * 1000; 217 val->intval = battery->design_voltage * 1000;
203 break; 218 break;
@@ -239,6 +254,7 @@ static enum power_supply_property charge_battery_props[] = {
239 POWER_SUPPLY_PROP_STATUS, 254 POWER_SUPPLY_PROP_STATUS,
240 POWER_SUPPLY_PROP_PRESENT, 255 POWER_SUPPLY_PROP_PRESENT,
241 POWER_SUPPLY_PROP_TECHNOLOGY, 256 POWER_SUPPLY_PROP_TECHNOLOGY,
257 POWER_SUPPLY_PROP_CYCLE_COUNT,
242 POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, 258 POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
243 POWER_SUPPLY_PROP_VOLTAGE_NOW, 259 POWER_SUPPLY_PROP_VOLTAGE_NOW,
244 POWER_SUPPLY_PROP_CURRENT_NOW, 260 POWER_SUPPLY_PROP_CURRENT_NOW,
@@ -254,6 +270,7 @@ static enum power_supply_property energy_battery_props[] = {
254 POWER_SUPPLY_PROP_STATUS, 270 POWER_SUPPLY_PROP_STATUS,
255 POWER_SUPPLY_PROP_PRESENT, 271 POWER_SUPPLY_PROP_PRESENT,
256 POWER_SUPPLY_PROP_TECHNOLOGY, 272 POWER_SUPPLY_PROP_TECHNOLOGY,
273 POWER_SUPPLY_PROP_CYCLE_COUNT,
257 POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, 274 POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
258 POWER_SUPPLY_PROP_VOLTAGE_NOW, 275 POWER_SUPPLY_PROP_VOLTAGE_NOW,
259 POWER_SUPPLY_PROP_CURRENT_NOW, 276 POWER_SUPPLY_PROP_CURRENT_NOW,
@@ -305,6 +322,28 @@ static struct acpi_offsets info_offsets[] = {
305 {offsetof(struct acpi_battery, oem_info), 1}, 322 {offsetof(struct acpi_battery, oem_info), 1},
306}; 323};
307 324
325static struct acpi_offsets extended_info_offsets[] = {
326 {offsetof(struct acpi_battery, power_unit), 0},
327 {offsetof(struct acpi_battery, design_capacity), 0},
328 {offsetof(struct acpi_battery, full_charge_capacity), 0},
329 {offsetof(struct acpi_battery, technology), 0},
330 {offsetof(struct acpi_battery, design_voltage), 0},
331 {offsetof(struct acpi_battery, design_capacity_warning), 0},
332 {offsetof(struct acpi_battery, design_capacity_low), 0},
333 {offsetof(struct acpi_battery, cycle_count), 0},
334 {offsetof(struct acpi_battery, measurement_accuracy), 0},
335 {offsetof(struct acpi_battery, max_sampling_time), 0},
336 {offsetof(struct acpi_battery, min_sampling_time), 0},
337 {offsetof(struct acpi_battery, max_averaging_interval), 0},
338 {offsetof(struct acpi_battery, min_averaging_interval), 0},
339 {offsetof(struct acpi_battery, capacity_granularity_1), 0},
340 {offsetof(struct acpi_battery, capacity_granularity_2), 0},
341 {offsetof(struct acpi_battery, model_number), 1},
342 {offsetof(struct acpi_battery, serial_number), 1},
343 {offsetof(struct acpi_battery, type), 1},
344 {offsetof(struct acpi_battery, oem_info), 1},
345};
346
308static int extract_package(struct acpi_battery *battery, 347static int extract_package(struct acpi_battery *battery,
309 union acpi_object *package, 348 union acpi_object *package,
310 struct acpi_offsets *offsets, int num) 349 struct acpi_offsets *offsets, int num)
@@ -350,22 +389,29 @@ static int acpi_battery_get_info(struct acpi_battery *battery)
350{ 389{
351 int result = -EFAULT; 390 int result = -EFAULT;
352 acpi_status status = 0; 391 acpi_status status = 0;
392 char *name = test_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags)?
393 "_BIX" : "_BIF";
394
353 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 395 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
354 396
355 if (!acpi_battery_present(battery)) 397 if (!acpi_battery_present(battery))
356 return 0; 398 return 0;
357 mutex_lock(&battery->lock); 399 mutex_lock(&battery->lock);
358 status = acpi_evaluate_object(battery->device->handle, "_BIF", 400 status = acpi_evaluate_object(battery->device->handle, name,
359 NULL, &buffer); 401 NULL, &buffer);
360 mutex_unlock(&battery->lock); 402 mutex_unlock(&battery->lock);
361 403
362 if (ACPI_FAILURE(status)) { 404 if (ACPI_FAILURE(status)) {
363 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BIF")); 405 ACPI_EXCEPTION((AE_INFO, status, "Evaluating %s", name));
364 return -ENODEV; 406 return -ENODEV;
365 } 407 }
366 408 if (test_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags))
367 result = extract_package(battery, buffer.pointer, 409 result = extract_package(battery, buffer.pointer,
368 info_offsets, ARRAY_SIZE(info_offsets)); 410 extended_info_offsets,
411 ARRAY_SIZE(extended_info_offsets));
412 else
413 result = extract_package(battery, buffer.pointer,
414 info_offsets, ARRAY_SIZE(info_offsets));
369 kfree(buffer.pointer); 415 kfree(buffer.pointer);
370 return result; 416 return result;
371} 417}
@@ -399,7 +445,7 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
399 battery->update_time = jiffies; 445 battery->update_time = jiffies;
400 kfree(buffer.pointer); 446 kfree(buffer.pointer);
401 447
402 if ((battery->quirks & QUIRK_SIGNED16_CURRENT) && 448 if (test_bit(ACPI_BATTERY_QUIRK_SIGNED16_CURRENT, &battery->flags) &&
403 battery->rate_now != -1) 449 battery->rate_now != -1)
404 battery->rate_now = abs((s16)battery->rate_now); 450 battery->rate_now = abs((s16)battery->rate_now);
405 451
@@ -412,7 +458,8 @@ static int acpi_battery_set_alarm(struct acpi_battery *battery)
412 union acpi_object arg0 = { .type = ACPI_TYPE_INTEGER }; 458 union acpi_object arg0 = { .type = ACPI_TYPE_INTEGER };
413 struct acpi_object_list arg_list = { 1, &arg0 }; 459 struct acpi_object_list arg_list = { 1, &arg0 };
414 460
415 if (!acpi_battery_present(battery)|| !battery->alarm_present) 461 if (!acpi_battery_present(battery) ||
462 !test_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags))
416 return -ENODEV; 463 return -ENODEV;
417 464
418 arg0.integer.value = battery->alarm; 465 arg0.integer.value = battery->alarm;
@@ -437,10 +484,10 @@ static int acpi_battery_init_alarm(struct acpi_battery *battery)
437 /* See if alarms are supported, and if so, set default */ 484 /* See if alarms are supported, and if so, set default */
438 status = acpi_get_handle(battery->device->handle, "_BTP", &handle); 485 status = acpi_get_handle(battery->device->handle, "_BTP", &handle);
439 if (ACPI_FAILURE(status)) { 486 if (ACPI_FAILURE(status)) {
440 battery->alarm_present = 0; 487 clear_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags);
441 return 0; 488 return 0;
442 } 489 }
443 battery->alarm_present = 1; 490 set_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags);
444 if (!battery->alarm) 491 if (!battery->alarm)
445 battery->alarm = battery->design_capacity_warning; 492 battery->alarm = battery->design_capacity_warning;
446 return acpi_battery_set_alarm(battery); 493 return acpi_battery_set_alarm(battery);
@@ -510,9 +557,8 @@ static void sysfs_remove_battery(struct acpi_battery *battery)
510 557
511static void acpi_battery_quirks(struct acpi_battery *battery) 558static void acpi_battery_quirks(struct acpi_battery *battery)
512{ 559{
513 battery->quirks = 0;
514 if (dmi_name_in_vendors("Acer") && battery->power_unit) { 560 if (dmi_name_in_vendors("Acer") && battery->power_unit) {
515 battery->quirks |= QUIRK_SIGNED16_CURRENT; 561 set_bit(ACPI_BATTERY_QUIRK_SIGNED16_CURRENT, &battery->flags);
516 } 562 }
517} 563}
518 564
@@ -522,13 +568,13 @@ static int acpi_battery_update(struct acpi_battery *battery)
522 result = acpi_battery_get_status(battery); 568 result = acpi_battery_get_status(battery);
523 if (result) 569 if (result)
524 return result; 570 return result;
525#ifdef CONFIG_ACPI_SYSFS_POWER
526 if (!acpi_battery_present(battery)) { 571 if (!acpi_battery_present(battery)) {
572#ifdef CONFIG_ACPI_SYSFS_POWER
527 sysfs_remove_battery(battery); 573 sysfs_remove_battery(battery);
574#endif
528 battery->update_time = 0; 575 battery->update_time = 0;
529 return 0; 576 return 0;
530 } 577 }
531#endif
532 if (!battery->update_time || 578 if (!battery->update_time ||
533 old_present != acpi_battery_present(battery)) { 579 old_present != acpi_battery_present(battery)) {
534 result = acpi_battery_get_info(battery); 580 result = acpi_battery_get_info(battery);
@@ -590,6 +636,7 @@ static int acpi_battery_print_info(struct seq_file *seq, int result)
590 seq_printf(seq, "design capacity low: %d %sh\n", 636 seq_printf(seq, "design capacity low: %d %sh\n",
591 battery->design_capacity_low, 637 battery->design_capacity_low,
592 acpi_battery_units(battery)); 638 acpi_battery_units(battery));
639 seq_printf(seq, "cycle count: %i\n", battery->cycle_count);
593 seq_printf(seq, "capacity granularity 1: %d %sh\n", 640 seq_printf(seq, "capacity granularity 1: %d %sh\n",
594 battery->capacity_granularity_1, 641 battery->capacity_granularity_1,
595 acpi_battery_units(battery)); 642 acpi_battery_units(battery));
@@ -833,7 +880,7 @@ static void acpi_battery_notify(struct acpi_device *device, u32 event)
833#ifdef CONFIG_ACPI_SYSFS_POWER 880#ifdef CONFIG_ACPI_SYSFS_POWER
834 /* acpi_battery_update could remove power_supply object */ 881 /* acpi_battery_update could remove power_supply object */
835 if (battery->bat.dev) 882 if (battery->bat.dev)
836 kobject_uevent(&battery->bat.dev->kobj, KOBJ_CHANGE); 883 power_supply_changed(&battery->bat);
837#endif 884#endif
838} 885}
839 886
@@ -841,6 +888,7 @@ static int acpi_battery_add(struct acpi_device *device)
841{ 888{
842 int result = 0; 889 int result = 0;
843 struct acpi_battery *battery = NULL; 890 struct acpi_battery *battery = NULL;
891 acpi_handle handle;
844 if (!device) 892 if (!device)
845 return -EINVAL; 893 return -EINVAL;
846 battery = kzalloc(sizeof(struct acpi_battery), GFP_KERNEL); 894 battery = kzalloc(sizeof(struct acpi_battery), GFP_KERNEL);
@@ -851,6 +899,9 @@ static int acpi_battery_add(struct acpi_device *device)
851 strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS); 899 strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS);
852 device->driver_data = battery; 900 device->driver_data = battery;
853 mutex_init(&battery->lock); 901 mutex_init(&battery->lock);
902 if (ACPI_SUCCESS(acpi_get_handle(battery->device->handle,
903 "_BIX", &handle)))
904 set_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags);
854 acpi_battery_update(battery); 905 acpi_battery_update(battery);
855#ifdef CONFIG_ACPI_PROCFS_POWER 906#ifdef CONFIG_ACPI_PROCFS_POWER
856 result = acpi_battery_add_fs(device); 907 result = acpi_battery_add_fs(device);