On Thursday, October 25, 2012 09:36:03 AM Huang Ying wrote: > In > > https://bugzilla.kernel.org/show_bug.cgi?id=48981 > > Peter reported that /proc/bus/pci/??/??.? does not works for 3.6. > This is 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. > > This is the same as /sys/bus/pci/devices/0000:??:??.?/config access > issue. So the function used to solve sysfs issue is used to solve > this issue. > > Cc: stable@xxxxxxxxxxxxxxx > Reported-by: Peter <lekensteyn@xxxxxxxxx> > Signed-off-by: Huang Ying <ying.huang@xxxxxxxxx> Acked-by: Rafael J. Wysocki <rafael.j.wysocki@xxxxxxxxx> > --- > drivers/pci/pci-sysfs.c | 34 ---------------------------------- > drivers/pci/pci.c | 32 ++++++++++++++++++++++++++++++++ > drivers/pci/pci.h | 2 ++ > drivers/pci/proc.c | 8 ++++++++ > 4 files changed, 42 insertions(+), 34 deletions(-) > > --- a/drivers/pci/pci-sysfs.c > +++ b/drivers/pci/pci-sysfs.c > @@ -458,40 +458,6 @@ 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); > - /* > - * Only need to resume devices in D3cold, because config > - * registers are still accessible for devices suspended but > - * not in D3cold. > - */ > - if (pdev->current_state == PCI_D3cold) > - pm_runtime_resume(dev); > -} > - > -static void > -pci_config_pm_runtime_put(struct pci_dev *pdev) > -{ > - struct device *dev = &pdev->dev; > - struct device *parent = dev->parent; > - > - pm_runtime_put(dev); > - if (parent) > - pm_runtime_put_sync(parent); > -} > - > static ssize_t > pci_read_config(struct file *filp, struct kobject *kobj, > struct bin_attribute *bin_attr, > --- a/drivers/pci/pci.c > +++ b/drivers/pci/pci.c > @@ -1858,6 +1858,38 @@ bool pci_dev_run_wake(struct pci_dev *de > } > EXPORT_SYMBOL_GPL(pci_dev_run_wake); > > +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); > + /* > + * Only need to resume devices in D3cold, because config > + * registers are still accessible for devices suspended but > + * not in D3cold. > + */ > + if (pdev->current_state == PCI_D3cold) > + pm_runtime_resume(dev); > +} > + > +void pci_config_pm_runtime_put(struct pci_dev *pdev) > +{ > + struct device *dev = &pdev->dev; > + struct device *parent = dev->parent; > + > + pm_runtime_put(dev); > + if (parent) > + pm_runtime_put_sync(parent); > +} > + > /** > * pci_pm_init - Initialize PM functions of given PCI device > * @dev: PCI device to handle. > --- a/drivers/pci/pci.h > +++ b/drivers/pci/pci.h > @@ -72,6 +72,8 @@ extern void pci_disable_enabled_device(s > extern int pci_finish_runtime_suspend(struct pci_dev *dev); > extern int __pci_pme_wakeup(struct pci_dev *dev, void *ign); > extern void pci_wakeup_bus(struct pci_bus *bus); > +extern void pci_config_pm_runtime_get(struct pci_dev *dev); > +extern void pci_config_pm_runtime_put(struct pci_dev *dev); > extern void pci_pm_init(struct pci_dev *dev); > extern void platform_pci_wakeup_init(struct pci_dev *dev); > extern void pci_allocate_cap_save_buffers(struct pci_dev *dev); > --- a/drivers/pci/proc.c > +++ b/drivers/pci/proc.c > @@ -76,6 +76,8 @@ proc_bus_pci_read(struct file *file, cha > if (!access_ok(VERIFY_WRITE, buf, cnt)) > return -EINVAL; > > + pci_config_pm_runtime_get(dev); > + > if ((pos & 1) && cnt) { > unsigned char val; > pci_user_read_config_byte(dev, pos, &val); > @@ -121,6 +123,8 @@ proc_bus_pci_read(struct file *file, cha > cnt--; > } > > + pci_config_pm_runtime_put(dev); > + > *ppos = pos; > return nbytes; > } > @@ -146,6 +150,8 @@ proc_bus_pci_write(struct file *file, co > if (!access_ok(VERIFY_READ, buf, cnt)) > return -EINVAL; > > + pci_config_pm_runtime_get(dev); > + > if ((pos & 1) && cnt) { > unsigned char val; > __get_user(val, buf); > @@ -191,6 +197,8 @@ proc_bus_pci_write(struct file *file, co > cnt--; > } > > + pci_config_pm_runtime_put(dev); > + > *ppos = pos; > i_size_write(ino, dp->size); > return nbytes; > -- > To unsubscribe from this list: send the line "unsubscribe linux-pm" in > the body of a message to majordomo@xxxxxxxxxxxxxxx > More majordomo info at http://vger.kernel.org/majordomo-info.html > -- I speak only for myself. Rafael J. Wysocki, Intel Open Source Technology Center. -- To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html