Skip to content

pmdomain: apple: finish fpwm power-on after s2idle - #221

Open
ludagoo wants to merge 1 commit into
omacom:integration/aurorafrom
ludagoo:fix/fpwm1-s2idle-restore
Open

ludagoo wants to merge 1 commit into
omacom:integration/aurorafrom
ludagoo:fix/fpwm1-s2idle-restore

Conversation

@ludagoo

@ludagoo ludagoo commented Oct 25, 2026 •

Copy link
Copy Markdown

On the MacBook Air M1 2020 (J313, t8103), s2idle resume powers fpwm1 (the keyboard backlight) back on in noirq, but the state machine is still clock-gated and BUSY (0xa4f) when the 100 us poll ends. genpd records the domain on anyway, then pwm-leds writes the duty cycle into a clock-gated block and the keys stay dark.

Defer that one in-progress power-on and finish it from resume_early, with the 10 ms poll m1n1 already uses, after noirq and before the LED resume write. Any other timeout still reports at 100 us.

The original patch did not apply onto 19f4965; this is the same restore ported onto the current driver, including apple,no-auto-pm.

Session build, Monday 26 Oct 2026 05:02 PM -03: linux-aurora 7.2.11-6-2-ARCH (package 7.2.11.aurora6-2), branch local/j313-test at 7638df0. makepkg exited 0. rustc 1.85.0, LLVM/clang 18.1.8. This machine is running that kernel. The stacked commit compiled in was 1d61113. This pull request's head is 72d49ac, which is not the commit that was built.

Two real s2idle cycles on this kernel showed no fpwm1 error. malik-na's real lid sleep showed the keyboard backlight on after resume.

@malik-na

Copy link
Copy Markdown
Member

Tested on a J313 (M1 Air): fixes the fpwm1 restore on resume. No regression attributable to this PR so far.

baseline (19f4965180f4) this PR
PS fpwm1: Failed to reach power state 0xf (… now: 0xa4f) after an s2idle cycle 1 0
kbd_backlight set 200 → read back after resume 200 200
device suspend phase (pm_test=devices) pass pass

The s2idle cycle here was pm_test=platform, which runs noirq suspend/resume and resume_early, so it exercises the deferred power-on in apple_pmgr_ps_resume_early(). It isn't a full s2idle with a keypress wake, and the keys weren't checked by eye.

One omarchy-m-test check failed on this boot: audio.microphone-signal. The evidence is captured 65536 samples: peak 7, rms 0.1 … silence: the peak stayed under 8, which reads as a quiet room just under the threshold, not something a pmgr change for fpwm1 would cause. The same check passed on the #219 and #220 kernels. A second run of this kernel is queued to confirm, and I'll follow up only if it fails again.

How this was tested
  • Hardware: MacBook Air (M1, 2020), J313, BCM4378 (brcmfmac4378b1-pcie), DCP 13.5, booted through U-Boot → Limine.
  • Kernels: this PR's head and its parent 19f4965180f4 (the baseline), built with the Air's own /proc/config.gz and booted once each as a one-shot test entry. The Mac returns to its installed 7.2.11-6-1-ARCH after every run.
  • Each boot ran:
    • a device-phase suspend test (pm_test=devices through systemctl suspend)
    • omarchy-m-test, compared with a run on the installed kernel
    • a check script that reads dmesg counters, writes the keyboard and panel backlight (420, 419, 189, then back), lists ALS IIO channels, re-associates Wi-Fi twice with nmcli con up, and does one pm_test=platform s2idle cycle (noirq + resume_early, auto-wakes after 5 s)
  • Not covered: a real s2idle with a keypress wake, Touch ID enrollment/verify with a finger, and how brightness looks.

@ludagoo
ludagoo force-pushed the fix/fpwm1-s2idle-restore branch from f2208ce to 72d49ac Compare October 26, 2026 18:14
@malik-na

Copy link
Copy Markdown
Member

Follow-up: second automated run and a hands-on real sleep.

  • omarchy-m-test passed with 0 regressions on the second run, so the earlier audio.microphone-signal failure was the quiet room (peak 7 against a threshold of 8).
  • PS fpwm1: Failed to reach power state after the pm_test=platform cycle: 0 on both runs, against 4 of 4 baseline boots.
  • Real lid-close sleep (about 2 min): after the keypress wake the keyboard backlight was on, no fpwm1 error was logged, and writing kbd_backlight 20 → 255 → 0 → 219 visibly followed on the keys. That's the case this PR fixes: on the baseline the duty-cycle write lands on the still clock-gated block.
How this was tested
  • MacBook Air (M1, 2020), J313, DCP 13.5, BCM4378, booted through U-Boot → Limine.
  • This PR's head and its parent 19f4965180f4 (the baseline), built with the Air's own /proc/config.gz and booted as one-shot test entries. The Mac returns to its installed 7.2.11-6-1-ARCH after every run.
  • Automated boots: device-phase suspend (pm_test=devices), omarchy-m-test, and a check script (dmesg counters, keyboard and panel backlight writes, ALS channels, two nmcli con up re-associations, one pm_test=platform s2idle cycle).
  • Hands-on boots: a person at the Mac doing a real lid-close sleep and keypress wake, using the brightness keys, and covering or lighting the ALS, while the kernel's state was logged every 2 s.
  • Tested commit: f2208cee5643 on 19f4965180f4. The PR has since been rebased to 72d49acd25dd on 937b727ef9a3 with an identical diff; the new base wasn't re-tested.

@ludagoo
ludagoo marked this pull request as ready for review October 26, 2026 23:06
@malik-na

Copy link
Copy Markdown
Member

Correction to my earlier follow-up: the audio.microphone-signal failure on the first run (peak 7) wasn't a quiet room. On this Air, kernels without #180 give a near-null capture (peak 0–77), because the enclave isn't booted (#141). So it's unrelated to this PR, as I said, but for a different reason.

@ludagoo
ludagoo force-pushed the fix/fpwm1-s2idle-restore branch 4 times, most recently from 820c3fe to 11603a9 Compare October 31, 2026 21:44
On this J313 (t8103), s2idle resumes log:

  apple-pmgr-pwrstate power-controller@1e0: PS fpwm1: Failed to reach
  power state 0xf (requested 0xf, now: 0xa4f)

fpwm1 is the keyboard-backlight PWM. genpd turns it off in suspend_noirq
and back on in resume_noirq. The write of target 0xf has already landed.
0xa4f is that target, actual state clock-gate (0x4), WAS_CLKGATED, and
BUSY. The 100 us poll expires while the state machine is still moving.

genpd ignores the error in noirq and records the domain on, and the
system_sleep path deliberately leaves the target latched. pwm-leds then
writes the duty cycle from its resume callback, which runs only after
every resume_early. A write into a block that is still clock-gated does
not restore the backlight.

The Apple ADT export lists no parent for fpwm1, and the same register
later reads actual 0xf with no second request, so this is the state
machine finishing late rather than a missing power-domains link.
pms_fpwm1 stays clock-gated the whole time and is not that parent.

Defer this one in-progress failure out of the noirq poll. resume_early
runs after every noirq callback and before the LED resume write, and
waits the 10 ms m1n1 already allows for a PS transition. Any other
failure still reports at 100 us. The retry keeps the power_on auto-PM
choice, so an apple,no-auto-pm domain is not switched to automatic PM.

Signed-off-by: Lucas Goossen <lucas.goossen@hey.com>
@ludagoo
ludagoo force-pushed the fix/fpwm1-s2idle-restore branch from 11603a9 to 1e57136 Compare November 2, 2026 07:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants