All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2] PCI: Check PCIe upstream port for PME support
@ 2021-08-12 15:39 Kai-Heng Feng
  2021-10-21  6:56 ` Kai-Heng Feng
  0 siblings, 1 reply; 5+ messages in thread
From: Kai-Heng Feng @ 2021-08-12 15:39 UTC (permalink / raw)
  To: bhelgaas
  Cc: Kai-Heng Feng, Lukas Wunner, Mika Westerberg, Rafael J . Wysocki,
	open list:PCI SUBSYSTEM, open list

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>
---
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


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH v2] PCI: Check PCIe upstream port for PME support
  2021-08-12 15:39 [PATCH v2] PCI: Check PCIe upstream port for PME support Kai-Heng Feng
@ 2021-10-21  6:56 ` Kai-Heng Feng
  2021-10-21 19:13   ` Rafael J. Wysocki
  0 siblings, 1 reply; 5+ messages in thread
From: Kai-Heng Feng @ 2021-10-21  6:56 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Lukas Wunner, Mika Westerberg, Rafael J . Wysocki,
	open list:PCI SUBSYSTEM, open list

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...

> ---
> 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
>

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v2] PCI: Check PCIe upstream port for PME support
  2021-10-21  6:56 ` Kai-Heng Feng
@ 2021-10-21 19:13   ` Rafael J. Wysocki
  2021-10-22  3:04     ` Kai-Heng Feng
  2021-10-22  6:53     ` Lukas Wunner
  0 siblings, 2 replies; 5+ messages in thread
From: Rafael J. Wysocki @ 2021-10-21 19:13 UTC (permalink / raw)
  To: Kai-Heng Feng, Bjorn Helgaas
  Cc: Lukas Wunner, Mika Westerberg, open list:PCI SUBSYSTEM,
	open list, Linux PM

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
>>


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v2] PCI: Check PCIe upstream port for PME support
  2021-10-21 19:13   ` Rafael J. Wysocki
@ 2021-10-22  3:04     ` Kai-Heng Feng
  2021-10-22  6:53     ` Lukas Wunner
  1 sibling, 0 replies; 5+ messages in thread
From: Kai-Heng Feng @ 2021-10-22  3:04 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Bjorn Helgaas, Lukas Wunner, Mika Westerberg,
	open list:PCI SUBSYSTEM, open list, Linux PM

On Fri, Oct 22, 2021 at 3:13 AM Rafael J. Wysocki
<rafael.j.wysocki@intel.com> wrote:
>
> 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?

Will remember this next time.

>
> So you basically want to check whether or not the PME interrupts are
> configured on the port?

Yes, that's the idea here.

Kai-Heng

>
>
> >> ---
> >> 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
> >>
>

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v2] PCI: Check PCIe upstream port for PME support
  2021-10-21 19:13   ` Rafael J. Wysocki
  2021-10-22  3:04     ` Kai-Heng Feng
@ 2021-10-22  6:53     ` Lukas Wunner
  1 sibling, 0 replies; 5+ messages in thread
From: Lukas Wunner @ 2021-10-22  6:53 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Kai-Heng Feng, Bjorn Helgaas, Mika Westerberg,
	open list:PCI SUBSYSTEM, open list, Linux PM

On Thu, Oct 21, 2021 at 09:13:29PM +0200, Rafael J. Wysocki wrote:
> 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.
> 
> So you basically want to check whether or not the PME interrupts are
> configured on the port?

This platform doesn't grant PME handling to OSPM, but the platform
doesn't handle PME itself either (recognizable by the fact that it
didn't set the PME Interrupt Enable bit in the Root Control Register).

The rationale of the patch is to recognize this situation and rely
on PME polling instead.

That is achieved by assuming no PME support for the device, despite
the device claiming that PME is supported.

(This information should probably be included in the commit message.)


> > > 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

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2021-10-22  7:00 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-12 15:39 [PATCH v2] PCI: Check PCIe upstream port for PME support Kai-Heng Feng
2021-10-21  6:56 ` Kai-Heng Feng
2021-10-21 19:13   ` Rafael J. Wysocki
2021-10-22  3:04     ` Kai-Heng Feng
2021-10-22  6:53     ` Lukas Wunner

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.