Skip to content

Enable suspend/resume on Pi 5 - #7514

Draft
PineappleBeech wants to merge 10 commits into
raspberrypi:rpi-6.18.yfrom
PineappleBeech:suspend
Draft

Enable suspend/resume on Pi 5#7514
PineappleBeech wants to merge 10 commits into
raspberrypi:rpi-6.18.yfrom
PineappleBeech:suspend

Conversation

@PineappleBeech

Copy link
Copy Markdown

This enables suspend/resume support for Pi 5.

The watchdog should be stopped when suspending.

The wireless can be turned off with cap-power-off-card. It could be left on with keep-power-in-suspend but that does not have any benefits currently.

NVME drives currently do not work. The NVME driver puts the drive in a low power state and expects the link to be left on. The PCIe driver then turns off the link. This stops the NVME driver waking up the drive. Adding NVME_QUIRK_SIMPLE_SUSPEND to a drive fixes it.

Signed-off-by: Peter Bailey <peter.bailey@raspberrypi.com>
@popcornmix

Copy link
Copy Markdown
Collaborator

Can you describe your use case?

@PineappleBeech

Copy link
Copy Markdown
Author

This is just for testing how the drivers handle suspend/resume. The firmware does not support suspend yet. It currently stops the arm and then starts it again after one second.

The first commit should only be merged if the firmware supports suspend. The other commits should do nothing if suspend is not enabled so they could be merged before suspend works.

@popcornmix

popcornmix commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator

The commits look plausible to me. Claude had some comments (that may not be an issue):

Commit 2 — watchdog: bcm2835: stop watchdog over suspend/resume. This is the solid one. It's the standard pattern used by many upstream watchdog drivers, and the implementation is idiomatic (DEFINE_SIMPLE_DEV_PM_OPS + pm_sleep_ptr, so it compiles away without CONFIG_PM_SLEEP). It still applies cleanly to our tree — the driver has no PM ops today. One edge case worth raising: it only checks watchdog_active(), which covers the userspace-opened case (WDOG_ACTIVE) but not WDOG_HW_RUNNING, which the probe sets when the bootloader left the watchdog running (bcm2835_wdt.c:207). In that state the watchdog core's keepalive worker pings the hardware, but that worker freezes during suspend, so a bootloader-armed watchdog would reset the board mid-suspend. Rare in practice on Pi, but cheap to handle.

Commit 3 — cap-power-off-card on the Pi 5 / CM5 wifi SDIO node. The rationale is sound: without keep-power-in-suspend, the MMC core needs permission to power-cycle the card across suspend, otherwise the SDIO suspend path aborts. Coverage is complete (Pi 500 includes the 5-b dts, the CM5L variants include cm5.dtsi). However, the author's claim that this commit "does nothing if suspend is not enabled" is not quite right: MMC_CAP_POWER_OFF_CARD also enables SDIO runtime PM, which changes card power behaviour at probe and whenever brcmfmac is unbound — today, on every user's board. It's probably fine, but it needs testing on the current kernel (wifi bring-up, unbind/rebind, rfkill) before merging, independent of any suspend work.

Signed-off-by: Peter Bailey <peter.bailey@raspberrypi.com>
Signed-off-by: Peter Bailey <peter.bailey@raspberrypi.com>
This makes the NVMe driver reset drives during suspend/resume.

Signed-off-by: Peter Bailey <peter.bailey@raspberrypi.com>
@PineappleBeech

Copy link
Copy Markdown
Author

I've updated the watchdog driver with the extra check.

The wireless driver prevents runtime PM while it is bound

I've added a temporary fix for NVMe drives. It works by overriding acpi_storage_d3 which has the correct effect of telling the NVMe driver that PCIe will be powered down. However, the Pi 5 does not use ACPI.

@timg236

timg236 commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

The firmware is now getting into the kernel after wakeup from S3 (lots to do!).

I think our TFA was assuming that GIC distributor was preserved in S3, it isn't. It's not in the AON power island
https://github.com/timg236/trusted-firmware-a/pull/new/pi5-s2ram-bringup

Mailboxes writes weren't making it to VPU after wakeup from S3, here's my very lightly tested patch for this on top of your patchset
#7559

@timg236

timg236 commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

Firmware for kernel debug here - pieeprom-2026-08-17 (probably quite broken)
https://github.com/timg236/rpi-eeprom/tree/pi5-s3-s2ram/firmware-2712/latest

