Commit 4a757148 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'pci-v6.8-fixes-3' of git://git.kernel.org/pub/scm/linux/kernel/git/pci/pci

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
......@@ -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)
......
......@@ -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 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 (bridge && bridge->current_state != PCI_D0)
continue;
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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment