Commit 4a757148 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull pci fixes from Bjorn Helgaas:

 - Keep bridges in D0 if we need to poll downstream devices for PME to
   resolve a v6.6 regression where we failed to enumerate devices below
   bridges put in D3hot by runtime PM, e.g., NVMe drives connected via
   Thunderbolt or USB4 docks (Alex Williamson)

 - Add Siddharth Vadapalli as PCI TI DRA7XX/J721E reviewer

* tag 'pci-v6.8-fixes-3' of git://git.kernel.org/pub/scm/linux/kernel/git/pci/pci:
  MAINTAINERS: Add Siddharth Vadapalli as PCI TI DRA7XX/J721E reviewer
  PCI: Fix active state requirement in PME polling
parents ad645dea 172c0cf5
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -16837,6 +16837,7 @@ F: drivers/pci/controller/dwc/*designware*
PCI DRIVER FOR TI DRA7XX/J721E
M:	Vignesh Raghavendra <vigneshr@ti.com>
R:	Siddharth Vadapalli <s-vadapalli@ti.com>
L:	linux-omap@vger.kernel.org
L:	linux-pci@vger.kernel.org
L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+22 −15
Original line number Diff line number Diff line
@@ -2522,29 +2522,36 @@ static void pci_pme_list_scan(struct work_struct *work)
		if (pdev->pme_poll) {
			struct pci_dev *bridge = pdev->bus->self;
			struct device *dev = &pdev->dev;
			int pm_status;
			struct device *bdev = bridge ? &bridge->dev : NULL;
			int bref = 0;

			/*
			 * If bridge is in low power state, the
			 * configuration space of subordinate devices
			 * may be not accessible
			 */
			if (bridge && bridge->current_state != PCI_D0)
			 * If we have a bridge, it should be in an active/D0
			 * state or the configuration space of subordinate
			 * devices may not be accessible or stable over the
			 * course of the call.
			 */
			if (bdev) {
				bref = pm_runtime_get_if_active(bdev, true);
				if (!bref)
					continue;

				if (bridge->current_state != PCI_D0)
					goto put_bridge;
			}

			/*
			 * If the device is in a low power state it
			 * should not be polled either.
			 * The device itself should be suspended but config
			 * space must be accessible, therefore it cannot be in
			 * D3cold.
			 */
			pm_status = pm_runtime_get_if_active(dev, true);
			if (!pm_status)
				continue;

			if (pdev->current_state != PCI_D3cold)
			if (pm_runtime_suspended(dev) &&
			    pdev->current_state != PCI_D3cold)
				pci_pme_wakeup(pdev, NULL);

			if (pm_status > 0)
				pm_runtime_put(dev);
put_bridge:
			if (bref > 0)
				pm_runtime_put(bdev);
		} else {
			list_del(&pme_dev->list);
			kfree(pme_dev);