Re: [PATCH v17 5/6] spi: pxa2xx-pci: restore LPSS private register state across S3 resume
From: Andy Shevchenko
Date: Thu Oct 01 2026 - 03:25:10 EST
On Thu, Oct 01, 2026 at 12:06:28AM +0800, Shih-Yuan Lee wrote:
> On platforms where Intel LPSS SPI is enumerated as a bare PCI device
> (such as the Apple MacBook8,1 on Lynxpoint-LP), the LPSS power island
> loses power during system sleep and powers up with the controller held
> in reset. Because the device lacks ACPI companion objects or MFD
> binding, neither drivers/acpi/x86/lpss.c nor drivers/mfd/intel-lpss.c
> restore the private register context across S3 resume.
>
> This causes memory-mapped I/O reads on resume to return ~0, resulting
> in PCIe Completion Timeouts, missing interrupts, and dead
> keyboard/touchpad.
>
> Restore LPSS private registers and deassert functional, APB, and iDMA
> resets in the PCI glue layer:
> 1. In suspend, quiesce the controller queue via spi_controller_suspend()
> so no transfers remain in flight and chip select is deasserted.
> Then save the LPSS private registers (LPSS_PRIV_REG_COUNT 9 covering
> up to offset 0x20 including reg_cs_ctrl at 0x18). Ensure the clock is
> active for reading MMIO registers using pm_runtime_resume_and_get(),
> balanced by pm_runtime_put_noidle(), before calling
> pm_runtime_force_suspend().
> 2. In resume, restore LPSS private registers and deassert functional,
> APB, and iDMA resets via pxa2xx_spi_pci_lpss_restore_ctx() before
> calling pm_runtime_force_resume(). Because the controller clock
> remains gated (clk_enabled is false) during this restoration, any
> interrupt arriving on a shared line bails out early in ssp_int()
> without accessing registers on a controller held in reset. Once
> resets are deasserted and private registers are restored, call
> pm_runtime_force_resume() to enable the clock and mark the device
> active, and restart the queue with spi_controller_resume().
> 3. In probe, call pci_d3cold_disable() for Lynxpoint-LP (is_lpt) to
> ensure the PCI device cannot enter D3cold during runtime PM,
> guaranteeing that LPSS private registers are retained during S0 idle
> periods and only require restoration across S3 system sleep. Set
> DPM_FLAG_NO_DIRECT_COMPLETE to prevent PCI subsystem direct-complete
> bypassing system sleep callbacks.
> 4. Scope LPSS context restoration specifically to Lynxpoint-LP
> (PCI_DEVICE_ID_INTEL_LPT*) devices to avoid perturbing other LPSS
> PCI platforms (BYT, BSW) or non-LPSS platforms.
>
> Export lpss_ssp_setup() and core runtime PM ops so the PCI glue layer
> can invoke them around private register restoration.
No, as I told earlier please find a way how to not add a code duplication.
> Assisted-by: Antigravity:gemini-3.8-flash sparse
Assisted-by: LLM
--
With Best Regards,
Andy Shevchenko