Messages in this thread | | | Date | Thu, 21 Oct 2021 21:13:29 +0200 | Subject | Re: [PATCH v2] PCI: Check PCIe upstream port for PME support | From | "Rafael J. Wysocki" <> |
| |
On 10/21/2021 8:56 AM, Kai-Heng Feng wrote: > On Thu, Aug 12, 2021 at 11:39 PM Kai-Heng Feng > <kai.heng.feng@canonical.com> wrote: >> Some platforms cannot detect ethernet hotplug once its upstream port is >> runtime suspended because PME isn't granted by BIOS _OSC. The issue can >> be workarounded by "pcie_ports=native". >> >> The vendor confirmed that the PME in _OSC is disabled intentionally for >> system stability issues on the other OS, so we should also honor the PME >> setting here. >> >> So before marking PME support status for the device, check >> PCI_EXP_RTCTL_PMEIE bit to ensure PME interrupt is either enabled by >> firmware or OS. >> >> Cc: Lukas Wunner <lukas@wunner.de> >> Cc: Mika Westerberg <mika.westerberg@linux.intel.com> >> Cc: Rafael J. Wysocki <rafael.j.wysocki@intel.com> >> Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=213873 >> Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com> > A gentle ping...
Any chance to CC this to linux-pm too?
So you basically want to check whether or not the PME interrupts are configured on the port?
>> --- >> v2: >> - Instead of prevent root port from runtime suspending, skip >> initializing PME status for the downstream device. >> >> drivers/pci/pci.c | 28 +++++++++++++++++++++++++++- >> 1 file changed, 27 insertions(+), 1 deletion(-) >> >> diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c >> index aacf575c15cf..4344dc302edd 100644 >> --- a/drivers/pci/pci.c >> +++ b/drivers/pci/pci.c >> @@ -2294,6 +2294,32 @@ void pci_pme_wakeup_bus(struct pci_bus *bus) >> pci_walk_bus(bus, pci_pme_wakeup, (void *)true); >> } >> >> +#ifdef CONFIG_PCIE_PME >> +static bool pci_pcie_port_pme_enabled(struct pci_dev *dev) >> +{ >> + struct pci_dev *bridge = pci_upstream_bridge(dev); >> + u16 val; >> + int ret; >> + >> + if (!bridge) >> + return true; >> + >> + if (pci_pcie_type(bridge) != PCI_EXP_TYPE_ROOT_PORT && >> + pci_pcie_type(bridge) != PCI_EXP_TYPE_RC_EC) >> + return true; >> + >> + ret = pcie_capability_read_word(bridge, PCI_EXP_RTCTL, &val); >> + if (ret) >> + return false; >> + >> + return val & PCI_EXP_RTCTL_PMEIE; >> +} >> +#else >> +static bool pci_pcie_port_pme_enabled(struct pci_dev *dev) >> +{ >> + return true; >> +} >> +#endif >> >> /** >> * pci_pme_capable - check the capability of PCI device to generate PME# >> @@ -3095,7 +3121,7 @@ void pci_pm_init(struct pci_dev *dev) >> } >> >> pmc &= PCI_PM_CAP_PME_MASK; >> - if (pmc) { >> + if (pmc && pci_pcie_port_pme_enabled(dev)) { >> pci_info(dev, "PME# supported from%s%s%s%s%s\n", >> (pmc & PCI_PM_CAP_PME_D0) ? " D0" : "", >> (pmc & PCI_PM_CAP_PME_D1) ? " D1" : "", >> -- >> 2.32.0 >>
| |