[PATCH] ACPI: battery: Fix bogus cycle count values on systems without _BIX
Armin Wolf <[email protected]> Fri, 7 Aug 2026 01:38:17 +0200
| Newsgroups | gmane.linux.kernel,gmane.linux.acpi.devel |
|---|---|
| Message-ID | <[email protected]> |
Devices supporting only the legacy _BIF ACPI control method cannot know the cycle count of the associated battery, so cycle_count always remains 0. Claiming support for POWER_SUPPLY_PROP_CYCLE_COUNT on such devices can thus mislead userspace applications and prevents power supply extensions from supplying correct cycle count values. Fix this by not claiming support for POWER_SUPPLY_PROP_CYCLE_COUNT on devices without _BIX. Signed-off-by: Armin Wolf <[email protected]> --- drivers/acpi/battery.c | 131 +++++++++++++++++++++++++++++++++++------ 1 file changed, 113 insertions(+), 18 deletions(-) diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 0084f308b790..b64f876f93cb 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -324,7 +324,9 @@ static int acpi_battery_get_property(struct power_supply *psy, return ret; } -static const enum power_supply_property charge_battery_props[] = { +/* For devices supporting the _BIX ACPI control method */ + +static const enum power_supply_property charge_battery_extended_props[] = { POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_PROP_PRESENT, POWER_SUPPLY_PROP_TECHNOLOGY, @@ -342,7 +344,7 @@ static const enum power_supply_property charge_battery_props[] = { POWER_SUPPLY_PROP_SERIAL_NUMBER, }; -static const enum power_supply_property charge_battery_full_cap_broken_props[] = { +static const enum power_supply_property charge_battery_full_cap_broken_extended_props[] = { POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_PROP_PRESENT, POWER_SUPPLY_PROP_TECHNOLOGY, @@ -356,7 +358,7 @@ static const enum power_supply_property charge_battery_full_cap_broken_props[] = POWER_SUPPLY_PROP_SERIAL_NUMBER, }; -static const enum power_supply_property energy_battery_props[] = { +static const enum power_supply_property energy_battery_extended_props[] = { POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_PROP_PRESENT, POWER_SUPPLY_PROP_TECHNOLOGY, @@ -374,7 +376,7 @@ static const enum power_supply_property energy_battery_props[] = { POWER_SUPPLY_PROP_SERIAL_NUMBER, }; -static const enum power_supply_property energy_battery_full_cap_broken_props[] = { +static const enum power_supply_property energy_battery_full_cap_broken_extended_props[] = { POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_PROP_PRESENT, POWER_SUPPLY_PROP_TECHNOLOGY, @@ -388,6 +390,68 @@ static const enum power_supply_property energy_battery_full_cap_broken_props[] = POWER_SUPPLY_PROP_SERIAL_NUMBER, }; +/* For devices supporting only the _BIF ACPI control method */ + +static const enum power_supply_property charge_battery_props[] = { + POWER_SUPPLY_PROP_STATUS, + POWER_SUPPLY_PROP_PRESENT, + POWER_SUPPLY_PROP_TECHNOLOGY, + POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, + POWER_SUPPLY_PROP_VOLTAGE_NOW, + POWER_SUPPLY_PROP_CURRENT_NOW, + POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, + POWER_SUPPLY_PROP_CHARGE_FULL, + POWER_SUPPLY_PROP_CHARGE_NOW, + POWER_SUPPLY_PROP_CAPACITY, + POWER_SUPPLY_PROP_CAPACITY_LEVEL, + POWER_SUPPLY_PROP_MODEL_NAME, + POWER_SUPPLY_PROP_MANUFACTURER, + POWER_SUPPLY_PROP_SERIAL_NUMBER, +}; + +static const enum power_supply_property charge_battery_full_cap_broken_props[] = { + POWER_SUPPLY_PROP_STATUS, + POWER_SUPPLY_PROP_PRESENT, + POWER_SUPPLY_PROP_TECHNOLOGY, + POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, + POWER_SUPPLY_PROP_VOLTAGE_NOW, + POWER_SUPPLY_PROP_CURRENT_NOW, + POWER_SUPPLY_PROP_CHARGE_NOW, + POWER_SUPPLY_PROP_MODEL_NAME, + POWER_SUPPLY_PROP_MANUFACTURER, + POWER_SUPPLY_PROP_SERIAL_NUMBER, +}; + +static const enum power_supply_property energy_battery_props[] = { + POWER_SUPPLY_PROP_STATUS, + POWER_SUPPLY_PROP_PRESENT, + POWER_SUPPLY_PROP_TECHNOLOGY, + POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, + POWER_SUPPLY_PROP_VOLTAGE_NOW, + POWER_SUPPLY_PROP_POWER_NOW, + POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN, + POWER_SUPPLY_PROP_ENERGY_FULL, + POWER_SUPPLY_PROP_ENERGY_NOW, + POWER_SUPPLY_PROP_CAPACITY, + POWER_SUPPLY_PROP_CAPACITY_LEVEL, + POWER_SUPPLY_PROP_MODEL_NAME, + POWER_SUPPLY_PROP_MANUFACTURER, + POWER_SUPPLY_PROP_SERIAL_NUMBER, +}; + +static const enum power_supply_property energy_battery_full_cap_broken_props[] = { + POWER_SUPPLY_PROP_STATUS, + POWER_SUPPLY_PROP_PRESENT, + POWER_SUPPLY_PROP_TECHNOLOGY, + POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, + POWER_SUPPLY_PROP_VOLTAGE_NOW, + POWER_SUPPLY_PROP_POWER_NOW, + POWER_SUPPLY_PROP_ENERGY_NOW, + POWER_SUPPLY_PROP_MODEL_NAME, + POWER_SUPPLY_PROP_MANUFACTURER, + POWER_SUPPLY_PROP_SERIAL_NUMBER, +}; + /* Battery Management */ struct acpi_offsets { size_t offset; /* offset inside struct acpi_sbs_battery */ @@ -875,6 +939,7 @@ static void __exit battery_hook_exit(void) static int sysfs_add_battery(struct acpi_battery *battery) { + bool extended_info_available = test_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags); struct power_supply_config psy_cfg = { .drv_data = battery, .attr_grp = acpi_battery_groups, @@ -888,25 +953,55 @@ static int sysfs_add_battery(struct acpi_battery *battery) if (battery->power_unit == ACPI_BATTERY_POWER_UNIT_MA) { if (full_cap_broken) { - battery->bat_desc.properties = - charge_battery_full_cap_broken_props; - battery->bat_desc.num_properties = - ARRAY_SIZE(charge_battery_full_cap_broken_props); + if (extended_info_available) { + battery->bat_desc.properties = + charge_battery_full_cap_broken_extended_props; + battery->bat_desc.num_properties = + ARRAY_SIZE(charge_battery_full_cap_broken_extended_props); + } else { + battery->bat_desc.properties = + charge_battery_full_cap_broken_props; + battery->bat_desc.num_properties = + ARRAY_SIZE(charge_battery_full_cap_broken_props); + } } else { - battery->bat_desc.properties = charge_battery_props; - battery->bat_desc.num_properties = - ARRAY_SIZE(charge_battery_props); + if (extended_info_available) { + battery->bat_desc.properties = + charge_battery_extended_props; + battery->bat_desc.num_properties = + ARRAY_SIZE(charge_battery_extended_props); + } else { + battery->bat_desc.properties = + charge_battery_props; + battery->bat_desc.num_properties = + ARRAY_SIZE(charge_battery_props); + } } } else { if (full_cap_broken) { - battery->bat_desc.properties = - energy_battery_full_cap_broken_props; - battery->bat_desc.num_properties = - ARRAY_SIZE(energy_battery_full_cap_broken_props); + if (extended_info_available) { + battery->bat_desc.properties = + energy_battery_full_cap_broken_extended_props; + battery->bat_desc.num_properties = + ARRAY_SIZE(energy_battery_full_cap_broken_extended_props); + } else { + battery->bat_desc.properties = + energy_battery_full_cap_broken_props; + battery->bat_desc.num_properties = + ARRAY_SIZE(energy_battery_full_cap_broken_props); + } } else { - battery->bat_desc.properties = energy_battery_props; - battery->bat_desc.num_properties = - ARRAY_SIZE(energy_battery_props); + if (extended_info_available) { + battery->bat_desc.properties = + energy_battery_extended_props; + battery->bat_desc.num_properties = + ARRAY_SIZE(energy_battery_extended_props); + } else { + battery->bat_desc.properties = + energy_battery_props; + battery->bat_desc.num_properties = + ARRAY_SIZE(energy_battery_props); + } } } -- 2.39.5