Some broken batteries like my DELL NR2227 or a friend's DELL GK4798 return the design_capacity (charge_full_design) as capacity_now (charge_now) when completely charged. I noticed this when looking at a battery plugin that reported "127% charged". Some of these plugins have already "fixed" this in userspace by coding something like min(percentage, 100)). Reading /sys/class/power_supply/BAT0/* my battery reported: charge_full = 5980000 charge_full_design = 7650000 I let my battery discharge a little bit and then I started charging it. At the same time, I read charge_now every second: ... 5850000 (charging) 5850000 (charging) 5850000 (charging) ... 5900000 (charging) 5900000 (charging) 5900000 (charging) ... 5950000 (charging) 5950000 (charging) 5950000 (charging) 7650000 (charged) 7650000 (charged) 7650000 (charged) 7650000 (charged) ... So I discovered that the battery wrongly returns charge_full_design when completely charged instead of charge_full. This patch fixes this by returning min(capacity_now, full_charge_capacity) on both procfs and sysfs. Now the userspace plugins report the correct 100% and their userspace check may not be needed (if this error is the only one producing >100% results). Signed-off-by: Miguel Ojeda <miguel.ojeda.sandonis@xxxxxxxxx> --- drivers/acpi/battery.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) --- linux-2.6.31.1/drivers/acpi/battery.c.old 2009-10-04 15:50:37.743999621 +0200 +++ linux-2.6.31.1/drivers/acpi/battery.c 2009-10-04 16:33:47.843696066 +0200 @@ -210,7 +210,10 @@ static int acpi_battery_get_property(str break; case POWER_SUPPLY_PROP_CHARGE_NOW: case POWER_SUPPLY_PROP_ENERGY_NOW: - val->intval = battery->capacity_now * 1000; + /* broken batteries return the design_capacity + as capacity_now when completely charged */ + val->intval = min(battery->capacity_now, + battery->full_charge_capacity) * 1000; break; case POWER_SUPPLY_PROP_MODEL_NAME: val->strval = battery->model_number; @@ -617,8 +620,12 @@ static int acpi_battery_print_state(stru if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN) seq_printf(seq, "remaining capacity: unknown\n"); else + /* broken batteries return the design_capacity + as capacity_now when completely charged */ seq_printf(seq, "remaining capacity: %d %sh\n", - battery->capacity_now, acpi_battery_units(battery)); + min(battery->capacity_now, + battery->full_charge_capacity), + acpi_battery_units(battery)); if (battery->voltage_now == ACPI_BATTERY_VALUE_UNKNOWN) seq_printf(seq, "present voltage: unknown\n"); else -- To unsubscribe from this list: send the line "unsubscribe linux-acpi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html