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.c68
1 files changed, 58 insertions, 10 deletions
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index b2b48f8545c7..1ca0ea77115b 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
@@ -90,9 +91,11 @@ MODULE_DEVICE_TABLE(acpi, battery_device_ids);
90 91
91enum { 92enum {
92 ACPI_BATTERY_ALARM_PRESENT, 93 ACPI_BATTERY_ALARM_PRESENT,
93 /* For buggy DSDTs that report negative 16-bit values for either charging 94 ACPI_BATTERY_XINFO_PRESENT,
94 * or discharging current and/or report 0 as 65536 due to bad math. 95 /* For buggy DSDTs that report negative 16-bit values for either
95 */ 96 * charging or discharging current and/or report 0 as 65536
97 * due to bad math.
98 */
96 ACPI_BATTERY_QUIRK_SIGNED16_CURRENT, 99 ACPI_BATTERY_QUIRK_SIGNED16_CURRENT,
97}; 100};
98 101
@@ -112,6 +115,12 @@ struct acpi_battery {
112 int design_voltage; 115 int design_voltage;
113 int design_capacity_warning; 116 int design_capacity_warning;
114 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;
115 int capacity_granularity_1; 124 int capacity_granularity_1;
116 int capacity_granularity_2; 125 int capacity_granularity_2;
117 int alarm; 126 int alarm;
@@ -200,6 +209,9 @@ static int acpi_battery_get_property(struct power_supply *psy,
200 case POWER_SUPPLY_PROP_TECHNOLOGY: 209 case POWER_SUPPLY_PROP_TECHNOLOGY:
201 val->intval = acpi_battery_technology(battery); 210 val->intval = acpi_battery_technology(battery);
202 break; 211 break;
212 case POWER_SUPPLY_PROP_CYCLE_COUNT:
213 val->intval = battery->cycle_count;
214 break;
203 case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: 215 case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
204 val->intval = battery->design_voltage * 1000; 216 val->intval = battery->design_voltage * 1000;
205 break; 217 break;
@@ -241,6 +253,7 @@ static enum power_supply_property charge_battery_props[] = {
241 POWER_SUPPLY_PROP_STATUS, 253 POWER_SUPPLY_PROP_STATUS,
242 POWER_SUPPLY_PROP_PRESENT, 254 POWER_SUPPLY_PROP_PRESENT,
243 POWER_SUPPLY_PROP_TECHNOLOGY, 255 POWER_SUPPLY_PROP_TECHNOLOGY,
256 POWER_SUPPLY_PROP_CYCLE_COUNT,
244 POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, 257 POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
245 POWER_SUPPLY_PROP_VOLTAGE_NOW, 258 POWER_SUPPLY_PROP_VOLTAGE_NOW,
246 POWER_SUPPLY_PROP_CURRENT_NOW, 259 POWER_SUPPLY_PROP_CURRENT_NOW,
@@ -256,6 +269,7 @@ static enum power_supply_property energy_battery_props[] = {
256 POWER_SUPPLY_PROP_STATUS, 269 POWER_SUPPLY_PROP_STATUS,
257 POWER_SUPPLY_PROP_PRESENT, 270 POWER_SUPPLY_PROP_PRESENT,
258 POWER_SUPPLY_PROP_TECHNOLOGY, 271 POWER_SUPPLY_PROP_TECHNOLOGY,
272 POWER_SUPPLY_PROP_CYCLE_COUNT,
259 POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, 273 POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
260 POWER_SUPPLY_PROP_VOLTAGE_NOW, 274 POWER_SUPPLY_PROP_VOLTAGE_NOW,
261 POWER_SUPPLY_PROP_CURRENT_NOW, 275 POWER_SUPPLY_PROP_CURRENT_NOW,
@@ -307,6 +321,28 @@ static struct acpi_offsets info_offsets[] = {
307 {offsetof(struct acpi_battery, oem_info), 1}, 321 {offsetof(struct acpi_battery, oem_info), 1},
308}; 322};
309 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
310static int extract_package(struct acpi_battery *battery, 346static int extract_package(struct acpi_battery *battery,
311 union acpi_object *package, 347 union acpi_object *package,
312 struct acpi_offsets *offsets, int num) 348 struct acpi_offsets *offsets, int num)
@@ -352,22 +388,29 @@ static int acpi_battery_get_info(struct acpi_battery *battery)
352{ 388{
353 int result = -EFAULT; 389 int result = -EFAULT;
354 acpi_status status = 0; 390 acpi_status status = 0;
391 char *name = test_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags)?
392 "_BIX" : "_BIF";
393
355 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 394 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
356 395
357 if (!acpi_battery_present(battery)) 396 if (!acpi_battery_present(battery))
358 return 0; 397 return 0;
359 mutex_lock(&battery->lock); 398 mutex_lock(&battery->lock);
360 status = acpi_evaluate_object(battery->device->handle, "_BIF", 399 status = acpi_evaluate_object(battery->device->handle, name,
361 NULL, &buffer); 400 NULL, &buffer);
362 mutex_unlock(&battery->lock); 401 mutex_unlock(&battery->lock);
363 402
364 if (ACPI_FAILURE(status)) { 403 if (ACPI_FAILURE(status)) {
365 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BIF")); 404 ACPI_EXCEPTION((AE_INFO, status, "Evaluating %s", name));
366 return -ENODEV; 405 return -ENODEV;
367 } 406 }
368 407 if (test_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags))
369 result = extract_package(battery, buffer.pointer, 408 result = extract_package(battery, buffer.pointer,
370 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));
371 kfree(buffer.pointer); 414 kfree(buffer.pointer);
372 return result; 415 return result;
373} 416}
@@ -414,7 +457,7 @@ static int acpi_battery_set_alarm(struct acpi_battery *battery)
414 union acpi_object arg0 = { .type = ACPI_TYPE_INTEGER }; 457 union acpi_object arg0 = { .type = ACPI_TYPE_INTEGER };
415 struct acpi_object_list arg_list = { 1, &arg0 }; 458 struct acpi_object_list arg_list = { 1, &arg0 };
416 459
417 if (!acpi_battery_present(battery)|| 460 if (!acpi_battery_present(battery) ||
418 !test_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags)) 461 !test_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags))
419 return -ENODEV; 462 return -ENODEV;
420 463
@@ -592,6 +635,7 @@ static int acpi_battery_print_info(struct seq_file *seq, int result)
592 seq_printf(seq, "design capacity low: %d %sh\n", 635 seq_printf(seq, "design capacity low: %d %sh\n",
593 battery->design_capacity_low, 636 battery->design_capacity_low,
594 acpi_battery_units(battery)); 637 acpi_battery_units(battery));
638 seq_printf(seq, "cycle count: %i\n", battery->cycle_count);
595 seq_printf(seq, "capacity granularity 1: %d %sh\n", 639 seq_printf(seq, "capacity granularity 1: %d %sh\n",
596 battery->capacity_granularity_1, 640 battery->capacity_granularity_1,
597 acpi_battery_units(battery)); 641 acpi_battery_units(battery));
@@ -843,6 +887,7 @@ static int acpi_battery_add(struct acpi_device *device)
843{ 887{
844 int result = 0; 888 int result = 0;
845 struct acpi_battery *battery = NULL; 889 struct acpi_battery *battery = NULL;
890 acpi_handle handle;
846 if (!device) 891 if (!device)
847 return -EINVAL; 892 return -EINVAL;
848 battery = kzalloc(sizeof(struct acpi_battery), GFP_KERNEL); 893 battery = kzalloc(sizeof(struct acpi_battery), GFP_KERNEL);
@@ -853,6 +898,9 @@ static int acpi_battery_add(struct acpi_device *device)
853 strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS); 898 strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS);
854 device->driver_data = battery; 899 device->driver_data = battery;
855 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);
856 acpi_battery_update(battery); 904 acpi_battery_update(battery);
857#ifdef CONFIG_ACPI_PROCFS_POWER 905#ifdef CONFIG_ACPI_PROCFS_POWER
858 result = acpi_battery_add_fs(device); 906 result = acpi_battery_add_fs(device);