PCI PM: Run default PM callbacks for all devices using new framework
It should be quite clear that it generally makes sense to execute
the default PM callbacks (ie. the callbacks used for handling
suspend, hibernation and resume of PCI devices without drivers) for
all devices. Of course, the drivers that provide legacy PCI PM
support (ie. the ->suspend, ->suspend_late, ->resume_early
or ->resume hooks in the pci_driver structure), carry out these
operations too, so we can't do it for devices with such drivers.
Still, we can make the default PM callbacks run for devices with
drivers using the new framework (ie. implement the pm object), since
there are no such drivers at the moment.
This also simplifies the code and makes it smaller.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@suse.cz>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 02bf4d4..b7e67c2 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -486,6 +486,8 @@
if (!pci_is_bridge(pci_dev))
pci_prepare_to_sleep(pci_dev);
+
+ pci_fixup_device(pci_fixup_suspend, pci_dev);
}
static bool pci_has_legacy_pm_support(struct pci_dev *pci_dev)
@@ -536,16 +538,13 @@
if (pci_has_legacy_pm_support(pci_dev))
return pci_legacy_suspend(dev, PMSG_SUSPEND);
- if (drv && drv->pm) {
- if (drv->pm->suspend) {
- error = drv->pm->suspend(dev);
- suspend_report_result(drv->pm->suspend, error);
- }
- } else {
- pci_pm_default_suspend(pci_dev);
+ if (drv && drv->pm && drv->pm->suspend) {
+ error = drv->pm->suspend(dev);
+ suspend_report_result(drv->pm->suspend, error);
}
- pci_fixup_device(pci_fixup_suspend, pci_dev);
+ if (!error)
+ pci_pm_default_suspend(pci_dev);
return error;
}
@@ -559,15 +558,14 @@
if (pci_has_legacy_pm_support(pci_dev))
return pci_legacy_suspend_late(dev, PMSG_SUSPEND);
- if (drv && drv->pm) {
- if (drv->pm->suspend_noirq) {
- error = drv->pm->suspend_noirq(dev);
- suspend_report_result(drv->pm->suspend_noirq, error);
- }
- } else {
- pci_pm_set_unknown_state(pci_dev);
+ if (drv && drv->pm && drv->pm->suspend_noirq) {
+ error = drv->pm->suspend_noirq(dev);
+ suspend_report_result(drv->pm->suspend_noirq, error);
}
+ if (!error)
+ pci_pm_set_unknown_state(pci_dev);
+
return error;
}
@@ -580,14 +578,10 @@
if (pci_has_legacy_pm_support(pci_dev))
return pci_legacy_resume(dev);
- if (drv && drv->pm) {
- pci_fixup_device(pci_fixup_resume, pci_dev);
+ error = pci_pm_default_resume(pci_dev);
- if (drv->pm->resume)
- error = drv->pm->resume(dev);
- } else {
- error = pci_pm_default_resume(pci_dev);
- }
+ if (!error && drv && drv->pm && drv->pm->resume)
+ error = drv->pm->resume(dev);
return error;
}
@@ -601,14 +595,10 @@
if (pci_has_legacy_pm_support(pci_dev))
return pci_legacy_resume_early(dev);
- if (drv && drv->pm) {
- pci_fixup_device(pci_fixup_resume_early, pci_dev);
+ pci_pm_default_resume_noirq(pci_dev);
- if (drv->pm->resume_noirq)
- error = drv->pm->resume_noirq(dev);
- } else {
- pci_pm_default_resume_noirq(pci_dev);
- }
+ if (drv && drv->pm && drv->pm->resume_noirq)
+ error = drv->pm->resume_noirq(dev);
return error;
}
@@ -633,15 +623,14 @@
if (pci_has_legacy_pm_support(pci_dev))
return pci_legacy_suspend(dev, PMSG_FREEZE);
- if (drv && drv->pm) {
- if (drv->pm->freeze) {
- error = drv->pm->freeze(dev);
- suspend_report_result(drv->pm->freeze, error);
- }
- } else {
- pci_pm_default_suspend_generic(pci_dev);
+ if (drv && drv->pm && drv->pm->freeze) {
+ error = drv->pm->freeze(dev);
+ suspend_report_result(drv->pm->freeze, error);
}
+ if (!error)
+ pci_pm_default_suspend_generic(pci_dev);
+
return error;
}
@@ -654,15 +643,14 @@
if (pci_has_legacy_pm_support(pci_dev))
return pci_legacy_suspend_late(dev, PMSG_FREEZE);
- if (drv && drv->pm) {
- if (drv->pm->freeze_noirq) {
- error = drv->pm->freeze_noirq(dev);
- suspend_report_result(drv->pm->freeze_noirq, error);
- }
- } else {
- pci_pm_set_unknown_state(pci_dev);
+ if (drv && drv->pm && drv->pm->freeze_noirq) {
+ error = drv->pm->freeze_noirq(dev);
+ suspend_report_result(drv->pm->freeze_noirq, error);
}
+ if (!error)
+ pci_pm_set_unknown_state(pci_dev);
+
return error;
}
@@ -675,12 +663,10 @@
if (pci_has_legacy_pm_support(pci_dev))
return pci_legacy_resume(dev);
- if (drv && drv->pm) {
- if (drv->pm->thaw)
- error = drv->pm->thaw(dev);
- } else {
- pci_pm_reenable_device(pci_dev);
- }
+ pci_pm_reenable_device(pci_dev);
+
+ if (drv && drv->pm && drv->pm->thaw)
+ error = drv->pm->thaw(dev);
return error;
}
@@ -694,12 +680,10 @@
if (pci_has_legacy_pm_support(pci_dev))
return pci_legacy_resume_early(dev);
- if (drv && drv->pm) {
- if (drv->pm->thaw_noirq)
- error = drv->pm->thaw_noirq(dev);
- } else {
- pci_update_current_state(pci_dev, PCI_D0);
- }
+ pci_update_current_state(pci_dev, PCI_D0);
+
+ if (drv && drv->pm && drv->pm->thaw_noirq)
+ error = drv->pm->thaw_noirq(dev);
return error;
}
@@ -713,16 +697,13 @@
if (pci_has_legacy_pm_support(pci_dev))
return pci_legacy_suspend(dev, PMSG_HIBERNATE);
- if (drv && drv->pm) {
- if (drv->pm->poweroff) {
- error = drv->pm->poweroff(dev);
- suspend_report_result(drv->pm->poweroff, error);
- }
- } else {
- pci_pm_default_suspend(pci_dev);
+ if (drv && drv->pm && drv->pm->poweroff) {
+ error = drv->pm->poweroff(dev);
+ suspend_report_result(drv->pm->poweroff, error);
}
- pci_fixup_device(pci_fixup_suspend, pci_dev);
+ if (!error)
+ pci_pm_default_suspend(pci_dev);
return error;
}
@@ -735,11 +716,9 @@
if (pci_has_legacy_pm_support(to_pci_dev(dev)))
return pci_legacy_suspend_late(dev, PMSG_HIBERNATE);
- if (drv && drv->pm) {
- if (drv->pm->poweroff_noirq) {
- error = drv->pm->poweroff_noirq(dev);
- suspend_report_result(drv->pm->poweroff_noirq, error);
- }
+ if (drv && drv->pm && drv->pm->poweroff_noirq) {
+ error = drv->pm->poweroff_noirq(dev);
+ suspend_report_result(drv->pm->poweroff_noirq, error);
}
return error;
@@ -754,14 +733,10 @@
if (pci_has_legacy_pm_support(pci_dev))
return pci_legacy_resume(dev);
- if (drv && drv->pm) {
- pci_fixup_device(pci_fixup_resume, pci_dev);
+ error = pci_pm_default_resume(pci_dev);
- if (drv->pm->restore)
- error = drv->pm->restore(dev);
- } else {
- error = pci_pm_default_resume(pci_dev);
- }
+ if (!error && drv && drv->pm && drv->pm->restore)
+ error = drv->pm->restore(dev);
return error;
}
@@ -775,14 +750,10 @@
if (pci_has_legacy_pm_support(pci_dev))
return pci_legacy_resume_early(dev);
- if (drv && drv->pm) {
- pci_fixup_device(pci_fixup_resume_early, pci_dev);
+ pci_pm_default_resume_noirq(pci_dev);
- if (drv->pm->restore_noirq)
- error = drv->pm->restore_noirq(dev);
- } else {
- pci_pm_default_resume_noirq(pci_dev);
- }
+ if (drv && drv->pm && drv->pm->restore_noirq)
+ error = drv->pm->restore_noirq(dev);
return error;
}