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