Page MenuHomeFreeBSD

acpi: Suspend-to-idle support (s2idle)
Needs ReviewPublic

Authored by obiwac_gmail.com on Thu, Jan 30, 6:59 PM.

Details

Reviewers
jkim
jhb
imp
Summary

Add a new STYPE_SUSPEND_TO_IDLE sleep type to the enum sleep_type added by D48732.

Factor out do_standby, do_sleep, and add a new do_idle function for idling the CPU (a future patch will make this an idle loop and not just a simple cpu_idle() call). In do_idle, SCIs (interrupt 9) are enabled to allow wake events to break the CPU out of idle.

Also records all the steps made instead of just the last one in slp_state, which allows for more flexible unwinding (will be useful to not have to goto breakout if the SPMC entry call fails).

This is a prerequisite for the firmware to enter the S0ix states. When suspending to idle, the system stays in an ACPI S0 state, but the CPUs are idled and devices are suspended/resumed before and after this as they would be when entering any other sleep type (except for AWAKE and POWEROFF, of course). An entry notification to the SPMC (D48387) is needed to actually kick the firmware modern standby.

All the hw.acpi sysctls that previously supported S1-S5 now also support an s2idle option, and s2idle is always advertised as a supported option under hw.acpi.supported_sleep_states.

A lot of this borrows from Ben's patch: D17675. The main functional difference with that patch is that suspend-to-idle is a wholly separate sleep type in this one as opposed to being an alternative implementation for S3.

Test Plan

Tested on the Framework 13 AMD Ryzen 7040 series. When certain GPEs are emitted, the SCI is triggered and the CPU exits out of idle. So with this patch, the system exits s2idle very quickly after entering it. Another patch is needed to create an idle loop, where the CPU is immediately idled again if the last SCI was not for a wake event. The SPMC (D48387) entry notification lets the firmware know to be less noisy, which also alleviates this issue.

% sysctl hw.acpi.supported_sleep_state
hw.acpi.supported_sleep_state: S4 S5 s2idle

To test this out, you can set a press of the power button to suspend to idle e.g.:

% sysctl hw.acpi.power_button_state=s2idle
hw.acpi.power_button_state: S5 -> s2idle

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Skipped
Unit
Tests Skipped
Build Status
Buildable 62161
Build 59045: arc lint + arc unit