ACPI battery: support percentage battery remaining capacity
PATCH RESEND 1/1 ACPI battery: support percentage battery remaining capacity
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.
--- drivers/acpi/battery.c | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-)
drivers/acpi/battery.c +37 -1
@@ -95,6 +95,7 @@ enum {* due to bad math. */ ACPI_BATTERY_QUIRK_SIGNED16_CURRENT , + ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, }; struct acpi_battery {
@@ -405,6 +406,8 @@ static int acpi_battery_get_info(struct 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; }
@@ -441,6 +444,10 @@ static int acpi_battery_get_state(struct 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; }
@@ -552,6 +559,33 @@ static void acpi_battery_quirks(struct a } } +/* +* 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);
@@ -573,7 +607,9 @@ static int acpi_battery_update(struct ac }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; }/* --------------------------------------------------------------------------
Quoted 7 lines · Zhang Rui
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.
Quoted 7 lines
Now we found some battery follows this rule even if it's a rechargeable.
https://bugzilla.kernel.org/show_bug.cgi?id=15979Handle these batteries correctly in ACPI battery driver so that they won't break userspace.
Signed-off-by Zhang Rui <[email protected]>
Quoted 82 lines
--- drivers/acpi/battery.c | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-)Index:
linux-2.6/drivers/acpi/battery.c
===================================================================drivers/acpi/battery.c +37
-1@@ -95,6 +95,7 @@ enum {* due to bad math. */ ACPI_BATTERY_QUIRK_SIGNED16_CURRENT , + ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, }; struct acpi_battery {@@ -405,6 +406,8 @@ static int acpi_battery_get_info(struct 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; }@@ -441,6 +444,10 @@ static int acpi_battery_get_state(struct 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; }@@ -552,6 +559,33 @@ static void acpi_battery_quirks(struct a } } +/* +* 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);@@ -573,7 +607,9 @@ static int acpi_battery_update(struct ac }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; }/* --------------------------------------------------------------------------
applied
thanks,
Len Brown, Intel Open Source Technology Center