Skip to content

WB8: kernel side of EC-assisted suspend-to-off (single series)#363

Open
evgeny-boger wants to merge 11 commits into
feature/wb-pstore-shuttle-v6.18from
feature/wb85-suspend-to-off
Open

WB8: kernel side of EC-assisted suspend-to-off (single series)#363
evgeny-boger wants to merge 11 commits into
feature/wb-pstore-shuttle-v6.18from
feature/wb85-suspend-to-off

Conversation

@evgeny-boger

@evgeny-boger evgeny-boger commented Jul 10, 2026

Copy link
Copy Markdown
Member

The complete kernel side of the WB8.5 EC-assisted suspend-to-off (firmware half: wirenboard/arm-trusted-firmware#4, tag wb8-suspend-rc1). Single 11-commit series, one driver per commit, bindings before driver, DTS last; every commit passes scripts/checkpatch.pl with 0 errors (the sole warning is the Co-authored-by attribution trailer, which checkpatch does not list as a standard tag).

Contents:

  • Kernel ownership of device state that dies with VDD-SYS during suspend-to-off: CCU snapshot/replay, pinctrl save/restore, spi-sun6i / musb / usb-phy system-sleep support (1–5).
  • i2c: mv64xxx fail-fast hardening for a continuously erroring bus — prevents one wedged peripheral from D-stating every consumer behind the regmap mutex (6).
  • PSCI SYSTEM_SUSPEND failure report — a silent -EPERM (DENIED) is otherwise nearly indistinguishable from an instant wake (7).
  • The wbec suspend-to-off coordinator: binding, driver (syscore magic arming in the no-going-back window, EC wake-deadline plumbing), and the DT wiring, gated on wirenboard,suspend-magic-rtc so only WB8/H616 is affected (8–10).
  • opp-suspend on the bin-universal 0.90 V / 480 MHz OPP — the kernel-side belt for the SPL boot-voltage contract (supersedes arm64: dts: allwinner: wirenboard85x: park CPU at a boot-safe OPP across suspend #362) (11).

Provenance: the original development history was lost with its scratchpad repo; the series is reconstructed from the exact working tree of bench-validated build #14 — the kernel behind 210+ clean suspend cycles and firmware gates G1b/P3. Bench diagnostics that tree carried (per-cycle prints, a D-state dumper kthread, lockup-panic config flips) are stripped; suspend_crc_verify stays as the documented opt-in debug interface to BL31's CRC bracket.

Verified: Image + dtbs build clean (defconfig + wb8.config); both wirenboard,suspend-magic-rtc and opp-suspend confirmed present in the compiled sun50i-h616-wirenboard851.dtb via fdtget.

Based on feature/wb-pstore-shuttle-v6.18 (the suspend recovery story builds on its ramoops/poweron-reason work). Independent of the TF-A/U-Boot/EC PRs — safe to merge alone; the feature arms only when firmware and DT both support it.

🤖 Generated with Claude Code

evgeny-boger and others added 11 commits July 10, 2026 17:25
On boards where a system ("mem") suspend is implemented as a
suspend-to-off, the PMIC drops VDD-SYS and the whole CCU register file
comes back at reset defaults. Firmware restores only what it needs to
re-enter the kernel (the base PLLs and the CPU/bus/DRAM clock tree);
every other clock is the kernel's to restore.

Snapshot the CCU register file at suspend and replay it on resume,
excluding the firmware-owned registers. Platforms that resume with the
CCU intact see no change: the restore only rewrites registers whose
value differs from the snapshot.

Signed-off-by: Evgeny Boger <boger@wirenboard.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
The PIO and R_PIO blocks lose their state with VDD-SYS during a
suspend-to-off. Save the pin configuration (mux, drive, pull and output
latches) at suspend and restore it on resume, so pad state does not
depend on firmware replaying it. No change on platforms that keep the
pin controller powered across suspend.

Signed-off-by: Evgeny Boger <boger@wirenboard.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
The controller loses all register state with VDD-SYS during a
suspend-to-off. Add system-sleep callbacks that quiesce the controller
at suspend and fully re-initialize it on resume instead of assuming the
register file survived.

Signed-off-by: Evgeny Boger <boger@wirenboard.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
The glue's bus clock, reset, PHY and optional SRAM claim all die with
VDD-SYS during a suspend-to-off. Add system-sleep callbacks that
release the glue-owned resources at suspend and re-acquire and
reprogram them on resume. Resource liveness keys off glue->musb so a
suspend racing controller teardown is tolerated.

Signed-off-by: Evgeny Boger <boger@wirenboard.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
PHY register state (PHYCTL routing, forced session/ID bits, dual-route
selection) is lost with VDD-SYS during a suspend-to-off. Reprogram it
in the resume path rather than assuming it survived.

Signed-off-by: Evgeny Boger <boger@wirenboard.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
If the bus errors continuously (e.g. a wedged peripheral holding SDA),
the error->recover->retry churn can hold a client's regmap mutex for
minutes, putting every consumer of that bus in uninterruptible sleep
behind it. Track the start of a failing streak and fail transfers
immediately once the streak exceeds a timeout; any successful transfer
resets the streak.

Found on Wiren Board 8 where a jammed PMIC I2C bus turned one bad
transfer into a system-wide D-state hang that even hung-task panic
could not report (the panic path itself blocked on the same mutex).

Signed-off-by: Evgeny Boger <boger@wirenboard.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
A SYSTEM_SUSPEND call that returns (instead of resuming through
cpu_resume) has failed, but the only symptom is an errno bubbling out
of the suspend core - nearly indistinguishable from a suspend that
woke immediately. PSCI_RET_DENIED in particular (typically a CPU that
never went offline) surfaced as a silent -EPERM. Print the failure and
the online CPU count.

Signed-off-by: Evgeny Boger <boger@wirenboard.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Document the phandle that points the EC driver at the RTC whose
general-purpose data0 register carries the firmware suspend-to-off
magic. Its presence gates the in-kernel suspend-to-off coordinator, so
only boards that wire it (WB8/H616) are affected.

Signed-off-by: Evgeny Boger <boger@wirenboard.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Coordinate EC-assisted suspend-to-off with the boot firmware: a syscore
hook arms the firmware magic in the RTC data0 register inside the same
no-going-back window that arms the EC's suspend mode, so the PMIC-sleep
and EC-wake paths cannot desync. A PM notifier plus announce/
deannounce plumbing program the EC wake deadline around each suspend.

The coordinator arms only when the wirenboard,suspend-magic-rtc DT
phandle is present; other boards see no behaviour change.

Module parameters: suspend_crc_verify selects the firmware's
CRC-verifying magic (opt-in debug bracket, ~80 s per cycle, keep off in
production); suspend_default_timeout_s bounds the EC wake deadline.

Signed-off-by: Evgeny Boger <boger@wirenboard.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…inator

Wire wirenboard,suspend-magic-rtc to the sun6i RTC so the wbec driver
arms the firmware suspend-to-off magic on WB8.5 boards.

Signed-off-by: Evgeny Boger <boger@wirenboard.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
… across suspend

On suspend-to-off resume, U-Boot SPL's board init runs before the
resume branch and programs VDD-CPU to its 0.90 V cold-boot value; BL31
then re-locks PLL_CPUX to the frequency the kernel parked at. Under
schedutil the suspend-entry work (fs sync, freezing) spikes the load,
so the kernel routinely parks at a 1.00-1.10 V OPP (up to 1416 MHz),
leaving the cluster up to 200 mV under-volted until cpufreq's resume
rewrites the regulator ~2 s later. The resulting fetch/load transients
during secondary bringup were a whole family of post-resume corruption
(fetch faults on valid code words, single-bit pointer flips, bringup
lockups, always within ~2 s of resume, with retained-DRAM CRC clean on
every failing cycle).

Mark the 480 MHz OPP as the suspend OPP: cpufreq_generic_suspend()
parks there before the PSCI call. 480 MHz is rated 0.90 V and present
on every speed bin (opp-supported-hw 0x1f), so the parked frequency is
safe at the SPL boot voltage even if the firmware-side fix is absent or
the boot voltage changes. Costs a few hundred ms of resume latency
until the governor revives.

Signed-off-by: Evgeny Boger <boger@wirenboard.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
@evgeny-boger evgeny-boger force-pushed the feature/wb85-suspend-to-off branch from f411ae0 to 5a51354 Compare July 10, 2026 14:27
@evgeny-boger evgeny-boger changed the title WB8: kernel side of EC-assisted suspend-to-off WB8: kernel side of EC-assisted suspend-to-off (single series) Jul 10, 2026
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.

1 participant