ACPI: battery: do not export degraded capacity values over 100
PATCH 1/1 ACPI: battery: do not export degraded capacity values over 100
With a degraded battery, full_charge_capacity can be less than design_capacity, however it's not sure that capacity_now's max will follow.
Example from an affected machine:/sys/class/power_supply/BAT0/charge_full -> 4290000/sys/class/power_supply/BAT0/charge_full_design -> 5900000/sys/class/power_supply/BAT0/charge_now -> 5900000/sys/class/power_supply/BAT0/capacity -> 137
The battery is a degraded one with a full charge, and charge_now is the value of charge_full_design instead of charge_full.
Added a new quirk to test and correct this, and a new function to check if the battery is a degraded one or not. This keeps the possibility to be over 100 if it's really the case.
--- drivers/acpi/battery.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+)
drivers/acpi/battery.c +28 -0
@@ -116,6 +116,10 @@ enum {post-1.29 BIOS), but as of Nov. 2012, no such update is available for the 2010 models. */ ACPI_BATTERY_QUIRK_THINKPAD_MAH , +/* for batteries reporting current capacity with design capacity +* on a full charge, but showing degradation in full charge cap. +*/ + ACPI_BATTERY_QUIRK_DESIGN_MAX_CAPACITY, }; struct acpi_battery {
@@ -201,6 +205,13 @@ static int acpi_battery_is_charged(struct acpi_battery *battery)return 0 ; } +static inline int acpi_battery_is_degraded (struct acpi_battery *battery) +{ +if (battery->full_charge_capacity && battery->design_capacity) +return battery->full_charge_capacity < battery->design_capacity; +return 0 ; +} +static int acpi_battery_get_property (struct power_supply *psy,enum power_supply_property psp,union power_supply_propval *val)
@@ -475,6 +486,9 @@ static int extract_battery_info(const int use_bix,it's impossible to tell if they would need an adjustment or not if their values were higher. */ } +if (test_bit (ACPI_BATTERY_QUIRK_DESIGN_MAX_CAPACITY , &battery->flags) && + battery->capacity_now > battery->full_charge_capacity) + battery->capacity_now = battery->full_charge_capacity;return result; }
@@ -567,6 +581,10 @@ static int acpi_battery_get_state(struct acpi_battery *battery) battery->capacity_now = battery->capacity_now *10000 / battery->design_voltage; } +if (test_bit (ACPI_BATTERY_QUIRK_DESIGN_MAX_CAPACITY , &battery->flags) && + battery->capacity_now > battery->full_charge_capacity) + battery->capacity_now = battery->full_charge_capacity; +return result; }
@@ -743,6 +761,16 @@ static void acpi_battery_quirks(struct acpi_battery *battery) } } } + +if (test_bit (ACPI_BATTERY_QUIRK_DESIGN_MAX_CAPACITY , &battery->flags)) +return ; + +if (acpi_battery_is_degraded (battery) && + battery->capacity_now > battery->full_charge_capacity) { +set_bit (ACPI_BATTERY_QUIRK_DESIGN_MAX_CAPACITY , + &battery->flags); + battery->capacity_now = battery->full_charge_capacity; + } }static int acpi_battery_update (struct acpi_battery *battery,bool resume)
Signature · 1 line
2.7.4