From 21af603b6509e1e2297de5c159317639477dcbf3 Mon Sep 17 00:00:00 2001 From: Armin Wolf Date: Fri, 7 Aug 2026 01:38:17 +0200 Subject: [PATCH 1/6] ACPI: battery: Fix bogus cycle count values on systems without _BIX 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 Link: https://patch.msgid.link/20260806233817.622975-1-W_Armin@gmx.de Signed-off-by: Rafael J. Wysocki --- 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 670853ec3a4d..8599949f8786 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -341,7 +341,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, @@ -359,7 +361,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, @@ -373,7 +375,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, @@ -391,7 +393,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, @@ -405,6 +407,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 */ @@ -904,6 +968,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, @@ -922,25 +987,55 @@ static int sysfs_add_battery(struct acpi_battery *battery) if (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); + } } } From f16c512a07b954aa3b0b3c580e7abb5dd4f5e703 Mon Sep 17 00:00:00 2001 From: Ian Gallagher Date: Sun, 30 Aug 2026 13:19:24 +1200 Subject: [PATCH 2/6] ACPI: button: Add lid_init_state quirk for Razer Blade Stealth 13 (Early 2020) RZ09-0310 This patch adds a quirk mapping for the "Blade Stealth 13 (Early 2020) - RZ09-0310" laptop, which exhibits the same issue as the following two related products already accounted for in this file. - Razer Blade Stealth 13 Late 2019 - Blade Pro 17 (Early 2020) - RZ09-0329 Summary of the issue this fixes: The firmware's _LID method still returns "closed" after resume when the lid was opened during S3, causing systemd-logind to suspend the system again within several seconds (15-40) after waking. Signed-off-by: Ian Gallagher Link: https://patch.msgid.link/90ab9b58-da8b-4ffc-bd4b-adf7590545a9@app.fastmail.com Signed-off-by: Rafael J. Wysocki --- drivers/acpi/button.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index cdbb1023a8ee..34c7173b5a6c 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c @@ -144,6 +144,18 @@ static const struct dmi_system_id dmi_lid_quirks[] = { }, .driver_data = (void *)(long)ACPI_BUTTON_LID_INIT_OPEN, }, + { + /* + * Razer Blade Stealth 13 early 2020, when the lid is opened + * while suspended the open notification is lost and _LID keeps + * returning closed after resume, causing spurious re-suspends. + */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Razer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Blade Stealth 13 (Early 2020) - RZ09-0310"), + }, + .driver_data = (void *)(long)ACPI_BUTTON_LID_INIT_OPEN, + }, { /* * Samsung galaxybook2 ,initial _LID device notification returns From 7c0940e431c33ca13e9fde57ea0ad56da6529c56 Mon Sep 17 00:00:00 2001 From: Itay Shem-tov Date: Thu, 3 Sep 2026 13:42:44 +0300 Subject: [PATCH 3/6] ACPI: SBS: report relative state of charge as CAPACITY acpi_sbs reads SBS command 0x0e (AbsoluteStateOfCharge) into battery->state_of_charge, which is exported unmodified as POWER_SUPPLY_PROP_CAPACITY. Per the Smart Battery Data Specification 1.1, 0x0e is expressed as a percentage of DesignCapacity and is explicitly permitted to exceed 100%. Documentation/ABI/testing/sysfs-class-power specifies the capacity attribute as "Valid values: 0 - 100 (percent)", so any pack whose FullChargeCapacity exceeds its DesignCapacity - the normal state of a new or recently replaced battery - makes the driver report out of range. The correct source is 0x0d (RelativeStateOfCharge), a percentage of FullChargeCapacity, which the specification bounds to 0..100. This is the same defect that was fixed in the i2c SBS driver by commit b1f092f6480e ("sbs-battery.c: Capacity attr = remaining relative capacity"), whose reasoning applies verbatim here; drivers/acpi/sbs.c was not updated at the time. drivers/power/supply/sbs-battery.c has used 0x0d since, so the two SBS drivers currently disagree about what CAPACITY means. Observed on a MacBookPro11,1 with an SMP/bq20z451 pack (FullChargeCapacity 6775 mAh, DesignCapacity 6400 mAh). Both registers read back-to-back from the pack at a full charge: 0x0d RelativeStateOfCharge = 100 % 0x0e AbsoluteStateOfCharge = 106 % /sys/class/power_supply/BAT0/capacity reported 106 while upower, which computes charge_now/charge_full itself rather than trusting the driver, reported 100. battery->state_of_charge has no other consumer, so no other property changes behaviour. Signed-off-by: Itay Shem-tov Reviewed-by: Sebastian Reichel Link: https://patch.msgid.link/20260903104244.25556-1-itayst@gmail.com Signed-off-by: Rafael J. Wysocki --- drivers/acpi/sbs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c index 86b7c7975852..862cb94a8b43 100644 --- a/drivers/acpi/sbs.c +++ b/drivers/acpi/sbs.c @@ -318,7 +318,7 @@ static struct acpi_battery_reader state_readers[] = { {0x0a, SMBUS_READ_WORD, offsetof(struct acpi_battery, rate_now)}, {0x0b, SMBUS_READ_WORD, offsetof(struct acpi_battery, rate_avg)}, {0x0f, SMBUS_READ_WORD, offsetof(struct acpi_battery, capacity_now)}, - {0x0e, SMBUS_READ_WORD, offsetof(struct acpi_battery, state_of_charge)}, + {0x0d, SMBUS_READ_WORD, offsetof(struct acpi_battery, state_of_charge)}, {0x16, SMBUS_READ_WORD, offsetof(struct acpi_battery, state)}, }; From 2b30842e52d9a364428b598f5edd4b12fa772f5a Mon Sep 17 00:00:00 2001 From: Guangshuo Li Date: Sat, 12 Sep 2026 19:33:55 +0800 Subject: [PATCH 4/6] ACPI: SBS: Fix NULL pointer dereference on allocation failure acpi_sbs_probe() jumps to the common error path when kzalloc_obj() fails, but platform_set_drvdata() is only called after the allocation succeeds. The error path calls acpi_sbs_remove(), which retrieves the unset driver data and dereferences the resulting NULL pointer when locking sbs->lock, causing a NULL pointer dereference. Return -ENOMEM directly when the allocation fails, since no resources have been initialized at that point and there is nothing to clean up. This issue was found by manual code inspection. Fixes: 9460eaae2ee42 ("ACPI: SBS: Convert the driver to a platform one") Cc: All applicable Signed-off-by: Guangshuo Li Link: https://patch.msgid.link/20260912113355.644238-1-lgs201920130244@gmail.com Signed-off-by: Rafael J. Wysocki --- drivers/acpi/sbs.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c index 862cb94a8b43..f10bbf13c242 100644 --- a/drivers/acpi/sbs.c +++ b/drivers/acpi/sbs.c @@ -639,10 +639,8 @@ static int acpi_sbs_probe(struct platform_device *pdev) return -ENODEV; sbs = kzalloc_obj(struct acpi_sbs); - if (!sbs) { - result = -ENOMEM; - goto end; - } + if (!sbs) + return -ENOMEM; mutex_init(&sbs->lock); From efed63bc78ede446f8bdc3b7b1730882016d332d Mon Sep 17 00:00:00 2001 From: Dirga Yuza Date: Fri, 11 Sep 2026 21:33:06 +0700 Subject: [PATCH 5/6] ACPI: video: add backlight=native DMI quirk on Acer Nitro AN515-58 The Acer Nitro AN515-58 requires the same quirk entry as AN515-46, since its firmware also advertises the NVIDIA WMI EC backlight GUID. However, on this hybrid graphics setup, the internal display is wired to the Integrated GPU (Intel Iris Xe Graphics). As a result, the nvidia_wmi_ec_backlight driver fails to probe, leaving no backlight device registered and rendering the brightness keys and desktop brightness slider non-functional. Setting acpi_backlight=native allows intel_backlight to register its backlight interface and restoring brightness control. Add a DMI quirk entry so this model uses the native backlight by default. Signed-off-by: Dirga Yuza Link: https://patch.msgid.link/20260911143306.49015-1-dirgayuza123@gmail.com Signed-off-by: Rafael J. Wysocki --- drivers/acpi/video_detect.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index e3b69f876d24..3037fd18d420 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c @@ -929,6 +929,14 @@ static const struct dmi_system_id video_detect_dmi_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "Nitro AN515-46"), }, }, + { + .callback = video_detect_force_native, + /* Acer Nitro AN515-58 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Nitro AN515-58"), + }, + }, /* * x86 android tablets which directly control the backlight through From 5d76269ee75391812bfdf18df4b2db690d7e264d Mon Sep 17 00:00:00 2001 From: Chitransh Mandhaniya Date: Sat, 10 Oct 2026 18:18:30 +0530 Subject: [PATCH 6/6] ACPI: video: force native backlight on Dell OptiPlex AIO 7410 35W The Dell OptiPlex AIO 7410 35W (board 01KP8D) declares DELL0501 in its ACPI DSDT (status = 0x0F) even though no UART scalar board is physically present. This causes acpi_video_get_backlight_type() to return acpi_backlight_dell_uart, which makes i915 skip registering intel_backlight. The dell-uart-backlight driver then times out talking to the absent board and the probe fails, leaving the machine with zero backlight control. A BIOS update fixes this on some models (e.g. OptiPlex 7420, board 0914RT) by setting DELL0501 _STA to 0, but Dell has not shipped a corrected BIOS for the 7410 even in the latest release (1.37.0, 2026-05-28). Add a DMI quirk to force native backlight on this model so that i915 registers intel_backlight and brightness control works out of the box. Tested on: - OptiPlex AIO 7410 35W (01KP8D, BIOS 1.37.0) -- confirmed acpi_backlight=native produces working intel_backlight (raw, max=96000), DMI quirk has the same effect. - OptiPlex AIO 7420 35W (0914RT, BIOS 1.27.0) -- DELL0501 absent in updated BIOS, intel_backlight works natively (no regression). Signed-off-by: Chitransh Mandhaniya Reviewed-by: Hans de Goede Link: https://patch.msgid.link/20261010124830.116750-1-chitranshmandhaniya@gmail.com Signed-off-by: Rafael J. Wysocki --- drivers/acpi/video_detect.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index 3037fd18d420..326d4c6d132a 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c @@ -883,6 +883,14 @@ static const struct dmi_system_id video_detect_dmi_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 7770 AIO"), }, }, + { + .callback = video_detect_force_native, + /* Dell OptiPlex AIO 7410 35W */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex AIO 7410 35W"), + }, + }, /* * Models which have nvidia-ec-wmi support, but should not use it.