mirror of
https://github.com/torvalds/linux.git
synced 2024-11-24 05:02:12 +00:00
Merge branch 'pm-sleep'
* pm-sleep: PM / hibernate: fix a comment typo input: i8042: Avoid resetting controller on system suspend/resume PM / PCI / ACPI: Kick devices that might have been reset by firmware PM / sleep: Add flags to indicate platform firmware involvement PM / sleep: Drop pm_request_idle() from pm_generic_complete() PCI / PM: Avoid resuming more devices during system suspend PM / wakeup: wakeup_source_create: use kstrdup_const PM / sleep: Report interrupt that caused system wakeup
This commit is contained in:
commit
9bb4064ca3
@ -256,3 +256,15 @@ Description:
|
||||
Writing a "1" enables this printing while writing a "0"
|
||||
disables it. The default value is "0". Reading from this file
|
||||
will display the current value.
|
||||
|
||||
What: /sys/power/pm_wakeup_irq
|
||||
Date: April 2015
|
||||
Contact: Alexandra Yates <alexandra.yates@linux.intel.org>
|
||||
Description:
|
||||
The /sys/power/pm_wakeup_irq file reports to user space the IRQ
|
||||
number of the first wakeup interrupt (that is, the first
|
||||
interrupt from an IRQ line armed for system wakeup) seen by the
|
||||
kernel during the most recent system suspend/resume cycle.
|
||||
|
||||
This output is useful for system wakeup diagnostics of spurious
|
||||
wakeup interrupts.
|
||||
|
@ -664,7 +664,7 @@ static struct dev_pm_domain acpi_lpss_pm_domain = {
|
||||
#ifdef CONFIG_PM
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
.prepare = acpi_subsys_prepare,
|
||||
.complete = acpi_subsys_complete,
|
||||
.complete = pm_complete_with_resume_check,
|
||||
.suspend = acpi_subsys_suspend,
|
||||
.suspend_late = acpi_lpss_suspend_late,
|
||||
.resume_early = acpi_lpss_resume_early,
|
||||
|
@ -962,23 +962,6 @@ int acpi_subsys_prepare(struct device *dev)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_subsys_prepare);
|
||||
|
||||
/**
|
||||
* acpi_subsys_complete - Finalize device's resume during system resume.
|
||||
* @dev: Device to handle.
|
||||
*/
|
||||
void acpi_subsys_complete(struct device *dev)
|
||||
{
|
||||
pm_generic_complete(dev);
|
||||
/*
|
||||
* If the device had been runtime-suspended before the system went into
|
||||
* the sleep state it is going out of and it has never been resumed till
|
||||
* now, resume it in case the firmware powered it up.
|
||||
*/
|
||||
if (dev->power.direct_complete)
|
||||
pm_request_resume(dev);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_subsys_complete);
|
||||
|
||||
/**
|
||||
* acpi_subsys_suspend - Run the device driver's suspend callback.
|
||||
* @dev: Device to handle.
|
||||
@ -1047,7 +1030,7 @@ static struct dev_pm_domain acpi_general_pm_domain = {
|
||||
.runtime_resume = acpi_subsys_runtime_resume,
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
.prepare = acpi_subsys_prepare,
|
||||
.complete = acpi_subsys_complete,
|
||||
.complete = pm_complete_with_resume_check,
|
||||
.suspend = acpi_subsys_suspend,
|
||||
.suspend_late = acpi_subsys_suspend_late,
|
||||
.resume_early = acpi_subsys_resume_early,
|
||||
|
@ -487,6 +487,8 @@ static int acpi_suspend_begin(suspend_state_t pm_state)
|
||||
pr_err("ACPI does not support sleep state S%u\n", acpi_state);
|
||||
return -ENOSYS;
|
||||
}
|
||||
if (acpi_state > ACPI_STATE_S1)
|
||||
pm_set_suspend_via_firmware();
|
||||
|
||||
acpi_pm_start(acpi_state);
|
||||
return 0;
|
||||
@ -522,6 +524,7 @@ static int acpi_suspend_enter(suspend_state_t pm_state)
|
||||
if (error)
|
||||
return error;
|
||||
pr_info(PREFIX "Low-level resume complete\n");
|
||||
pm_set_resume_via_firmware();
|
||||
break;
|
||||
}
|
||||
trace_suspend_resume(TPS("acpi_suspend"), acpi_state, false);
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <linux/pm.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/suspend.h>
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
/**
|
||||
@ -296,11 +297,27 @@ void pm_generic_complete(struct device *dev)
|
||||
|
||||
if (drv && drv->pm && drv->pm->complete)
|
||||
drv->pm->complete(dev);
|
||||
|
||||
/*
|
||||
* Let runtime PM try to suspend devices that haven't been in use before
|
||||
* going into the system-wide sleep state we're resuming from.
|
||||
*/
|
||||
pm_request_idle(dev);
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_complete_with_resume_check - Complete a device power transition.
|
||||
* @dev: Device to handle.
|
||||
*
|
||||
* Complete a device power transition during a system-wide power transition and
|
||||
* optionally schedule a runtime resume of the device if the system resume in
|
||||
* progress has been initated by the platform firmware and the device had its
|
||||
* power.direct_complete flag set.
|
||||
*/
|
||||
void pm_complete_with_resume_check(struct device *dev)
|
||||
{
|
||||
pm_generic_complete(dev);
|
||||
/*
|
||||
* If the device had been runtime-suspended before the system went into
|
||||
* the sleep state it is going out of and it has never been resumed till
|
||||
* now, resume it in case the firmware powered it up.
|
||||
*/
|
||||
if (dev->power.direct_complete && pm_resume_via_firmware())
|
||||
pm_request_resume(dev);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pm_complete_with_resume_check);
|
||||
#endif /* CONFIG_PM_SLEEP */
|
||||
|
@ -25,6 +25,9 @@
|
||||
*/
|
||||
bool events_check_enabled __read_mostly;
|
||||
|
||||
/* First wakeup IRQ seen by the kernel in the last cycle. */
|
||||
unsigned int pm_wakeup_irq __read_mostly;
|
||||
|
||||
/* If set and the system is suspending, terminate the suspend. */
|
||||
static bool pm_abort_suspend __read_mostly;
|
||||
|
||||
@ -91,7 +94,7 @@ struct wakeup_source *wakeup_source_create(const char *name)
|
||||
if (!ws)
|
||||
return NULL;
|
||||
|
||||
wakeup_source_prepare(ws, name ? kstrdup(name, GFP_KERNEL) : NULL);
|
||||
wakeup_source_prepare(ws, name ? kstrdup_const(name, GFP_KERNEL) : NULL);
|
||||
return ws;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(wakeup_source_create);
|
||||
@ -154,7 +157,7 @@ void wakeup_source_destroy(struct wakeup_source *ws)
|
||||
|
||||
wakeup_source_drop(ws);
|
||||
wakeup_source_record(ws);
|
||||
kfree(ws->name);
|
||||
kfree_const(ws->name);
|
||||
kfree(ws);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(wakeup_source_destroy);
|
||||
@ -868,6 +871,15 @@ EXPORT_SYMBOL_GPL(pm_system_wakeup);
|
||||
void pm_wakeup_clear(void)
|
||||
{
|
||||
pm_abort_suspend = false;
|
||||
pm_wakeup_irq = 0;
|
||||
}
|
||||
|
||||
void pm_system_irq_wakeup(unsigned int irq_number)
|
||||
{
|
||||
if (pm_wakeup_irq == 0) {
|
||||
pm_wakeup_irq = irq_number;
|
||||
pm_system_wakeup();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/i8042.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/suspend.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
|
||||
@ -1170,7 +1171,8 @@ static int i8042_pm_suspend(struct device *dev)
|
||||
{
|
||||
int i;
|
||||
|
||||
i8042_controller_reset(true);
|
||||
if (pm_suspend_via_firmware())
|
||||
i8042_controller_reset(true);
|
||||
|
||||
/* Set up serio interrupts for system wakeup. */
|
||||
for (i = 0; i < I8042_NUM_PORTS; i++) {
|
||||
@ -1183,8 +1185,17 @@ static int i8042_pm_suspend(struct device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int i8042_pm_resume_noirq(struct device *dev)
|
||||
{
|
||||
if (!pm_resume_via_firmware())
|
||||
i8042_interrupt(0, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int i8042_pm_resume(struct device *dev)
|
||||
{
|
||||
bool force_reset;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < I8042_NUM_PORTS; i++) {
|
||||
@ -1195,11 +1206,21 @@ static int i8042_pm_resume(struct device *dev)
|
||||
}
|
||||
|
||||
/*
|
||||
* On resume from S2R we always try to reset the controller
|
||||
* to bring it in a sane state. (In case of S2D we expect
|
||||
* BIOS to reset the controller for us.)
|
||||
* If platform firmware was not going to be involved in suspend, we did
|
||||
* not restore the controller state to whatever it had been at boot
|
||||
* time, so we do not need to do anything.
|
||||
*/
|
||||
return i8042_controller_resume(true);
|
||||
if (!pm_suspend_via_firmware())
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* We only need to reset the controller if we are resuming after handing
|
||||
* off control to the platform firmware, otherwise we can simply restore
|
||||
* the mode.
|
||||
*/
|
||||
force_reset = pm_resume_via_firmware();
|
||||
|
||||
return i8042_controller_resume(force_reset);
|
||||
}
|
||||
|
||||
static int i8042_pm_thaw(struct device *dev)
|
||||
@ -1223,6 +1244,7 @@ static int i8042_pm_restore(struct device *dev)
|
||||
|
||||
static const struct dev_pm_ops i8042_pm_ops = {
|
||||
.suspend = i8042_pm_suspend,
|
||||
.resume_noirq = i8042_pm_resume_noirq,
|
||||
.resume = i8042_pm_resume,
|
||||
.thaw = i8042_pm_thaw,
|
||||
.poweroff = i8042_pm_reset,
|
||||
|
@ -684,10 +684,16 @@ static int pci_pm_prepare(struct device *dev)
|
||||
return pci_dev_keep_suspended(to_pci_dev(dev));
|
||||
}
|
||||
|
||||
static void pci_pm_complete(struct device *dev)
|
||||
{
|
||||
pci_dev_complete_resume(to_pci_dev(dev));
|
||||
pm_complete_with_resume_check(dev);
|
||||
}
|
||||
|
||||
#else /* !CONFIG_PM_SLEEP */
|
||||
|
||||
#define pci_pm_prepare NULL
|
||||
#define pci_pm_complete NULL
|
||||
|
||||
#endif /* !CONFIG_PM_SLEEP */
|
||||
|
||||
@ -1218,6 +1224,7 @@ static int pci_pm_runtime_idle(struct device *dev)
|
||||
|
||||
static const struct dev_pm_ops pci_dev_pm_ops = {
|
||||
.prepare = pci_pm_prepare,
|
||||
.complete = pci_pm_complete,
|
||||
.suspend = pci_pm_suspend,
|
||||
.resume = pci_pm_resume,
|
||||
.freeze = pci_pm_freeze,
|
||||
|
@ -1710,15 +1710,7 @@ static void pci_pme_list_scan(struct work_struct *work)
|
||||
mutex_unlock(&pci_pme_list_mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* pci_pme_active - enable or disable PCI device's PME# function
|
||||
* @dev: PCI device to handle.
|
||||
* @enable: 'true' to enable PME# generation; 'false' to disable it.
|
||||
*
|
||||
* The caller must verify that the device is capable of generating PME# before
|
||||
* calling this function with @enable equal to 'true'.
|
||||
*/
|
||||
void pci_pme_active(struct pci_dev *dev, bool enable)
|
||||
static void __pci_pme_active(struct pci_dev *dev, bool enable)
|
||||
{
|
||||
u16 pmcsr;
|
||||
|
||||
@ -1732,6 +1724,19 @@ void pci_pme_active(struct pci_dev *dev, bool enable)
|
||||
pmcsr &= ~PCI_PM_CTRL_PME_ENABLE;
|
||||
|
||||
pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, pmcsr);
|
||||
}
|
||||
|
||||
/**
|
||||
* pci_pme_active - enable or disable PCI device's PME# function
|
||||
* @dev: PCI device to handle.
|
||||
* @enable: 'true' to enable PME# generation; 'false' to disable it.
|
||||
*
|
||||
* The caller must verify that the device is capable of generating PME# before
|
||||
* calling this function with @enable equal to 'true'.
|
||||
*/
|
||||
void pci_pme_active(struct pci_dev *dev, bool enable)
|
||||
{
|
||||
__pci_pme_active(dev, enable);
|
||||
|
||||
/*
|
||||
* PCI (as opposed to PCIe) PME requires that the device have
|
||||
@ -2032,17 +2037,60 @@ EXPORT_SYMBOL_GPL(pci_dev_run_wake);
|
||||
* reconfigured due to wakeup settings difference between system and runtime
|
||||
* suspend and the current power state of it is suitable for the upcoming
|
||||
* (system) transition.
|
||||
*
|
||||
* If the device is not configured for system wakeup, disable PME for it before
|
||||
* returning 'true' to prevent it from waking up the system unnecessarily.
|
||||
*/
|
||||
bool pci_dev_keep_suspended(struct pci_dev *pci_dev)
|
||||
{
|
||||
struct device *dev = &pci_dev->dev;
|
||||
|
||||
if (!pm_runtime_suspended(dev)
|
||||
|| (device_can_wakeup(dev) && !device_may_wakeup(dev))
|
||||
|| pci_target_state(pci_dev) != pci_dev->current_state
|
||||
|| platform_pci_need_resume(pci_dev))
|
||||
return false;
|
||||
|
||||
return pci_target_state(pci_dev) == pci_dev->current_state;
|
||||
/*
|
||||
* At this point the device is good to go unless it's been configured
|
||||
* to generate PME at the runtime suspend time, but it is not supposed
|
||||
* to wake up the system. In that case, simply disable PME for it
|
||||
* (it will have to be re-enabled on exit from system resume).
|
||||
*
|
||||
* If the device's power state is D3cold and the platform check above
|
||||
* hasn't triggered, the device's configuration is suitable and we don't
|
||||
* need to manipulate it at all.
|
||||
*/
|
||||
spin_lock_irq(&dev->power.lock);
|
||||
|
||||
if (pm_runtime_suspended(dev) && pci_dev->current_state < PCI_D3cold &&
|
||||
!device_may_wakeup(dev))
|
||||
__pci_pme_active(pci_dev, false);
|
||||
|
||||
spin_unlock_irq(&dev->power.lock);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* pci_dev_complete_resume - Finalize resume from system sleep for a device.
|
||||
* @pci_dev: Device to handle.
|
||||
*
|
||||
* If the device is runtime suspended and wakeup-capable, enable PME for it as
|
||||
* it might have been disabled during the prepare phase of system suspend if
|
||||
* the device was not configured for system wakeup.
|
||||
*/
|
||||
void pci_dev_complete_resume(struct pci_dev *pci_dev)
|
||||
{
|
||||
struct device *dev = &pci_dev->dev;
|
||||
|
||||
if (!pci_dev_run_wake(pci_dev))
|
||||
return;
|
||||
|
||||
spin_lock_irq(&dev->power.lock);
|
||||
|
||||
if (pm_runtime_suspended(dev) && pci_dev->current_state < PCI_D3cold)
|
||||
__pci_pme_active(pci_dev, true);
|
||||
|
||||
spin_unlock_irq(&dev->power.lock);
|
||||
}
|
||||
|
||||
void pci_config_pm_runtime_get(struct pci_dev *pdev)
|
||||
|
@ -75,6 +75,7 @@ void pci_disable_enabled_device(struct pci_dev *dev);
|
||||
int pci_finish_runtime_suspend(struct pci_dev *dev);
|
||||
int __pci_pme_wakeup(struct pci_dev *dev, void *ign);
|
||||
bool pci_dev_keep_suspended(struct pci_dev *dev);
|
||||
void pci_dev_complete_resume(struct pci_dev *pci_dev);
|
||||
void pci_config_pm_runtime_get(struct pci_dev *dev);
|
||||
void pci_config_pm_runtime_put(struct pci_dev *dev);
|
||||
void pci_pm_init(struct pci_dev *dev);
|
||||
|
@ -732,6 +732,7 @@ extern int pm_generic_poweroff_noirq(struct device *dev);
|
||||
extern int pm_generic_poweroff_late(struct device *dev);
|
||||
extern int pm_generic_poweroff(struct device *dev);
|
||||
extern void pm_generic_complete(struct device *dev);
|
||||
extern void pm_complete_with_resume_check(struct device *dev);
|
||||
|
||||
#else /* !CONFIG_PM_SLEEP */
|
||||
|
||||
|
@ -202,6 +202,36 @@ struct platform_freeze_ops {
|
||||
extern void suspend_set_ops(const struct platform_suspend_ops *ops);
|
||||
extern int suspend_valid_only_mem(suspend_state_t state);
|
||||
|
||||
extern unsigned int pm_suspend_global_flags;
|
||||
|
||||
#define PM_SUSPEND_FLAG_FW_SUSPEND (1 << 0)
|
||||
#define PM_SUSPEND_FLAG_FW_RESUME (1 << 1)
|
||||
|
||||
static inline void pm_suspend_clear_flags(void)
|
||||
{
|
||||
pm_suspend_global_flags = 0;
|
||||
}
|
||||
|
||||
static inline void pm_set_suspend_via_firmware(void)
|
||||
{
|
||||
pm_suspend_global_flags |= PM_SUSPEND_FLAG_FW_SUSPEND;
|
||||
}
|
||||
|
||||
static inline void pm_set_resume_via_firmware(void)
|
||||
{
|
||||
pm_suspend_global_flags |= PM_SUSPEND_FLAG_FW_RESUME;
|
||||
}
|
||||
|
||||
static inline bool pm_suspend_via_firmware(void)
|
||||
{
|
||||
return !!(pm_suspend_global_flags & PM_SUSPEND_FLAG_FW_SUSPEND);
|
||||
}
|
||||
|
||||
static inline bool pm_resume_via_firmware(void)
|
||||
{
|
||||
return !!(pm_suspend_global_flags & PM_SUSPEND_FLAG_FW_RESUME);
|
||||
}
|
||||
|
||||
/* Suspend-to-idle state machnine. */
|
||||
enum freeze_state {
|
||||
FREEZE_STATE_NONE, /* Not suspended/suspending. */
|
||||
@ -241,6 +271,12 @@ extern int pm_suspend(suspend_state_t state);
|
||||
#else /* !CONFIG_SUSPEND */
|
||||
#define suspend_valid_only_mem NULL
|
||||
|
||||
static inline void pm_suspend_clear_flags(void) {}
|
||||
static inline void pm_set_suspend_via_firmware(void) {}
|
||||
static inline void pm_set_resume_via_firmware(void) {}
|
||||
static inline bool pm_suspend_via_firmware(void) { return false; }
|
||||
static inline bool pm_resume_via_firmware(void) { return false; }
|
||||
|
||||
static inline void suspend_set_ops(const struct platform_suspend_ops *ops) {}
|
||||
static inline int pm_suspend(suspend_state_t state) { return -ENOSYS; }
|
||||
static inline bool idle_should_freeze(void) { return false; }
|
||||
@ -387,10 +423,12 @@ extern int unregister_pm_notifier(struct notifier_block *nb);
|
||||
|
||||
/* drivers/base/power/wakeup.c */
|
||||
extern bool events_check_enabled;
|
||||
extern unsigned int pm_wakeup_irq;
|
||||
|
||||
extern bool pm_wakeup_pending(void);
|
||||
extern void pm_system_wakeup(void);
|
||||
extern void pm_wakeup_clear(void);
|
||||
extern void pm_system_irq_wakeup(unsigned int irq_number);
|
||||
extern bool pm_get_wakeup_count(unsigned int *count, bool block);
|
||||
extern bool pm_save_wakeup_count(unsigned int count);
|
||||
extern void pm_wakep_autosleep_enabled(bool set);
|
||||
@ -440,6 +478,7 @@ static inline int unregister_pm_notifier(struct notifier_block *nb)
|
||||
static inline bool pm_wakeup_pending(void) { return false; }
|
||||
static inline void pm_system_wakeup(void) {}
|
||||
static inline void pm_wakeup_clear(void) {}
|
||||
static inline void pm_system_irq_wakeup(unsigned int irq_number) {}
|
||||
|
||||
static inline void lock_system_sleep(void) {}
|
||||
static inline void unlock_system_sleep(void) {}
|
||||
|
@ -21,7 +21,7 @@ bool irq_pm_check_wakeup(struct irq_desc *desc)
|
||||
desc->istate |= IRQS_SUSPENDED | IRQS_PENDING;
|
||||
desc->depth++;
|
||||
irq_disable(desc);
|
||||
pm_system_wakeup();
|
||||
pm_system_irq_wakeup(irq_desc_get_irq(desc));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -733,7 +733,7 @@ int hibernate(void)
|
||||
* contents of memory is restored from the saved image.
|
||||
*
|
||||
* If this is successful, control reappears in the restored target kernel in
|
||||
* hibernation_snaphot() which returns to hibernate(). Otherwise, the routine
|
||||
* hibernation_snapshot() which returns to hibernate(). Otherwise, the routine
|
||||
* attempts to recover gracefully and make the kernel return to the normal mode
|
||||
* of operation.
|
||||
*/
|
||||
|
@ -272,6 +272,22 @@ static inline void pm_print_times_init(void)
|
||||
{
|
||||
pm_print_times_enabled = !!initcall_debug;
|
||||
}
|
||||
|
||||
static ssize_t pm_wakeup_irq_show(struct kobject *kobj,
|
||||
struct kobj_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
return pm_wakeup_irq ? sprintf(buf, "%u\n", pm_wakeup_irq) : -ENODATA;
|
||||
}
|
||||
|
||||
static ssize_t pm_wakeup_irq_store(struct kobject *kobj,
|
||||
struct kobj_attribute *attr,
|
||||
const char *buf, size_t n)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
power_attr(pm_wakeup_irq);
|
||||
|
||||
#else /* !CONFIG_PM_SLEEP_DEBUG */
|
||||
static inline void pm_print_times_init(void) {}
|
||||
#endif /* CONFIG_PM_SLEEP_DEBUG */
|
||||
@ -604,6 +620,7 @@ static struct attribute * g[] = {
|
||||
#endif
|
||||
#ifdef CONFIG_PM_SLEEP_DEBUG
|
||||
&pm_print_times_attr.attr,
|
||||
&pm_wakeup_irq_attr.attr,
|
||||
#endif
|
||||
#endif
|
||||
#ifdef CONFIG_FREEZER
|
||||
|
@ -35,6 +35,9 @@
|
||||
const char *pm_labels[] = { "mem", "standby", "freeze", NULL };
|
||||
const char *pm_states[PM_SUSPEND_MAX];
|
||||
|
||||
unsigned int pm_suspend_global_flags;
|
||||
EXPORT_SYMBOL_GPL(pm_suspend_global_flags);
|
||||
|
||||
static const struct platform_suspend_ops *suspend_ops;
|
||||
static const struct platform_freeze_ops *freeze_ops;
|
||||
static DECLARE_WAIT_QUEUE_HEAD(suspend_freeze_wait_head);
|
||||
@ -493,6 +496,7 @@ static int enter_state(suspend_state_t state)
|
||||
#endif
|
||||
|
||||
pr_debug("PM: Preparing system for sleep (%s)\n", pm_states[state]);
|
||||
pm_suspend_clear_flags();
|
||||
error = suspend_prepare(state);
|
||||
if (error)
|
||||
goto Unlock;
|
||||
|
Loading…
Reference in New Issue
Block a user