[PATCH v17 5/6] spi: pxa2xx-pci: restore LPSS private register state across S3 resume

Andy Shevchenko andriy.shevchenko at linux.intel.com
Thu Oct 1 00:20:27 PDT 2026


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





More information about the linux-arm-kernel mailing list