Re: [PATCH] ACPI: battery: Fix bogus cycle count values on systems without _BIX

From: Rafael J. Wysocki (Intel)

Date: Tue Sep 01 2026 - 16:21:26 EST


On Tue, Sep 1, 2026 at 10:11 PM Armin Wolf <W_Armin@xxxxxx> wrote:
>
> Am 07.08.26 um 01:38 schrieb Armin Wolf:
>
> > 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.
>
> Any thoughts on this? I tested it on my device, and so far everything seems
> to work flawlessly.

It looks good overall, but it is quite substantial, which is why it
didn't make it into 7.3-rc1.

I'm planning to apply it for 7.4.

> > Signed-off-by: Armin Wolf <W_Armin@xxxxxx>
> > ---
> > 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);
> > + }
> > }
> > }
> >