Re: [BUGFIX -v3 3/4] PCI/PM: Fix config reg access for D3cold and bridge suspending

Rafael J. Wysocki
2012-08-14T21:48:04Z

Sorry for the delay.

On Friday, August 10, 2012, Huang Ying wrote:
> On Wed, 2012-08-08 at 09:07 +0800, Huang Ying wrote:
> > This patch fixes the following bug:
> >
> > http://marc.info/?l=linux-pci&m=134338059022620&w=2
> >
> > Where lspci does not work properly if a device and the corresponding
> > parent bridge (such as PCIe port) is suspended. This is because the
> > device configuration space registers will be not accessible if the
> > corresponding parent bridge is suspended or the device is put into
> > D3cold state.
> >
> > To solve the issue, the bridge/PCIe port connected to the device is
> > put into active state before read/write configuration space registers.
> > If the device is in D3cold state, it will be put into active state
> > too.
> >
> > To avoid resume/suspend PCIe port for each configuration register
> > read/write, a small delay is added before the PCIe port to go
> > suspended.
> >
> > Reported-by: Bjorn Mork <bjorn@mork.no>
> > Signed-off-by: Huang Ying <ying.huang@intel.com>
> > ---
> > drivers/pci/pci-sysfs.c | 43 +++++++++++++++++++++++++++++++++++++++++
> > drivers/pci/pcie/portdrv_pci.c | 9 ++++++++
> > 2 files changed, 52 insertions(+)
> >
> > --- a/drivers/pci/pci-sysfs.c
> > +++ b/drivers/pci/pci-sysfs.c
> > @@ -458,6 +458,41 @@ boot_vga_show(struct device *dev, struct
> > }
> > struct device_attribute vga_attr = __ATTR_RO(boot_vga);
> >
> > +static void
> > +pci_config_pm_runtime_get(struct pci_dev *pdev)
> > +{
> > + struct device *dev = &pdev->dev;
> > + struct device *parent = dev->parent;
> > +
> > + if (parent)
> > + pm_runtime_get_sync(parent);
> > + pm_runtime_get_noresume(dev);
> > + /*
> > + * pdev->current_state is set to PCI_D3cold during suspending,
> > + * so wait until suspending completes
> > + */
> > + pm_runtime_barrier(dev);
> > + if (pdev->current_state == PCI_D3cold) {
> > + /*
> > + * Already called pm_runtime_get_noresume above, so
> > + * just calling pm_runtime_resume is sufficient, need
> > + * not to call pm_runtime_get_sync.
> > + */
> > + pm_runtime_resume(dev);
>
> Hi, Rafael,
>
> Do you OK with this new version and the comments added above?

I meant something different. Namely, it may not be entirely clear why
we make the effort to check if pdev->current_state is equal to PCI_D3cold
instead of just calling pm_runtime_get_sync() right after resuming the
parent.

My understanding is that we do it because in principle the device may
be suspended, but not in D3cold, and in that case we don't need to
resume it. If that is the reason, it may be a good idea to document it
in a comment.

The comment explaining why the barrier is there is clearly useful, though.

Thanks,
Rafael