Re: [PATCH] ACPI: battery: Re-read battery information in the complete callback

From: Charis Stratakis

Date: Mon Oct 12 2026 - 21:40:39 EST


On Tuesday, October 13th, 2026 at 12:58 AM, Ali Ahmet Memiş <aliamemis@xxxxxxxxxxx> wrote:

> Hi Charis, could you test this on the P1 Gen2?
>

I've rebuilt the Fedora 7.2.10 kernel with the patch for F44 to test it, the hunks are identical to 7.3-rc7. As before, no vanilla
kernel was installed, all testing on my laptop, with Claude's help.

The test is cycles of "rtcwake -m no -s 25; systemctl suspend", checking energy_full, voltage_min_design and serial_number
after each resume, with int3403_thermal loaded throughout. I ran it as ABA so that nothing else could drift:

7.2.8-200.fc44, stock 10 of 10 resumes corrupted
7.2.10 + this patch 0 of 20 resumes corrupted
7.2.8-200.fc44, stock again 8 of 10 resumes corrupted

18 of 20 on stock against 0 of 20 patched.

Tested-by: Charalampos Stratakis <c.stratakis@xxxxxxxxx>

Here is what Claude reports, hope it makes sense as I don't have much knowledge of the kernel's workings:


Both flavours from my report show up: energy_full = 328.1x Wh, which makes
capacity read ~20%, together with voltage_min_design = 32.81x V, and one
cycle with energy_now = 328960000, i.e. 424%, with energy_full intact. One
bad cycle is worth singling out because it supports the \GTST explanation,
it returned voltage_min_design correctly as 15360000 while energy_full was
328160000. So the page selector flips in the middle of _BIX and which
fields come back wrong depends on where in the read the _TMP burst lands,
rather than the whole structure being read from page 0x60.

I also traced the EC (ec.c dyndbg) on the patched kernel for one resume,
which shows the ordering the patch relies on:

.223100 WR 81=01, 00, 02, 06, 04, 05 with the 0xA0-0xAF reads, i.e.
_BIX and _BST from the complete callback
.236664 last battery page selection
.239670 WR 81=60, first \GTST
.270916 last of 13 consecutive \GTST bursts

Nothing from the battery is interleaved among those bursts, and the next
battery access is 5.7s later from userspace polling. Worth noting that
"Restarting tasks: Done" (.240802) and "PM: suspend exit" (.251365) both
fall inside the \GTST burst, so PM_POST_SUSPEND, where the refresh used to
happen, is right in the middle of it.

The firmware bug itself is of course untouched, so a _BST that races a _TMP
at runtime can still return garbage. Those were the transient 424% readings
and they self-heal on the next read because of the 1s cache. Would a
plausibility check in acpi_battery_get_state() be welcome for that, re-
evaluating _BST once and warning FW_BUG when capacity_now exceeds
design_capacity by a wide margin? It would sit next to the existing
workarounds there. I realise it only catches the obviously absurd values
and not wrong ones that look plausible, so I am not sure it is worth it.

Regards,
Charalampos Stratakis