aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/pci-driver.c
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2009-01-07 07:05:05 -0500
committerJesse Barnes <jbarnes@virtuousgeek.org>2009-01-07 14:15:18 -0500
commit571ff7584bb9e05fca0eb79752ae55a46faf3a98 (patch)
treea9439b1749154f2a7d4ed18c28a4d221235f2f3b /drivers/pci/pci-driver.c
parentfa58d305d9925b01830e535896a7227a868a9e15 (diff)
PCI PM: Power-manage devices without drivers during suspend-resume
PCI devices without drivers can be put into low power states during suspend with the help of pci_prepare_to_sleep() and prevented from generating wake-up events during resume with the help of pci_enable_wake(). However, it's better not to put bridges into low power states during suspend, because that might result in entire bus segments being powered off. Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl> Acked-by: Pavel Machek <pavel@suse.cz> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'drivers/pci/pci-driver.c')
-rw-r--r--drivers/pci/pci-driver.c33
1 files changed, 29 insertions, 4 deletions
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 57cb0015a470..2617ebb34e14 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -435,6 +435,31 @@ static int pci_legacy_resume_early(struct device *dev)
435 return error; 435 return error;
436} 436}
437 437
438/* Auxiliary functions used by the new power management framework */
439
440static bool pci_is_bridge(struct pci_dev *pci_dev)
441{
442 return !!(pci_dev->subordinate);
443}
444
445static int pci_pm_default_resume(struct pci_dev *pci_dev)
446{
447 if (!pci_is_bridge(pci_dev))
448 pci_enable_wake(pci_dev, PCI_D0, false);
449
450 return pci_default_pm_resume_late(pci_dev);
451}
452
453static void pci_pm_default_suspend(struct pci_dev *pci_dev)
454{
455 pci_default_pm_suspend_early(pci_dev);
456
457 if (!pci_is_bridge(pci_dev))
458 pci_prepare_to_sleep(pci_dev);
459}
460
461/* New power management framework */
462
438static int pci_pm_prepare(struct device *dev) 463static int pci_pm_prepare(struct device *dev)
439{ 464{
440 struct device_driver *drv = dev->driver; 465 struct device_driver *drv = dev->driver;
@@ -470,7 +495,7 @@ static int pci_pm_suspend(struct device *dev)
470 } else if (pci_has_legacy_pm_support(pci_dev)) { 495 } else if (pci_has_legacy_pm_support(pci_dev)) {
471 error = pci_legacy_suspend(dev, PMSG_SUSPEND); 496 error = pci_legacy_suspend(dev, PMSG_SUSPEND);
472 } else { 497 } else {
473 pci_default_pm_suspend_early(pci_dev); 498 pci_pm_default_suspend(pci_dev);
474 } 499 }
475 500
476 pci_fixup_device(pci_fixup_suspend, pci_dev); 501 pci_fixup_device(pci_fixup_suspend, pci_dev);
@@ -512,7 +537,7 @@ static int pci_pm_resume(struct device *dev)
512 } else if (pci_has_legacy_pm_support(pci_dev)) { 537 } else if (pci_has_legacy_pm_support(pci_dev)) {
513 error = pci_legacy_resume(dev); 538 error = pci_legacy_resume(dev);
514 } else { 539 } else {
515 error = pci_default_pm_resume_late(pci_dev); 540 error = pci_pm_default_resume(pci_dev);
516 } 541 }
517 542
518 return error; 543 return error;
@@ -642,7 +667,7 @@ static int pci_pm_poweroff(struct device *dev)
642 } else if (pci_has_legacy_pm_support(pci_dev)) { 667 } else if (pci_has_legacy_pm_support(pci_dev)) {
643 error = pci_legacy_suspend(dev, PMSG_HIBERNATE); 668 error = pci_legacy_suspend(dev, PMSG_HIBERNATE);
644 } else { 669 } else {
645 pci_default_pm_suspend_early(pci_dev); 670 pci_pm_default_suspend(pci_dev);
646 } 671 }
647 672
648 pci_fixup_device(pci_fixup_suspend, pci_dev); 673 pci_fixup_device(pci_fixup_suspend, pci_dev);
@@ -681,7 +706,7 @@ static int pci_pm_restore(struct device *dev)
681 } else if (pci_has_legacy_pm_support(pci_dev)) { 706 } else if (pci_has_legacy_pm_support(pci_dev)) {
682 error = pci_legacy_resume(dev); 707 error = pci_legacy_resume(dev);
683 } else { 708 } else {
684 error = pci_default_pm_resume_late(pci_dev); 709 error = pci_pm_default_resume(pci_dev);
685 } 710 }
686 711
687 return error; 712 return error;