Skip to content

Commit

Permalink
ACPI battery: support percentage battery remaining capacity
Browse files Browse the repository at this point in the history
According to the ACPI spec, some kinds of primary battery can
report percentage battery remaining capacity directly to OS.

In this case, it reports the LastFullChargedCapacity == 100,
BatteryPresentRate = 0xFFFFFFFF, and BatteryRemaingCapacity a
percentage value, which actually means RemainingBatteryPercentage.

Now we found some battery follows this rule even if it's a rechargeable.
https://bugzilla.kernel.org/show_bug.cgi?id=15979

Handle these batteries correctly in ACPI battery driver
so that they won't break userspace.

Signed-off-by: Zhang Rui <rui.zhang@intel.com>
Tested-by: Sitsofe Wheeler <sitsofe@yahoo.com>
Signed-off-by: Len Brown <len.brown@intel.com>
  • Loading branch information
Zhang Rui authored and Len Brown committed Oct 22, 2010
1 parent 03e7c34 commit 557d586
Showing 1 changed file with 37 additions and 1 deletion.
38 changes: 37 additions & 1 deletion drivers/acpi/battery.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ enum {
* due to bad math.
*/
ACPI_BATTERY_QUIRK_SIGNED16_CURRENT,
ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY,
};

struct acpi_battery {
Expand Down Expand Up @@ -405,6 +406,8 @@ static int acpi_battery_get_info(struct acpi_battery *battery)
result = extract_package(battery, buffer.pointer,
info_offsets, ARRAY_SIZE(info_offsets));
kfree(buffer.pointer);
if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags))
battery->full_charge_capacity = battery->design_capacity;
return result;
}

Expand Down Expand Up @@ -441,6 +444,10 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
battery->rate_now != -1)
battery->rate_now = abs((s16)battery->rate_now);

if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags)
&& battery->capacity_now >= 0 && battery->capacity_now <= 100)
battery->capacity_now = (battery->capacity_now *
battery->full_charge_capacity) / 100;
return result;
}

Expand Down Expand Up @@ -552,6 +559,33 @@ static void acpi_battery_quirks(struct acpi_battery *battery)
}
}

/*
* According to the ACPI spec, some kinds of primary batteries can
* report percentage battery remaining capacity directly to OS.
* In this case, it reports the Last Full Charged Capacity == 100
* and BatteryPresentRate == 0xFFFFFFFF.
*
* Now we found some battery reports percentage remaining capacity
* even if it's rechargeable.
* https://bugzilla.kernel.org/show_bug.cgi?id=15979
*
* Handle this correctly so that they won't break userspace.
*/
static void acpi_battery_quirks2(struct acpi_battery *battery)
{
if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags))
return ;

if (battery->full_charge_capacity == 100 &&
battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN &&
battery->capacity_now >=0 && battery->capacity_now <= 100) {
set_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags);
battery->full_charge_capacity = battery->design_capacity;
battery->capacity_now = (battery->capacity_now *
battery->full_charge_capacity) / 100;
}
}

static int acpi_battery_update(struct acpi_battery *battery)
{
int result, old_present = acpi_battery_present(battery);
Expand All @@ -573,7 +607,9 @@ static int acpi_battery_update(struct acpi_battery *battery)
}
if (!battery->bat.dev)
sysfs_add_battery(battery);
return acpi_battery_get_state(battery);
result = acpi_battery_get_state(battery);
acpi_battery_quirks2(battery);
return result;
}

/* --------------------------------------------------------------------------
Expand Down

0 comments on commit 557d586

Please sign in to comment.