Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag '3.7-pci-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci

Pull PCI fixes from Bjorn Helgaas:
"Power management:
- PCI/PM: Fix proc config reg access for D3cold and bridge
suspending
- PCI/PM: Resume device before shutdown
- PCI/PM: Fix deadlock when unbinding device if parent in D3cold
Hotplug:
- PCI/portdrv: Don't create hotplug slots unless port supports
hotplug"

* tag '3.7-pci-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci:
PCI/portdrv: Don't create hotplug slots unless port supports hotplug
PCI/PM: Fix proc config reg access for D3cold and bridge suspending
PCI/PM: Resume device before shutdown
PCI/PM: Fix deadlock when unbinding device if parent in D3cold

+62 -52
-3
drivers/pci/bus.c
··· 320 320 } else 321 321 next = dev->bus_list.next; 322 322 323 - /* Run device routines with the device locked */ 324 - device_lock(&dev->dev); 325 323 retval = cb(dev, userdata); 326 - device_unlock(&dev->dev); 327 324 if (retval) 328 325 break; 329 326 }
+2 -10
drivers/pci/pci-driver.c
··· 398 398 struct pci_dev *pci_dev = to_pci_dev(dev); 399 399 struct pci_driver *drv = pci_dev->driver; 400 400 401 + pm_runtime_resume(dev); 402 + 401 403 if (drv && drv->shutdown) 402 404 drv->shutdown(pci_dev); 403 405 pci_msi_shutdown(pci_dev); ··· 410 408 * continue to do DMA 411 409 */ 412 410 pci_disable_device(pci_dev); 413 - 414 - /* 415 - * Devices may be enabled to wake up by runtime PM, but they need not 416 - * be supposed to wake up the system from its "power off" state (e.g. 417 - * ACPI S5). Therefore disable wakeup for all devices that aren't 418 - * supposed to wake up the system at this point. The state argument 419 - * will be ignored by pci_enable_wake(). 420 - */ 421 - if (!device_may_wakeup(dev)) 422 - pci_enable_wake(pci_dev, PCI_UNKNOWN, false); 423 411 } 424 412 425 413 #ifdef CONFIG_PM
-34
drivers/pci/pci-sysfs.c
··· 458 458 } 459 459 struct device_attribute vga_attr = __ATTR_RO(boot_vga); 460 460 461 - static void 462 - pci_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 - 484 - static void 485 - pci_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 - 495 461 static ssize_t 496 462 pci_read_config(struct file *filp, struct kobject *kobj, 497 463 struct bin_attribute *bin_attr,
+32
drivers/pci/pci.c
··· 1858 1858 } 1859 1859 EXPORT_SYMBOL_GPL(pci_dev_run_wake); 1860 1860 1861 + void 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 + 1883 + void 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 1894 * pci_pm_init - Initialize PM functions of given PCI device 1863 1895 * @dev: PCI device to handle.
+2
drivers/pci/pci.h
··· 72 72 extern int pci_finish_runtime_suspend(struct pci_dev *dev); 73 73 extern int __pci_pme_wakeup(struct pci_dev *dev, void *ign); 74 74 extern void pci_wakeup_bus(struct pci_bus *bus); 75 + extern void pci_config_pm_runtime_get(struct pci_dev *dev); 76 + extern void pci_config_pm_runtime_put(struct pci_dev *dev); 75 77 extern void pci_pm_init(struct pci_dev *dev); 76 78 extern void platform_pci_wakeup_init(struct pci_dev *dev); 77 79 extern void pci_allocate_cap_save_buffers(struct pci_dev *dev);
+16 -4
drivers/pci/pcie/aer/aerdrv_core.c
··· 213 213 struct aer_broadcast_data *result_data; 214 214 result_data = (struct aer_broadcast_data *) data; 215 215 216 + device_lock(&dev->dev); 216 217 dev->error_state = result_data->state; 217 218 218 219 if (!dev->driver || ··· 232 231 dev->driver ? 233 232 "no AER-aware driver" : "no driver"); 234 233 } 235 - return 0; 234 + goto out; 236 235 } 237 236 238 237 err_handler = dev->driver->err_handler; 239 238 vote = err_handler->error_detected(dev, result_data->state); 240 239 result_data->result = merge_result(result_data->result, vote); 240 + out: 241 + device_unlock(&dev->dev); 241 242 return 0; 242 243 } 243 244 ··· 250 247 struct aer_broadcast_data *result_data; 251 248 result_data = (struct aer_broadcast_data *) data; 252 249 250 + device_lock(&dev->dev); 253 251 if (!dev->driver || 254 252 !dev->driver->err_handler || 255 253 !dev->driver->err_handler->mmio_enabled) 256 - return 0; 254 + goto out; 257 255 258 256 err_handler = dev->driver->err_handler; 259 257 vote = err_handler->mmio_enabled(dev); 260 258 result_data->result = merge_result(result_data->result, vote); 259 + out: 260 + device_unlock(&dev->dev); 261 261 return 0; 262 262 } 263 263 ··· 271 265 struct aer_broadcast_data *result_data; 272 266 result_data = (struct aer_broadcast_data *) data; 273 267 268 + device_lock(&dev->dev); 274 269 if (!dev->driver || 275 270 !dev->driver->err_handler || 276 271 !dev->driver->err_handler->slot_reset) 277 - return 0; 272 + goto out; 278 273 279 274 err_handler = dev->driver->err_handler; 280 275 vote = err_handler->slot_reset(dev); 281 276 result_data->result = merge_result(result_data->result, vote); 277 + out: 278 + device_unlock(&dev->dev); 282 279 return 0; 283 280 } 284 281 ··· 289 280 { 290 281 const struct pci_error_handlers *err_handler; 291 282 283 + device_lock(&dev->dev); 292 284 dev->error_state = pci_channel_io_normal; 293 285 294 286 if (!dev->driver || 295 287 !dev->driver->err_handler || 296 288 !dev->driver->err_handler->resume) 297 - return 0; 289 + goto out; 298 290 299 291 err_handler = dev->driver->err_handler; 300 292 err_handler->resume(dev); 293 + out: 294 + device_unlock(&dev->dev); 301 295 return 0; 302 296 } 303 297
+2 -1
drivers/pci/pcie/portdrv_core.c
··· 272 272 } 273 273 274 274 /* Hot-Plug Capable */ 275 - if (cap_mask & PCIE_PORT_SERVICE_HP) { 275 + if ((cap_mask & PCIE_PORT_SERVICE_HP) && 276 + dev->pcie_flags_reg & PCI_EXP_FLAGS_SLOT) { 276 277 pcie_capability_read_dword(dev, PCI_EXP_SLTCAP, &reg32); 277 278 if (reg32 & PCI_EXP_SLTCAP_HPC) { 278 279 services |= PCIE_PORT_SERVICE_HP;
+8
drivers/pci/proc.c
··· 76 76 if (!access_ok(VERIFY_WRITE, buf, cnt)) 77 77 return -EINVAL; 78 78 79 + pci_config_pm_runtime_get(dev); 80 + 79 81 if ((pos & 1) && cnt) { 80 82 unsigned char val; 81 83 pci_user_read_config_byte(dev, pos, &val); ··· 123 121 cnt--; 124 122 } 125 123 124 + pci_config_pm_runtime_put(dev); 125 + 126 126 *ppos = pos; 127 127 return nbytes; 128 128 } ··· 149 145 150 146 if (!access_ok(VERIFY_READ, buf, cnt)) 151 147 return -EINVAL; 148 + 149 + pci_config_pm_runtime_get(dev); 152 150 153 151 if ((pos & 1) && cnt) { 154 152 unsigned char val; ··· 196 190 pos++; 197 191 cnt--; 198 192 } 193 + 194 + pci_config_pm_runtime_put(dev); 199 195 200 196 *ppos = pos; 201 197 i_size_write(ino, dp->size);