diff options
-rw-r--r-- | drivers/pci/pci-driver.c | 41 | ||||
-rw-r--r-- | include/linux/pci.h | 3 |
2 files changed, 43 insertions, 1 deletions
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 474e9cd0e9e4..9e7d6ceb3805 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c | |||
@@ -264,6 +264,19 @@ static int pci_device_remove(struct device * dev) | |||
264 | return 0; | 264 | return 0; |
265 | } | 265 | } |
266 | 266 | ||
267 | static int pci_device_suspend_prepare(struct device * dev, pm_message_t state) | ||
268 | { | ||
269 | struct pci_dev * pci_dev = to_pci_dev(dev); | ||
270 | struct pci_driver * drv = pci_dev->driver; | ||
271 | int i = 0; | ||
272 | |||
273 | if (drv && drv->suspend_prepare) { | ||
274 | i = drv->suspend_prepare(pci_dev, state); | ||
275 | suspend_report_result(drv->suspend_prepare, i); | ||
276 | } | ||
277 | return i; | ||
278 | } | ||
279 | |||
267 | static int pci_device_suspend(struct device * dev, pm_message_t state) | 280 | static int pci_device_suspend(struct device * dev, pm_message_t state) |
268 | { | 281 | { |
269 | struct pci_dev * pci_dev = to_pci_dev(dev); | 282 | struct pci_dev * pci_dev = to_pci_dev(dev); |
@@ -279,6 +292,18 @@ static int pci_device_suspend(struct device * dev, pm_message_t state) | |||
279 | return i; | 292 | return i; |
280 | } | 293 | } |
281 | 294 | ||
295 | static int pci_device_suspend_late(struct device * dev, pm_message_t state) | ||
296 | { | ||
297 | struct pci_dev * pci_dev = to_pci_dev(dev); | ||
298 | struct pci_driver * drv = pci_dev->driver; | ||
299 | int i = 0; | ||
300 | |||
301 | if (drv && drv->suspend_late) { | ||
302 | i = drv->suspend_late(pci_dev, state); | ||
303 | suspend_report_result(drv->suspend_late, i); | ||
304 | } | ||
305 | return i; | ||
306 | } | ||
282 | 307 | ||
283 | /* | 308 | /* |
284 | * Default resume method for devices that have no driver provided resume, | 309 | * Default resume method for devices that have no driver provided resume, |
@@ -313,6 +338,17 @@ static int pci_device_resume(struct device * dev) | |||
313 | return error; | 338 | return error; |
314 | } | 339 | } |
315 | 340 | ||
341 | static int pci_device_resume_early(struct device * dev) | ||
342 | { | ||
343 | int error = 0; | ||
344 | struct pci_dev * pci_dev = to_pci_dev(dev); | ||
345 | struct pci_driver * drv = pci_dev->driver; | ||
346 | |||
347 | if (drv && drv->resume_early) | ||
348 | error = drv->resume_early(pci_dev); | ||
349 | return error; | ||
350 | } | ||
351 | |||
316 | static void pci_device_shutdown(struct device *dev) | 352 | static void pci_device_shutdown(struct device *dev) |
317 | { | 353 | { |
318 | struct pci_dev *pci_dev = to_pci_dev(dev); | 354 | struct pci_dev *pci_dev = to_pci_dev(dev); |
@@ -508,9 +544,12 @@ struct bus_type pci_bus_type = { | |||
508 | .uevent = pci_uevent, | 544 | .uevent = pci_uevent, |
509 | .probe = pci_device_probe, | 545 | .probe = pci_device_probe, |
510 | .remove = pci_device_remove, | 546 | .remove = pci_device_remove, |
547 | .suspend_prepare= pci_device_suspend_prepare, | ||
511 | .suspend = pci_device_suspend, | 548 | .suspend = pci_device_suspend, |
512 | .shutdown = pci_device_shutdown, | 549 | .suspend_late = pci_device_suspend_late, |
550 | .resume_early = pci_device_resume_early, | ||
513 | .resume = pci_device_resume, | 551 | .resume = pci_device_resume, |
552 | .shutdown = pci_device_shutdown, | ||
514 | .dev_attrs = pci_dev_attrs, | 553 | .dev_attrs = pci_dev_attrs, |
515 | }; | 554 | }; |
516 | 555 | ||
diff --git a/include/linux/pci.h b/include/linux/pci.h index 8565b81d7fbc..4b2e629467c7 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
@@ -345,7 +345,10 @@ struct pci_driver { | |||
345 | const struct pci_device_id *id_table; /* must be non-NULL for probe to be called */ | 345 | const struct pci_device_id *id_table; /* must be non-NULL for probe to be called */ |
346 | int (*probe) (struct pci_dev *dev, const struct pci_device_id *id); /* New device inserted */ | 346 | int (*probe) (struct pci_dev *dev, const struct pci_device_id *id); /* New device inserted */ |
347 | void (*remove) (struct pci_dev *dev); /* Device removed (NULL if not a hot-plug capable driver) */ | 347 | void (*remove) (struct pci_dev *dev); /* Device removed (NULL if not a hot-plug capable driver) */ |
348 | int (*suspend_prepare) (struct pci_dev *dev, pm_message_t state); | ||
348 | int (*suspend) (struct pci_dev *dev, pm_message_t state); /* Device suspended */ | 349 | int (*suspend) (struct pci_dev *dev, pm_message_t state); /* Device suspended */ |
350 | int (*suspend_late) (struct pci_dev *dev, pm_message_t state); | ||
351 | int (*resume_early) (struct pci_dev *dev); | ||
349 | int (*resume) (struct pci_dev *dev); /* Device woken up */ | 352 | int (*resume) (struct pci_dev *dev); /* Device woken up */ |
350 | int (*enable_wake) (struct pci_dev *dev, pci_power_t state, int enable); /* Enable wake event */ | 353 | int (*enable_wake) (struct pci_dev *dev, pci_power_t state, int enable); /* Enable wake event */ |
351 | void (*shutdown) (struct pci_dev *dev); | 354 | void (*shutdown) (struct pci_dev *dev); |