#
8a039557 |
|
10-Oct-2023 |
Bjorn Helgaas <bhelgaas@google.com> |
PCI/portdrv: Use FIELD_GET() Use FIELD_GET() to remove dependences on the field position, i.e., the shift value. No functional change intended. Link: https://lore.kernel.org/r/20231010204436.1000644-11-helgaas@kernel.org Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> Reviewed-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
|
#
62b6dee1 |
|
31-Jan-2023 |
Huacai Chen <chenhuacai@kernel.org> |
PCI/portdrv: Prevent LS7A Bus Master clearing on shutdown After cc27b735ad3a ("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 Signed-off-by: Huacai Chen <chenhuacai@loongson.cn> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
|
#
d8d2b65a |
|
09-Dec-2022 |
Bjorn Helgaas <bhelgaas@google.com> |
PCI/portdrv: Allow AER service only for Root Ports & RCECs Previously portdrv allowed the AER service for any device with an AER capability (assuming Linux had control of AER) even though the AER service driver only attaches to Root Port and RCECs. Because get_port_device_capability() included AER for non-RP, non-RCEC devices, we tried to initialize the AER IRQ even though these devices don't generate AER interrupts. Intel DG1 and DG2 discrete graphics cards contain a switch leading to a GPU. The switch supports AER but not MSI, so initializing an AER IRQ failed, and portdrv failed to claim the switch port at all. The GPU itself could be suspended, but the switch could not be put in a low-power state because it had no driver. Don't allow the AER service on non-Root Port, non-Root Complex Event Collector devices. This means we won't enable Bus Mastering if the device doesn't require MSI, the AER service will not appear in sysfs, and the AER service driver will not bind to the device. Link: https://lore.kernel.org/r/20221207084105.84947-1-mika.westerberg@linux.intel.com Link: https://lore.kernel.org/r/20221210002922.1749403-1-helgaas@kernel.org Based-on-patch-by: Mika Westerberg <mika.westerberg@linux.intel.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
|
#
461a65d7 |
|
19-Oct-2022 |
Bjorn Helgaas <bhelgaas@google.com> |
PCI/portdrv: Unexport pcie_port_service_register(), pcie_port_service_unregister() pcie_port_service_register() and pcie_port_service_unregister() are used only by the pciehp, aer, dpc, and pme PCIe port service drivers, none of which can be modules. Unexport pcie_port_service_register() and pcie_port_service_unregister(). No functional change intended. Link: https://lore.kernel.org/r/20221019204127.44463-4-helgaas@kernel.org Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Keith Busch <kbusch@kernel.org>
|
#
29f193fe |
|
19-Oct-2022 |
Bjorn Helgaas <bhelgaas@google.com> |
PCI/portdrv: Move private things to portdrv.c Previously several things used by portdrv_core.c and portdrv_pci.c were shared by defining them in portdrv.h. Now that portdrv_core.c and portdrv_pci.c have been squashed, move things that can be private into portdrv.c. No functional change intended. Link: https://lore.kernel.org/r/20221019204127.44463-3-helgaas@kernel.org Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Keith Busch <kbusch@kernel.org>
|
#
a1ccd3d9 |
|
19-Oct-2022 |
Bjorn Helgaas <bhelgaas@google.com> |
PCI/portdrv: Squash into portdrv.c Squash portdrv_core.c and portdrv_pci.c into portdrv.c to make it easier to find things. The whole thing is less than 1000 lines, and it's a pain to bounce back and forth between two files. Several portdrv_core.c functions were non-static because they were referenced from portdrv_pci.c. Make them static since they're now all in portdrv.c. No functional change intended. Link: https://lore.kernel.org/r/20221019204127.44463-2-helgaas@kernel.org Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Keith Busch <kbusch@kernel.org>
|