aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/pci/pci-sysfs.c34
-rw-r--r--drivers/pci/pci.c32
-rw-r--r--drivers/pci/pci.h2
-rw-r--r--drivers/pci/proc.c8
4 files changed, 42 insertions, 34 deletions
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 02d107b15281..f39378d9da15 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -458,40 +458,6 @@ boot_vga_show(struct device *dev, struct device_attribute *attr, char *buf)
458} 458}
459struct device_attribute vga_attr = __ATTR_RO(boot_vga); 459struct device_attribute vga_attr = __ATTR_RO(boot_vga);
460 460
461static void
462pci_config_pm_runtime_get(struct pci_dev *pdev)
463{
464 struct device *dev = &pdev->dev;
465 struct device *parent = dev->parent;
466
467 if (parent)
468 pm_runtime_get_sync(parent);
469 pm_runtime_get_noresume(dev);
470 /*
471 * pdev->current_state is set to PCI_D3cold during suspending,
472 * so wait until suspending completes
473 */
474 pm_runtime_barrier(dev);
475 /*
476 * Only need to resume devices in D3cold, because config
477 * registers are still accessible for devices suspended but
478 * not in D3cold.
479 */
480 if (pdev->current_state == PCI_D3cold)
481 pm_runtime_resume(dev);
482}
483
484static void
485pci_config_pm_runtime_put(struct pci_dev *pdev)
486{
487 struct device *dev = &pdev->dev;
488 struct device *parent = dev->parent;
489
490 pm_runtime_put(dev);
491 if (parent)
492 pm_runtime_put_sync(parent);
493}
494
495static ssize_t 461static ssize_t
496pci_read_config(struct file *filp, struct kobject *kobj, 462pci_read_config(struct file *filp, struct kobject *kobj,
497 struct bin_attribute *bin_attr, 463 struct bin_attribute *bin_attr,
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 54858838f098..aabf64798bda 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -1858,6 +1858,38 @@ bool pci_dev_run_wake(struct pci_dev *dev)
1858} 1858}
1859EXPORT_SYMBOL_GPL(pci_dev_run_wake); 1859EXPORT_SYMBOL_GPL(pci_dev_run_wake);
1860 1860
1861void pci_config_pm_runtime_get(struct pci_dev *pdev)
1862{
1863 struct device *dev = &pdev->dev;
1864 struct device *parent = dev->parent;
1865
1866 if (parent)
1867 pm_runtime_get_sync(parent);
1868 pm_runtime_get_noresume(dev);
1869 /*
1870 * pdev->current_state is set to PCI_D3cold during suspending,
1871 * so wait until suspending completes
1872 */
1873 pm_runtime_barrier(dev);
1874 /*
1875 * Only need to resume devices in D3cold, because config
1876 * registers are still accessible for devices suspended but
1877 * not in D3cold.
1878 */
1879 if (pdev->current_state == PCI_D3cold)
1880 pm_runtime_resume(dev);
1881}
1882
1883void pci_config_pm_runtime_put(struct pci_dev *pdev)
1884{
1885 struct device *dev = &pdev->dev;
1886 struct device *parent = dev->parent;
1887
1888 pm_runtime_put(dev);
1889 if (parent)
1890 pm_runtime_put_sync(parent);
1891}
1892
1861/** 1893/**
1862 * pci_pm_init - Initialize PM functions of given PCI device 1894 * pci_pm_init - Initialize PM functions of given PCI device
1863 * @dev: PCI device to handle. 1895 * @dev: PCI device to handle.
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index bacbcba69cf3..fd92aab9904b 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -72,6 +72,8 @@ extern void pci_disable_enabled_device(struct pci_dev *dev);
72extern int pci_finish_runtime_suspend(struct pci_dev *dev); 72extern int pci_finish_runtime_suspend(struct pci_dev *dev);
73extern int __pci_pme_wakeup(struct pci_dev *dev, void *ign); 73extern int __pci_pme_wakeup(struct pci_dev *dev, void *ign);
74extern void pci_wakeup_bus(struct pci_bus *bus); 74extern void pci_wakeup_bus(struct pci_bus *bus);
75extern void pci_config_pm_runtime_get(struct pci_dev *dev);
76extern void pci_config_pm_runtime_put(struct pci_dev *dev);
75extern void pci_pm_init(struct pci_dev *dev); 77extern void pci_pm_init(struct pci_dev *dev);
76extern void platform_pci_wakeup_init(struct pci_dev *dev); 78extern void platform_pci_wakeup_init(struct pci_dev *dev);
77extern void pci_allocate_cap_save_buffers(struct pci_dev *dev); 79extern void pci_allocate_cap_save_buffers(struct pci_dev *dev);
diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c
index eb907a8faf2a..9b8505ccc56d 100644
--- a/drivers/pci/proc.c
+++ b/drivers/pci/proc.c
@@ -76,6 +76,8 @@ proc_bus_pci_read(struct file *file, char __user *buf, size_t nbytes, loff_t *pp
76 if (!access_ok(VERIFY_WRITE, buf, cnt)) 76 if (!access_ok(VERIFY_WRITE, buf, cnt))
77 return -EINVAL; 77 return -EINVAL;
78 78
79 pci_config_pm_runtime_get(dev);
80
79 if ((pos & 1) && cnt) { 81 if ((pos & 1) && cnt) {
80 unsigned char val; 82 unsigned char val;
81 pci_user_read_config_byte(dev, pos, &val); 83 pci_user_read_config_byte(dev, pos, &val);
@@ -121,6 +123,8 @@ proc_bus_pci_read(struct file *file, char __user *buf, size_t nbytes, loff_t *pp
121 cnt--; 123 cnt--;
122 } 124 }
123 125
126 pci_config_pm_runtime_put(dev);
127
124 *ppos = pos; 128 *ppos = pos;
125 return nbytes; 129 return nbytes;
126} 130}
@@ -146,6 +150,8 @@ proc_bus_pci_write(struct file *file, const char __user *buf, size_t nbytes, lof
146 if (!access_ok(VERIFY_READ, buf, cnt)) 150 if (!access_ok(VERIFY_READ, buf, cnt))
147 return -EINVAL; 151 return -EINVAL;
148 152
153 pci_config_pm_runtime_get(dev);
154
149 if ((pos & 1) && cnt) { 155 if ((pos & 1) && cnt) {
150 unsigned char val; 156 unsigned char val;
151 __get_user(val, buf); 157 __get_user(val, buf);
@@ -191,6 +197,8 @@ proc_bus_pci_write(struct file *file, const char __user *buf, size_t nbytes, lof
191 cnt--; 197 cnt--;
192 } 198 }
193 199
200 pci_config_pm_runtime_put(dev);
201
194 *ppos = pos; 202 *ppos = pos;
195 i_size_write(ino, dp->size); 203 i_size_write(ino, dp->size);
196 return nbytes; 204 return nbytes;