aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 7b8787b490f6..0b2707ee094b 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -95,6 +95,7 @@ enum {
95 * due to bad math. 95 * due to bad math.
96 */ 96 */
97 ACPI_BATTERY_QUIRK_SIGNED16_CURRENT, 97 ACPI_BATTERY_QUIRK_SIGNED16_CURRENT,
98 ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY,
98}; 99};
99 100
100struct acpi_battery { 101struct acpi_battery {
@@ -405,6 +406,8 @@ static int acpi_battery_get_info(struct acpi_battery *battery)
405 result = extract_package(battery, buffer.pointer, 406 result = extract_package(battery, buffer.pointer,
406 info_offsets, ARRAY_SIZE(info_offsets)); 407 info_offsets, ARRAY_SIZE(info_offsets));
407 kfree(buffer.pointer); 408 kfree(buffer.pointer);
409 if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags))
410 battery->full_charge_capacity = battery->design_capacity;
408 return result; 411 return result;
409} 412}
410 413
@@ -441,6 +444,10 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
441 battery->rate_now != -1) 444 battery->rate_now != -1)
442 battery->rate_now = abs((s16)battery->rate_now); 445 battery->rate_now = abs((s16)battery->rate_now);
443 446
447 if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags)
448 && battery->capacity_now >= 0 && battery->capacity_now <= 100)
449 battery->capacity_now = (battery->capacity_now *
450 battery->full_charge_capacity) / 100;
444 return result; 451 return result;
445} 452}
446 453
@@ -552,6 +559,33 @@ static void acpi_battery_quirks(struct acpi_battery *battery)
552 } 559 }
553} 560}
554 561
562/*
563 * According to the ACPI spec, some kinds of primary batteries can
564 * report percentage battery remaining capacity directly to OS.
565 * In this case, it reports the Last Full Charged Capacity == 100
566 * and BatteryPresentRate == 0xFFFFFFFF.
567 *
568 * Now we found some battery reports percentage remaining capacity
569 * even if it's rechargeable.
570 * https://bugzilla.kernel.org/show_bug.cgi?id=15979
571 *
572 * Handle this correctly so that they won't break userspace.
573 */
574static void acpi_battery_quirks2(struct acpi_battery *battery)
575{
576 if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags))
577 return ;
578
579 if (battery->full_charge_capacity == 100 &&
580 battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN &&
581 battery->capacity_now >=0 && battery->capacity_now <= 100) {
582 set_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags);
583 battery->full_charge_capacity = battery->design_capacity;
584 battery->capacity_now = (battery->capacity_now *
585 battery->full_charge_capacity) / 100;
586 }
587}
588
555static int acpi_battery_update(struct acpi_battery *battery) 589static int acpi_battery_update(struct acpi_battery *battery)
556{ 590{
557 int result, old_present = acpi_battery_present(battery); 591 int result, old_present = acpi_battery_present(battery);
@@ -573,7 +607,9 @@ static int acpi_battery_update(struct acpi_battery *battery)
573 } 607 }
574 if (!battery->bat.dev) 608 if (!battery->bat.dev)
575 sysfs_add_battery(battery); 609 sysfs_add_battery(battery);
576 return acpi_battery_get_state(battery); 610 result = acpi_battery_get_state(battery);
611 acpi_battery_quirks2(battery);
612 return result;
577} 613}
578 614
579/* -------------------------------------------------------------------------- 615/* --------------------------------------------------------------------------