drivers/acpi/battery.c | 131 +++++++++++++++++++++++++++++++++++------ 1 file changed, 113 insertions(+), 18 deletions(-)
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 <W_Armin@gmx.de>
---
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
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.
Thanks,
Armin Wolf
> Signed-off-by: Armin Wolf <W_Armin@gmx.de>
> ---
> 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);
> + }
> }
> }
>
On Tue, Sep 1, 2026 at 10:11 PM Armin Wolf <W_Armin@gmx.de> 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@gmx.de>
> > ---
> > 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);
> > + }
> > }
> > }
> >
Am 01.09.26 um 22:16 schrieb Rafael J. Wysocki (Intel):
> On Tue, Sep 1, 2026 at 10:11 PM Armin Wolf <W_Armin@gmx.de> 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.
Alright, that works for me.
Thanks,
Armin Wolf
>>> Signed-off-by: Armin Wolf <W_Armin@gmx.de>
>>> ---
>>> 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);
>>> + }
>>> }
>>> }
>>>
On Tue, Sep 1, 2026 at 10:18 PM Armin Wolf <W_Armin@gmx.de> wrote: > > Am 01.09.26 um 22:16 schrieb Rafael J. Wysocki (Intel): > > > On Tue, Sep 1, 2026 at 10:11 PM Armin Wolf <W_Armin@gmx.de> 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. > > Alright, that works for me. And so applied. Sashiko has a comment on the _BIX failing case: https://sashiko.dev/#/patchset/20260806233817.622975-1-W_Armin%40gmx.de but this can be addressed on top of the current patch IMV. If you think that it's worth addressing, please send a follow-up one for that. Thanks!
Am 09.09.26 um 16:27 schrieb Rafael J. Wysocki (Intel): > On Tue, Sep 1, 2026 at 10:18 PM Armin Wolf <W_Armin@gmx.de> wrote: >> Am 01.09.26 um 22:16 schrieb Rafael J. Wysocki (Intel): >> >>> On Tue, Sep 1, 2026 at 10:11 PM Armin Wolf <W_Armin@gmx.de> 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. >> Alright, that works for me. > And so applied. > > Sashiko has a comment on the _BIX failing case: > > https://sashiko.dev/#/patchset/20260806233817.622975-1-W_Armin%40gmx.de > > but this can be addressed on top of the current patch IMV. > > If you think that it's worth addressing, please send a follow-up one for that. > > Thanks! Thank you :) I do not think that Sashiko is right in this case, as failures inside _BIX should _normally_ only be temporary. So i think the current strategy of temporally falling-back to _BIF if _BIX fails is fine. Thanks, Armin Wolf
On Thu, Sep 10, 2026 at 12:40 AM Armin Wolf <W_Armin@gmx.de> wrote: > > Am 09.09.26 um 16:27 schrieb Rafael J. Wysocki (Intel): > > > On Tue, Sep 1, 2026 at 10:18 PM Armin Wolf <W_Armin@gmx.de> wrote: > >> Am 01.09.26 um 22:16 schrieb Rafael J. Wysocki (Intel): > >> > >>> On Tue, Sep 1, 2026 at 10:11 PM Armin Wolf <W_Armin@gmx.de> 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. > >> Alright, that works for me. > > And so applied. > > > > Sashiko has a comment on the _BIX failing case: > > > > https://sashiko.dev/#/patchset/20260806233817.622975-1-W_Armin%40gmx.de > > > > but this can be addressed on top of the current patch IMV. > > > > If you think that it's worth addressing, please send a follow-up one for that. > > > > Thanks! > > Thank you :) > > I do not think that Sashiko is right in this case, as failures inside _BIX > should _normally_ only be temporary. So i think the current strategy of temporally > falling-back to _BIF if _BIX fails is fine. Sounds good to me, thanks!
© 2016 - 2026 Red Hat, Inc.