aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/pci-driver.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-12-13 15:14:47 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-12-13 15:14:47 -0500
commit193c0d682525987db59ac3a24531a77e4947aa95 (patch)
tree7b58346171c4d07e2c2ee6c3c469c325495149a4 /drivers/pci/pci-driver.c
parent8b0cab14951fbf8126795ab301835a8f8126a988 (diff)
parent1cb73f8c479e66541fefd3f7fa547b1fa56cdc54 (diff)
Merge tag 'for-3.8' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci
Pull PCI update from Bjorn Helgaas: "Host bridge hotplug: - Untangle _PRT from struct pci_bus (Bjorn Helgaas) - Request _OSC control before scanning root bus (Taku Izumi) - Assign resources when adding host bridge (Yinghai Lu) - Remove root bus when removing host bridge (Yinghai Lu) - Remove _PRT during hot remove (Yinghai Lu) SRIOV - Add sysfs knobs to control numVFs (Don Dutile) Power management - Notify devices when power resource turned on (Huang Ying) Bug fixes - Work around broken _SEG on HP xw9300 (Bjorn Helgaas) - Keep runtime PM enabled for unbound PCI devices (Huang Ying) - Fix Optimus dual-GPU runtime D3 suspend issue (Dave Airlie) - Fix xen frontend shutdown issue (David Vrabel) - Work around PLX PCI 9050 BAR alignment erratum (Ian Abbott) Miscellaneous - Add GPL license for drivers/pci/ioapic (Andrew Cooks) - Add standard PCI-X, PCIe ASPM register #defines (Bjorn Helgaas) - NumaChip remote PCI support (Daniel Blueman) - Fix PCIe Link Capabilities Supported Link Speed definition (Jingoo Han) - Convert dev_printk() to dev_info(), etc (Joe Perches) - Add support for non PCI BAR ROM data (Matthew Garrett) - Add x86 support for host bridge translation offset (Mike Yoknis) - Report success only when every driver supports AER (Vijay Pandarathil)" Fix up trivial conflicts. * tag 'for-3.8' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci: (48 commits) PCI: Use phys_addr_t for physical ROM address x86/PCI: Add NumaChip remote PCI support ath9k: Use standard #defines for PCIe Capability ASPM fields iwlwifi: Use standard #defines for PCIe Capability ASPM fields iwlwifi: collapse wrapper for pcie_capability_read_word() iwlegacy: Use standard #defines for PCIe Capability ASPM fields iwlegacy: collapse wrapper for pcie_capability_read_word() cxgb3: Use standard #defines for PCIe Capability ASPM fields PCI: Add standard PCIe Capability Link ASPM field names PCI/portdrv: Use PCI Express Capability accessors PCI: Use standard PCIe Capability Link register field names x86: Use PCI setup data PCI: Add support for non-BAR ROMs PCI: Add pcibios_add_device EFI: Stash ROMs if they're not in the PCI BAR PCI: Add and use standard PCI-X Capability register names PCI/PM: Keep runtime PM enabled for unbound PCI devices xen-pcifront: Handle backend CLOSED without CLOSING PCI: SRIOV control and status via sysfs (documentation) PCI/AER: Report success only when every device has AER-aware driver ...
Diffstat (limited to 'drivers/pci/pci-driver.c')
-rw-r--r--drivers/pci/pci-driver.c73
1 files changed, 43 insertions, 30 deletions
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 1dc78c5cabf8..f79cbcd3944b 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -248,31 +248,26 @@ struct drv_dev_and_id {
248static long local_pci_probe(void *_ddi) 248static long local_pci_probe(void *_ddi)
249{ 249{
250 struct drv_dev_and_id *ddi = _ddi; 250 struct drv_dev_and_id *ddi = _ddi;
251 struct device *dev = &ddi->dev->dev; 251 struct pci_dev *pci_dev = ddi->dev;
252 struct device *parent = dev->parent; 252 struct pci_driver *pci_drv = ddi->drv;
253 struct device *dev = &pci_dev->dev;
253 int rc; 254 int rc;
254 255
255 /* The parent bridge must be in active state when probing */ 256 /*
256 if (parent) 257 * Unbound PCI devices are always put in D0, regardless of
257 pm_runtime_get_sync(parent); 258 * runtime PM status. During probe, the device is set to
258 /* Unbound PCI devices are always set to disabled and suspended. 259 * active and the usage count is incremented. If the driver
259 * During probe, the device is set to enabled and active and the 260 * supports runtime PM, it should call pm_runtime_put_noidle()
260 * usage count is incremented. If the driver supports runtime PM, 261 * in its probe routine and pm_runtime_get_noresume() in its
261 * it should call pm_runtime_put_noidle() in its probe routine and 262 * remove routine.
262 * pm_runtime_get_noresume() in its remove routine.
263 */ 263 */
264 pm_runtime_get_noresume(dev); 264 pm_runtime_get_sync(dev);
265 pm_runtime_set_active(dev); 265 pci_dev->driver = pci_drv;
266 pm_runtime_enable(dev); 266 rc = pci_drv->probe(pci_dev, ddi->id);
267
268 rc = ddi->drv->probe(ddi->dev, ddi->id);
269 if (rc) { 267 if (rc) {
270 pm_runtime_disable(dev); 268 pci_dev->driver = NULL;
271 pm_runtime_set_suspended(dev); 269 pm_runtime_put_sync(dev);
272 pm_runtime_put_noidle(dev);
273 } 270 }
274 if (parent)
275 pm_runtime_put(parent);
276 return rc; 271 return rc;
277} 272}
278 273
@@ -322,10 +317,8 @@ __pci_device_probe(struct pci_driver *drv, struct pci_dev *pci_dev)
322 id = pci_match_device(drv, pci_dev); 317 id = pci_match_device(drv, pci_dev);
323 if (id) 318 if (id)
324 error = pci_call_probe(drv, pci_dev, id); 319 error = pci_call_probe(drv, pci_dev, id);
325 if (error >= 0) { 320 if (error >= 0)
326 pci_dev->driver = drv;
327 error = 0; 321 error = 0;
328 }
329 } 322 }
330 return error; 323 return error;
331} 324}
@@ -361,9 +354,7 @@ static int pci_device_remove(struct device * dev)
361 } 354 }
362 355
363 /* Undo the runtime PM settings in local_pci_probe() */ 356 /* Undo the runtime PM settings in local_pci_probe() */
364 pm_runtime_disable(dev); 357 pm_runtime_put_sync(dev);
365 pm_runtime_set_suspended(dev);
366 pm_runtime_put_noidle(dev);
367 358
368 /* 359 /*
369 * If the device is still on, set the power state as "unknown", 360 * If the device is still on, set the power state as "unknown",
@@ -986,6 +977,13 @@ static int pci_pm_runtime_suspend(struct device *dev)
986 pci_power_t prev = pci_dev->current_state; 977 pci_power_t prev = pci_dev->current_state;
987 int error; 978 int error;
988 979
980 /*
981 * If pci_dev->driver is not set (unbound), the device should
982 * always remain in D0 regardless of the runtime PM status
983 */
984 if (!pci_dev->driver)
985 return 0;
986
989 if (!pm || !pm->runtime_suspend) 987 if (!pm || !pm->runtime_suspend)
990 return -ENOSYS; 988 return -ENOSYS;
991 989
@@ -1007,10 +1005,10 @@ static int pci_pm_runtime_suspend(struct device *dev)
1007 return 0; 1005 return 0;
1008 } 1006 }
1009 1007
1010 if (!pci_dev->state_saved) 1008 if (!pci_dev->state_saved) {
1011 pci_save_state(pci_dev); 1009 pci_save_state(pci_dev);
1012 1010 pci_finish_runtime_suspend(pci_dev);
1013 pci_finish_runtime_suspend(pci_dev); 1011 }
1014 1012
1015 return 0; 1013 return 0;
1016} 1014}
@@ -1021,6 +1019,13 @@ static int pci_pm_runtime_resume(struct device *dev)
1021 struct pci_dev *pci_dev = to_pci_dev(dev); 1019 struct pci_dev *pci_dev = to_pci_dev(dev);
1022 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 1020 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
1023 1021
1022 /*
1023 * If pci_dev->driver is not set (unbound), the device should
1024 * always remain in D0 regardless of the runtime PM status
1025 */
1026 if (!pci_dev->driver)
1027 return 0;
1028
1024 if (!pm || !pm->runtime_resume) 1029 if (!pm || !pm->runtime_resume)
1025 return -ENOSYS; 1030 return -ENOSYS;
1026 1031
@@ -1038,8 +1043,16 @@ static int pci_pm_runtime_resume(struct device *dev)
1038 1043
1039static int pci_pm_runtime_idle(struct device *dev) 1044static int pci_pm_runtime_idle(struct device *dev)
1040{ 1045{
1046 struct pci_dev *pci_dev = to_pci_dev(dev);
1041 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 1047 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
1042 1048
1049 /*
1050 * If pci_dev->driver is not set (unbound), the device should
1051 * always remain in D0 regardless of the runtime PM status
1052 */
1053 if (!pci_dev->driver)
1054 goto out;
1055
1043 if (!pm) 1056 if (!pm)
1044 return -ENOSYS; 1057 return -ENOSYS;
1045 1058
@@ -1049,8 +1062,8 @@ static int pci_pm_runtime_idle(struct device *dev)
1049 return ret; 1062 return ret;
1050 } 1063 }
1051 1064
1065out:
1052 pm_runtime_suspend(dev); 1066 pm_runtime_suspend(dev);
1053
1054 return 0; 1067 return 0;
1055} 1068}
1056 1069