Should look something like this, WiFi + NETDEV timeouts

  0.65 BUCK1_VOUT e6 - e6
  0.65 BUCK2_VOUT be - be
  0.65 BUCK3_VOUT 28 - 28
  0.65 BUCK4_VOUT a0 - a0
  0.66 BUCK5_VOUT 3c - 3c
  0.66 BUCK6_VOUT a0 - a0
  0.66 BUCK7_VOUT 64 - 64
  0.66 BUCK8_VOUT 64 - 64
  0.67 USBPD_STATUS: 00,00,00,00,00

  0.67 RPi: BOOTSYS release VERSION:7397d9bd DATE: 2026/08/17 TIME: 08:11:26
  0.68 MFG_VER: 1
  0.68 BOOTMODE: 0x06 partition 0 build-ts BUILD_TIMESTAMP=1786954286 serial 1760d33e boardrev b04170 stc 684236
  0.69 AON_RESET: 00000010 PM_RSTS 00001000
  0.69 POWER_OFF_ON_HALT: 0 WAIT_FOR_POWER_BUTTON 0 power-on-reset 1
  0.70 EEPROM ID 0xef4015
  0.70 SFDP v1.5 Param v1.5
  0.70 boot_eeprom_config.active_standby 0
  0.71 part 00000000 reset_info 00000000
  0.71 PMIC reset-event 00000000 rtc 6a82c5ad alarm 00000000 enabled 0
  0.72 uSD voltage 3.3V
  0.72 S2RAM RESUME: sdram_config 00000006
  0.73 Initialising SDRAM rank 1 total-size: 16Gbit part: 0 (0x06 0x06) odt: 0
  0.73 memsys_init: 0 16Gbit MCB 0x80015ff0: 7880
  0.74 DDR 4267 Mbps dual-rank:0 byte-mode:0 size-gbit:16 part-config:0 odt:0
  0.77 Resume DDR PHYs
  0.89 SREF exit SD_CS 00018203
  0.91 OTP boardrev b04170 bootrom a a
  0.91 Customer key hash 0000000000000000000000000000000000000000000000000000000000000000
  0.92 VC-JTAG unlocked
  0.94 MESS:00:00:00.944130  0.96 MESS:00:00:00.962439:0: 00000040: -> 00000480
  0.96 MESS:00:00:00.964305:0: 00000030: -> 00100080
  0.96 MESS:00:00:00.969019:0: 00000034: -> 00100080
  0.97 MESS:00:00:00.973731:0: 00000038: -> 00100080
  0.97 MESS:00:00:00.978443:0: 0000003c: -> 00100080

INFO:    rpi5_pwr_domain_suspend_finish
INFO:    gic reinitialised
INFO:    returning to kernel
[  361.384292] Calling cpu_pm_resume+0x0/0x68
[  361.384292] Calling kvm_resume+0x0/0x40
[  361.384292] Calling irq_gc_resume+0x0/0x90
[  361.384292] Calling irq_pm_syscore_resume+0x0/0x30
[  361.384292] Calling timekeeping_resume+0x0/0x150
[  361.384292] Calling sched_clock_resume+0x0/0x68
[  361.384294] Calling ledtrig_cpu_syscore_resume+0x0/0x30
[  361.389632] Enabling non-boot CPUs ...
[  361.393553] Detected PIPT I-cache on CPU1
[  361.397605] CPU1: Booted secondary processor 0x0000000100 [0x414fd0b1]
[  361.404466] CPU1 is up
[  361.406939] Detected PIPT I-cache on CPU2
[  361.410981] CPU2: Booted secondary processor 0x0000000200 [0x414fd0b1]
[  361.417794] CPU2 is up
[  361.420272] Detected PIPT I-cache on CPU3
[  361.424312] CPU3: Booted secondary processor 0x0000000300 [0x414fd0b1]
[  361.431130] CPU3 is up
[  361.537120] brcm-pcie 1000120000.pcie: clkreq-mode set to default
[  361.543244] brcm-pcie 1000120000.pcie: link up, 5.0 GT/s PCIe x4 (!SSC)
[  361.550254] PM: noirq resume of devices complete after 116.765 msecs
[  361.556980] PM: early resume of devices complete after 0.291 msecs
[  361.565972] Timekeeping suspended for 5.421 seconds

PineappleBeech and others added 6 commits August 17, 2026 09:47
Signed-off-by: Peter Bailey <peter.bailey@raspberrypi.com>
Signed-Off-By: Peter Bailey <peter.bailey@raspberrypi.com>
Signed-off-by: Peter Bailey <peter.bailey@raspberrypi.com>
Signed-off-by: Peter Bailey <peter.bailey@raspberrypi.com>
Signed-off-by: Peter Bailey <peter.bailey@raspberrypi.com>
In S3 deep-sleep, the entire VPU, ARM, GIC infrastructure is
powered off. Re-initialise the mailbox hardware on resume
otherwise, the VPU won't see mailbox requests.
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.

3 participants