Merge branch 'pm-sleep'
* pm-sleep: PM: sleep: Drop dev_pm_skip_next_resume_phases() ACPI: PM: Drop unused function and function header ACPI: PM: Introduce "poweroff" callbacks for ACPI PM domain and LPSS ACPI: PM: Simplify and fix PM domain hibernation callbacks PCI: PM: Simplify bus-level hibernation callbacks PM: ACPI/PCI: Resume all devices during hibernation kernel: power: swap: use kzalloc() instead of kmalloc() followed by memset() PM: sleep: Update struct wakeup_source documentation drivers: base: power: remove wakeup_sources_stats_dentry variable PM: suspend: Rename pm_suspend_via_s2idle() PM: sleep: Show how long dpm_suspend_start() and dpm_suspend_end() take PM: hibernate: powerpc: Expose pfn_is_nosave() prototype
这个提交包含在:
@@ -1061,6 +1061,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;
|
||||
@@ -1091,16 +1098,99 @@ static int acpi_lpss_resume_noirq(struct device *dev)
|
||||
struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev));
|
||||
int ret;
|
||||
|
||||
ret = acpi_subsys_resume_noirq(dev);
|
||||
/* Follow acpi_subsys_resume_noirq(). */
|
||||
if (dev_pm_may_skip_resume(dev))
|
||||
return 0;
|
||||
|
||||
if (dev_pm_smart_suspend_and_suspended(dev))
|
||||
pm_runtime_set_active(dev);
|
||||
|
||||
ret = pm_generic_resume_noirq(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!dev_pm_may_skip_resume(dev) && pdata->dev_desc->resume_from_noirq)
|
||||
ret = acpi_lpss_do_resume_early(dev);
|
||||
if (!pdata->dev_desc->resume_from_noirq)
|
||||
return 0;
|
||||
|
||||
return ret;
|
||||
/*
|
||||
* The driver's ->resume_early callback will be invoked by
|
||||
* acpi_lpss_do_resume_early(), with the assumption that the driver
|
||||
* really wanted to run that code in ->resume_noirq, but it could not
|
||||
* run before acpi_dev_resume() and the driver expected the latter to be
|
||||
* called in the "early" phase.
|
||||
*/
|
||||
return acpi_lpss_do_resume_early(dev);
|
||||
}
|
||||
|
||||
static int acpi_lpss_do_restore_early(struct device *dev)
|
||||
{
|
||||
int ret = acpi_lpss_resume(dev);
|
||||
|
||||
return ret ? ret : pm_generic_restore_early(dev);
|
||||
}
|
||||
|
||||
static int acpi_lpss_restore_early(struct device *dev)
|
||||
{
|
||||
struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev));
|
||||
|
||||
if (pdata->dev_desc->resume_from_noirq)
|
||||
return 0;
|
||||
|
||||
return acpi_lpss_do_restore_early(dev);
|
||||
}
|
||||
|
||||
static int acpi_lpss_restore_noirq(struct device *dev)
|
||||
{
|
||||
struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev));
|
||||
int ret;
|
||||
|
||||
ret = pm_generic_restore_noirq(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!pdata->dev_desc->resume_from_noirq)
|
||||
return 0;
|
||||
|
||||
/* 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)
|
||||
@@ -1134,14 +1224,11 @@ 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,
|
||||
.freeze_late = acpi_subsys_freeze_late,
|
||||
.freeze_noirq = acpi_subsys_freeze_noirq,
|
||||
.thaw_noirq = acpi_subsys_thaw_noirq,
|
||||
.poweroff = acpi_subsys_suspend,
|
||||
.poweroff_late = acpi_lpss_suspend_late,
|
||||
.poweroff_noirq = acpi_lpss_suspend_noirq,
|
||||
.restore_noirq = acpi_lpss_resume_noirq,
|
||||
.restore_early = acpi_lpss_resume_early,
|
||||
.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
|
||||
.runtime_suspend = acpi_lpss_runtime_suspend,
|
||||
.runtime_resume = acpi_lpss_runtime_resume,
|
||||
|
在新工单中引用
屏蔽一个用户