summaryrefslogtreecommitdiff
path: root/drivers/acpi/acpi_lpss.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/acpi_lpss.c')
-rw-r--r--drivers/acpi/acpi_lpss.c50
1 files changed, 47 insertions, 3 deletions
diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c
index 8ea836857691..a7396e18f168 100644
--- a/drivers/acpi/acpi_lpss.c
+++ b/drivers/acpi/acpi_lpss.c
@@ -1064,6 +1064,13 @@ static int acpi_lpss_suspend_noirq(struct device *dev)
int ret;
if (pdata->dev_desc->resume_from_noirq) {
+ /*
+ * The driver's ->suspend_late callback will be invoked by
+ * acpi_lpss_do_suspend_late(), with the assumption that the
+ * driver really wanted to run that code in ->suspend_noirq, but
+ * it could not run after acpi_dev_suspend() and the driver
+ * expected the latter to be called in the "late" phase.
+ */
ret = acpi_lpss_do_suspend_late(dev);
if (ret)
return ret;
@@ -1150,6 +1157,43 @@ static int acpi_lpss_restore_noirq(struct device *dev)
/* This is analogous to what happens in acpi_lpss_resume_noirq(). */
return acpi_lpss_do_restore_early(dev);
}
+
+static int acpi_lpss_do_poweroff_late(struct device *dev)
+{
+ int ret = pm_generic_poweroff_late(dev);
+
+ return ret ? ret : acpi_lpss_suspend(dev, device_may_wakeup(dev));
+}
+
+static int acpi_lpss_poweroff_late(struct device *dev)
+{
+ struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev));
+
+ if (dev_pm_smart_suspend_and_suspended(dev))
+ return 0;
+
+ if (pdata->dev_desc->resume_from_noirq)
+ return 0;
+
+ return acpi_lpss_do_poweroff_late(dev);
+}
+
+static int acpi_lpss_poweroff_noirq(struct device *dev)
+{
+ struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev));
+
+ if (dev_pm_smart_suspend_and_suspended(dev))
+ return 0;
+
+ if (pdata->dev_desc->resume_from_noirq) {
+ /* This is analogous to the acpi_lpss_suspend_noirq() case. */
+ int ret = acpi_lpss_do_poweroff_late(dev);
+ if (ret)
+ return ret;
+ }
+
+ return pm_generic_poweroff_noirq(dev);
+}
#endif /* CONFIG_PM_SLEEP */
static int acpi_lpss_runtime_suspend(struct device *dev)
@@ -1183,9 +1227,9 @@ static struct dev_pm_domain acpi_lpss_pm_domain = {
.resume_noirq = acpi_lpss_resume_noirq,
.resume_early = acpi_lpss_resume_early,
.freeze = acpi_subsys_freeze,
- .poweroff = acpi_subsys_suspend,
- .poweroff_late = acpi_lpss_suspend_late,
- .poweroff_noirq = acpi_lpss_suspend_noirq,
+ .poweroff = acpi_subsys_poweroff,
+ .poweroff_late = acpi_lpss_poweroff_late,
+ .poweroff_noirq = acpi_lpss_poweroff_noirq,
.restore_noirq = acpi_lpss_restore_noirq,
.restore_early = acpi_lpss_restore_early,
#endif