Commit d12538e9 authored by Huacai Chen's avatar Huacai Chen Committed by Todd Kjos
Browse files

BACKPORT: PCI/portdrv: Prevent LS7A Bus Master clearing on shutdown

After cc27b735 ("PCI/portdrv: Turn off PCIe services during
shutdown") we observe hangs during poweroff/reboot on systems with
LS7A chipset.

This happens because the portdrv .shutdown() method
(pcie_portdrv_remove()) clears PCI_COMMAND_MASTER via
pci_disable_device(), which prevents bridges from forwarding memory
or I/O Requests in the upstream direction (PCIe r6.0, sec 7.5.1.1.3).

LS7A Root Ports have a hardware defect: clearing PCI_COMMAND_MASTER
*also* prevents the bridge from forwarding CPU MMIO requests in the
downstream direction, and these MMIO accesses to devices below the
bridge happen even after .shutdown(), e.g., to print console messages.
LS7A neither forwards the requests nor sends an unsuccessful
completion to the CPU, so the CPU waits forever, resulting in the
hang.

The purpose of .shutdown() is to disable interrupts and DMA from the
device.  PCIe ports may generate interrupts (either MSI/MSI-X or INTx)
for AER, DPC, PME, hotplug, etc., but they never perform DMA except
MSI/MSI-X. Clearing PCI_COMMAND_MASTER effectively disables MSI/MSI-X,
but not INTx.

The port service driver .remove() methods clear the interrupt enables
in PCI_ERR_ROOT_COMMAND, PCI_EXP_DPC_CTL, PCI_EXP_SLTCTL, and
PCI_EXP_RTCTL, etc., which disables interrupts regardless of whether
they are MSI/MSI-X or INTx.

Add a pcie_portdrv_shutdown() method that calls all the port service
driver .remove() methods to clear the interrupt enables for each
service but does not clear Bus Mastering on the port itself.

[bhelgaas: commit log]
Link: https://lore.kernel.org/r/20230201043018.778499-2-chenhuacai@loongson.cn


Change-Id: I795b5e092d273eb82dabbab87203b916cd579a5a
Signed-off-by: default avatarHuacai Chen <chenhuacai@loongson.cn>
Signed-off-by: default avatarBjorn Helgaas <bhelgaas@google.com>

Bug: 390546635

(cherry picked from commit 62b6dee1)
Change-Id: Id767eb3ee0a5f27f009ec2efa3753a6463152a71
Signed-off-by: default avatarJian Yang <jian.yang@mediatek.corp-partner.google.com>
parent dbdf659c
Loading
Loading
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment