summaryrefslogtreecommitdiffstats
path: root/drivers/acpi/device_pm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/device_pm.c')
-rw-r--r--drivers/acpi/device_pm.c58
1 files changed, 55 insertions, 3 deletions
diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c
index 52fc9042a107..6a9d41c44b70 100644
--- a/drivers/acpi/device_pm.c
+++ b/drivers/acpi/device_pm.c
@@ -1133,6 +1133,58 @@ int acpi_subsys_restore_early(struct device *dev)
return ret ? ret : pm_generic_restore_early(dev);
}
EXPORT_SYMBOL_GPL(acpi_subsys_restore_early);
+
+/**
+ * acpi_subsys_poweroff - Run the device driver's poweroff callback.
+ * @dev: Device to handle.
+ *
+ * Follow PCI and resume devices from runtime suspend before running their
+ * system poweroff callbacks, unless the driver can cope with runtime-suspended
+ * devices during system suspend and there are no ACPI-specific reasons for
+ * resuming them.
+ */
+int acpi_subsys_poweroff(struct device *dev)
+{
+ if (!dev_pm_test_driver_flags(dev, DPM_FLAG_SMART_SUSPEND) ||
+ acpi_dev_needs_resume(dev, ACPI_COMPANION(dev)))
+ pm_runtime_resume(dev);
+
+ return pm_generic_poweroff(dev);
+}
+EXPORT_SYMBOL_GPL(acpi_subsys_poweroff);
+
+/**
+ * acpi_subsys_poweroff_late - Run the device driver's poweroff callback.
+ * @dev: Device to handle.
+ *
+ * Carry out the generic late poweroff procedure for @dev and use ACPI to put
+ * it into a low-power state during system transition into a sleep state.
+ */
+static int acpi_subsys_poweroff_late(struct device *dev)
+{
+ int ret;
+
+ if (dev_pm_smart_suspend_and_suspended(dev))
+ return 0;
+
+ ret = pm_generic_poweroff_late(dev);
+ if (ret)
+ return ret;
+
+ return acpi_dev_suspend(dev, device_may_wakeup(dev));
+}
+
+/**
+ * acpi_subsys_poweroff_noirq - Run the driver's "noirq" poweroff callback.
+ * @dev: Device to suspend.
+ */
+static int acpi_subsys_poweroff_noirq(struct device *dev)
+{
+ if (dev_pm_smart_suspend_and_suspended(dev))
+ return 0;
+
+ return pm_generic_poweroff_noirq(dev);
+}
#endif /* CONFIG_PM_SLEEP */
static struct dev_pm_domain acpi_general_pm_domain = {
@@ -1148,9 +1200,9 @@ static struct dev_pm_domain acpi_general_pm_domain = {
.resume_noirq = acpi_subsys_resume_noirq,
.resume_early = acpi_subsys_resume_early,
.freeze = acpi_subsys_freeze,
- .poweroff = acpi_subsys_suspend,
- .poweroff_late = acpi_subsys_suspend_late,
- .poweroff_noirq = acpi_subsys_suspend_noirq,
+ .poweroff = acpi_subsys_poweroff,
+ .poweroff_late = acpi_subsys_poweroff_late,
+ .poweroff_noirq = acpi_subsys_poweroff_noirq,
.restore_early = acpi_subsys_restore_early,
#endif
},