diff options
Diffstat (limited to 'drivers/pci/pci-driver.c')
-rw-r--r-- | drivers/pci/pci-driver.c | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index b1c0c707d9..e5ae3a0c13 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c | |||
@@ -265,6 +265,13 @@ static int pci_device_remove(struct device * dev) | |||
265 | } | 265 | } |
266 | 266 | ||
267 | /* | 267 | /* |
268 | * If the device is still on, set the power state as "unknown", | ||
269 | * since it might change by the next time we load the driver. | ||
270 | */ | ||
271 | if (pci_dev->current_state == PCI_D0) | ||
272 | pci_dev->current_state = PCI_UNKNOWN; | ||
273 | |||
274 | /* | ||
268 | * We would love to complain here if pci_dev->is_enabled is set, that | 275 | * We would love to complain here if pci_dev->is_enabled is set, that |
269 | * the driver should have called pci_disable_device(), but the | 276 | * the driver should have called pci_disable_device(), but the |
270 | * unfortunate fact is there are too many odd BIOS and bridge setups | 277 | * unfortunate fact is there are too many odd BIOS and bridge setups |
@@ -288,6 +295,12 @@ static int pci_device_suspend(struct device * dev, pm_message_t state) | |||
288 | suspend_report_result(drv->suspend, i); | 295 | suspend_report_result(drv->suspend, i); |
289 | } else { | 296 | } else { |
290 | pci_save_state(pci_dev); | 297 | pci_save_state(pci_dev); |
298 | /* | ||
299 | * mark its power state as "unknown", since we don't know if | ||
300 | * e.g. the BIOS will change its device state when we suspend. | ||
301 | */ | ||
302 | if (pci_dev->current_state == PCI_D0) | ||
303 | pci_dev->current_state = PCI_UNKNOWN; | ||
291 | } | 304 | } |
292 | return i; | 305 | return i; |
293 | } | 306 | } |
@@ -316,8 +329,8 @@ static int pci_default_resume(struct pci_dev *pci_dev) | |||
316 | /* restore the PCI config space */ | 329 | /* restore the PCI config space */ |
317 | pci_restore_state(pci_dev); | 330 | pci_restore_state(pci_dev); |
318 | /* if the device was enabled before suspend, reenable */ | 331 | /* if the device was enabled before suspend, reenable */ |
319 | if (pci_dev->is_enabled) | 332 | if (atomic_read(&pci_dev->enable_cnt)) |
320 | retval = pci_enable_device(pci_dev); | 333 | retval = __pci_enable_device(pci_dev); |
321 | /* if the device was busmaster before the suspend, make it busmaster again */ | 334 | /* if the device was busmaster before the suspend, make it busmaster again */ |
322 | if (pci_dev->is_busmaster) | 335 | if (pci_dev->is_busmaster) |
323 | pci_set_master(pci_dev); | 336 | pci_set_master(pci_dev); |
@@ -432,9 +445,12 @@ int __pci_register_driver(struct pci_driver *drv, struct module *owner) | |||
432 | 445 | ||
433 | /* register with core */ | 446 | /* register with core */ |
434 | error = driver_register(&drv->driver); | 447 | error = driver_register(&drv->driver); |
448 | if (error) | ||
449 | return error; | ||
435 | 450 | ||
436 | if (!error) | 451 | error = pci_create_newid_file(drv); |
437 | error = pci_create_newid_file(drv); | 452 | if (error) |
453 | driver_unregister(&drv->driver); | ||
438 | 454 | ||
439 | return error; | 455 | return error; |
440 | } | 456 | } |