aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/battery.c
diff options
context:
space:
mode:
authorJeremy Erickson <jerickso@cs.unc.edu>2014-04-18 17:06:00 -0400
committerJeremy Erickson <jerickso@cs.unc.edu>2014-04-18 17:06:00 -0400
commita215aa7b9ab3759c047201199fba64d3042d7f13 (patch)
treebca37493d9b2233450e6d3ffced1261d0e4f71fe /drivers/acpi/battery.c
parentd31199a77ef606f1d06894385f1852181ba6136b (diff)
Update 2.6.36 to 2.6.36.4wip-dissipation2-jerickso
Diffstat (limited to 'drivers/acpi/battery.c')
-rw-r--r--drivers/acpi/battery.c38
1 files changed, 37 insertions, 1 deletions
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index 98417201e9ce..4c0a0a37d46e 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -98,6 +98,7 @@ enum {
98 * due to bad math. 98 * due to bad math.
99 */ 99 */
100 ACPI_BATTERY_QUIRK_SIGNED16_CURRENT, 100 ACPI_BATTERY_QUIRK_SIGNED16_CURRENT,
101 ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY,
101}; 102};
102 103
103struct acpi_battery { 104struct acpi_battery {
@@ -412,6 +413,8 @@ static int acpi_battery_get_info(struct acpi_battery *battery)
412 result = extract_package(battery, buffer.pointer, 413 result = extract_package(battery, buffer.pointer,
413 info_offsets, ARRAY_SIZE(info_offsets)); 414 info_offsets, ARRAY_SIZE(info_offsets));
414 kfree(buffer.pointer); 415 kfree(buffer.pointer);
416 if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags))
417 battery->full_charge_capacity = battery->design_capacity;
415 return result; 418 return result;
416} 419}
417 420
@@ -448,6 +451,10 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
448 battery->rate_now != -1) 451 battery->rate_now != -1)
449 battery->rate_now = abs((s16)battery->rate_now); 452 battery->rate_now = abs((s16)battery->rate_now);
450 453
454 if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags)
455 && battery->capacity_now >= 0 && battery->capacity_now <= 100)
456 battery->capacity_now = (battery->capacity_now *
457 battery->full_charge_capacity) / 100;
451 return result; 458 return result;
452} 459}
453 460
@@ -561,6 +568,33 @@ static void acpi_battery_quirks(struct acpi_battery *battery)
561 } 568 }
562} 569}
563 570
571/*
572 * According to the ACPI spec, some kinds of primary batteries can
573 * report percentage battery remaining capacity directly to OS.
574 * In this case, it reports the Last Full Charged Capacity == 100
575 * and BatteryPresentRate == 0xFFFFFFFF.
576 *
577 * Now we found some battery reports percentage remaining capacity
578 * even if it's rechargeable.
579 * https://bugzilla.kernel.org/show_bug.cgi?id=15979
580 *
581 * Handle this correctly so that they won't break userspace.
582 */
583static void acpi_battery_quirks2(struct acpi_battery *battery)
584{
585 if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags))
586 return ;
587
588 if (battery->full_charge_capacity == 100 &&
589 battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN &&
590 battery->capacity_now >=0 && battery->capacity_now <= 100) {
591 set_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags);
592 battery->full_charge_capacity = battery->design_capacity;
593 battery->capacity_now = (battery->capacity_now *
594 battery->full_charge_capacity) / 100;
595 }
596}
597
564static int acpi_battery_update(struct acpi_battery *battery) 598static int acpi_battery_update(struct acpi_battery *battery)
565{ 599{
566 int result, old_present = acpi_battery_present(battery); 600 int result, old_present = acpi_battery_present(battery);
@@ -586,7 +620,9 @@ static int acpi_battery_update(struct acpi_battery *battery)
586 if (!battery->bat.dev) 620 if (!battery->bat.dev)
587 sysfs_add_battery(battery); 621 sysfs_add_battery(battery);
588#endif 622#endif
589 return acpi_battery_get_state(battery); 623 result = acpi_battery_get_state(battery);
624 acpi_battery_quirks2(battery);
625 return result;
590} 626}
591 627
592/* -------------------------------------------------------------------------- 628/* --------------------------------------------------------------------------