diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-13 15:14:47 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-13 15:14:47 -0500 |
commit | 193c0d682525987db59ac3a24531a77e4947aa95 (patch) | |
tree | 7b58346171c4d07e2c2ee6c3c469c325495149a4 /drivers/pci/pci-driver.c | |
parent | 8b0cab14951fbf8126795ab301835a8f8126a988 (diff) | |
parent | 1cb73f8c479e66541fefd3f7fa547b1fa56cdc54 (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.c | 73 |
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 { | |||
248 | static long local_pci_probe(void *_ddi) | 248 | static 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 | ||
1039 | static int pci_pm_runtime_idle(struct device *dev) | 1044 | static 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 | ||
1065 | out: | ||
1052 | pm_runtime_suspend(dev); | 1066 | pm_runtime_suspend(dev); |
1053 | |||
1054 | return 0; | 1067 | return 0; |
1055 | } | 1068 | } |
1056 | 1069 | ||