Commit 36cc86e8 authored by Rafael J. Wysocki's avatar Rafael J. Wysocki

Merge branches 'pm-runtime' and 'pm-sleep'

* pm-runtime:
  PM / Runtime: Update runtime_idle() documentation for return value meaning

* pm-sleep:
  PM / sleep: Correct whitespace errors in <linux/pm.h>
  PM: Add missing "freeze" state
  PM / Hibernate: Spelling s/anonymouns/anonymous/
  PM / Runtime: Add missing "it" in comment
  PM / suspend: Remove unnecessary !!
  PCI / PM: Resume runtime-suspended devices later during system suspend
  ACPI / PM: Resume runtime-suspended devices later during system suspend
  PM / sleep: Set pm_generic functions to NULL for !CONFIG_PM_SLEEP
  PM: fix typo in comment
  PM / hibernate: use name_to_dev_t to parse resume
  PM / wakeup: Include appropriate header file in kernel/power/wakelock.c
  PM / sleep: Move prototype declaration to header file kernel/power/power.h
  PM / sleep: Asynchronous threads for suspend_late
  PM / sleep: Asynchronous threads for suspend_noirq
  PM / sleep: Asynchronous threads for resume_early
  PM / sleep: Asynchronous threads for resume_noirq
  PM / sleep: Two flags for async suspend_noirq and suspend_late
...@@ -12,8 +12,9 @@ Contact: Rafael J. Wysocki <rjw@rjwysocki.net> ...@@ -12,8 +12,9 @@ Contact: Rafael J. Wysocki <rjw@rjwysocki.net>
Description: Description:
The /sys/power/state file controls the system power state. The /sys/power/state file controls the system power state.
Reading from this file returns what states are supported, Reading from this file returns what states are supported,
which is hard-coded to 'standby' (Power-On Suspend), 'mem' which is hard-coded to 'freeze' (Low-Power Idle), 'standby'
(Suspend-to-RAM), and 'disk' (Suspend-to-Disk). (Power-On Suspend), 'mem' (Suspend-to-RAM), and 'disk'
(Suspend-to-Disk).
Writing to this file one of these strings causes the system to Writing to this file one of these strings causes the system to
transition into that state. Please see the file transition into that state. Please see the file
......
...@@ -901,14 +901,29 @@ EXPORT_SYMBOL_GPL(acpi_dev_resume_early); ...@@ -901,14 +901,29 @@ EXPORT_SYMBOL_GPL(acpi_dev_resume_early);
int acpi_subsys_prepare(struct device *dev) int acpi_subsys_prepare(struct device *dev)
{ {
/* /*
* Follow PCI and resume devices suspended at run time before running * Devices having power.ignore_children set may still be necessary for
* their system suspend callbacks. * suspending their children in the next phase of device suspend.
*/ */
if (dev->power.ignore_children)
pm_runtime_resume(dev); pm_runtime_resume(dev);
return pm_generic_prepare(dev); return pm_generic_prepare(dev);
} }
EXPORT_SYMBOL_GPL(acpi_subsys_prepare); EXPORT_SYMBOL_GPL(acpi_subsys_prepare);
/**
* acpi_subsys_suspend - Run the device driver's suspend callback.
* @dev: Device to handle.
*
* Follow PCI and resume devices suspended at run time before running their
* system suspend callbacks.
*/
int acpi_subsys_suspend(struct device *dev)
{
pm_runtime_resume(dev);
return pm_generic_suspend(dev);
}
/** /**
* acpi_subsys_suspend_late - Suspend device using ACPI. * acpi_subsys_suspend_late - Suspend device using ACPI.
* @dev: Device to suspend. * @dev: Device to suspend.
...@@ -937,6 +952,23 @@ int acpi_subsys_resume_early(struct device *dev) ...@@ -937,6 +952,23 @@ int acpi_subsys_resume_early(struct device *dev)
return ret ? ret : pm_generic_resume_early(dev); return ret ? ret : pm_generic_resume_early(dev);
} }
EXPORT_SYMBOL_GPL(acpi_subsys_resume_early); EXPORT_SYMBOL_GPL(acpi_subsys_resume_early);
/**
* acpi_subsys_freeze - Run the device driver's freeze callback.
* @dev: Device to handle.
*/
int acpi_subsys_freeze(struct device *dev)
{
/*
* This used to be done in acpi_subsys_prepare() for all devices and
* some drivers may depend on it, so do it here. Ideally, however,
* runtime-suspended devices should not be touched during freeze/thaw
* transitions.
*/
pm_runtime_resume(dev);
return pm_generic_freeze(dev);
}
#endif /* CONFIG_PM_SLEEP */ #endif /* CONFIG_PM_SLEEP */
static struct dev_pm_domain acpi_general_pm_domain = { static struct dev_pm_domain acpi_general_pm_domain = {
...@@ -947,8 +979,11 @@ static struct dev_pm_domain acpi_general_pm_domain = { ...@@ -947,8 +979,11 @@ static struct dev_pm_domain acpi_general_pm_domain = {
#endif #endif
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
.prepare = acpi_subsys_prepare, .prepare = acpi_subsys_prepare,
.suspend = acpi_subsys_suspend,
.suspend_late = acpi_subsys_suspend_late, .suspend_late = acpi_subsys_suspend_late,
.resume_early = acpi_subsys_resume_early, .resume_early = acpi_subsys_resume_early,
.freeze = acpi_subsys_freeze,
.poweroff = acpi_subsys_suspend,
.poweroff_late = acpi_subsys_suspend_late, .poweroff_late = acpi_subsys_suspend_late,
.restore_early = acpi_subsys_resume_early, .restore_early = acpi_subsys_resume_early,
#endif #endif
......
This diff is collapsed.
...@@ -1131,7 +1131,7 @@ EXPORT_SYMBOL_GPL(pm_runtime_barrier); ...@@ -1131,7 +1131,7 @@ EXPORT_SYMBOL_GPL(pm_runtime_barrier);
* @dev: Device to handle. * @dev: Device to handle.
* @check_resume: If set, check if there's a resume request for the device. * @check_resume: If set, check if there's a resume request for the device.
* *
* Increment power.disable_depth for the device and if was zero previously, * Increment power.disable_depth for the device and if it was zero previously,
* cancel all pending runtime PM requests for the device and wait for all * cancel all pending runtime PM requests for the device and wait for all
* operations in progress to complete. The device can be either active or * operations in progress to complete. The device can be either active or
* suspended after its runtime PM has been disabled. * suspended after its runtime PM has been disabled.
......
...@@ -616,14 +616,10 @@ static int pci_pm_prepare(struct device *dev) ...@@ -616,14 +616,10 @@ static int pci_pm_prepare(struct device *dev)
int error = 0; int error = 0;
/* /*
* PCI devices suspended at run time need to be resumed at this * Devices having power.ignore_children set may still be necessary for
* point, because in general it is necessary to reconfigure them for * suspending their children in the next phase of device suspend.
* system suspend. Namely, if the device is supposed to wake up the
* system from the sleep state, we may need to reconfigure it for this
* purpose. In turn, if the device is not supposed to wake up the
* system from the sleep state, we'll have to prevent it from signaling
* wake-up.
*/ */
if (dev->power.ignore_children)
pm_runtime_resume(dev); pm_runtime_resume(dev);
if (drv && drv->pm && drv->pm->prepare) if (drv && drv->pm && drv->pm->prepare)
...@@ -654,6 +650,16 @@ static int pci_pm_suspend(struct device *dev) ...@@ -654,6 +650,16 @@ static int pci_pm_suspend(struct device *dev)
goto Fixup; goto Fixup;
} }
/*
* PCI devices suspended at run time need to be resumed at this point,
* because in general it is necessary to reconfigure them for system
* suspend. Namely, if the device is supposed to wake up the system
* from the sleep state, we may need to reconfigure it for this purpose.
* In turn, if the device is not supposed to wake up the system from the
* sleep state, we'll have to prevent it from signaling wake-up.
*/
pm_runtime_resume(dev);
pci_dev->state_saved = false; pci_dev->state_saved = false;
if (pm->suspend) { if (pm->suspend) {
pci_power_t prev = pci_dev->current_state; pci_power_t prev = pci_dev->current_state;
...@@ -808,6 +814,14 @@ static int pci_pm_freeze(struct device *dev) ...@@ -808,6 +814,14 @@ static int pci_pm_freeze(struct device *dev)
return 0; return 0;
} }
/*
* This used to be done in pci_pm_prepare() for all devices and some
* drivers may depend on it, so do it here. Ideally, runtime-suspended
* devices should not be touched during freeze/thaw transitions,
* however.
*/
pm_runtime_resume(dev);
pci_dev->state_saved = false; pci_dev->state_saved = false;
if (pm->freeze) { if (pm->freeze) {
int error; int error;
...@@ -915,6 +929,9 @@ static int pci_pm_poweroff(struct device *dev) ...@@ -915,6 +929,9 @@ static int pci_pm_poweroff(struct device *dev)
goto Fixup; goto Fixup;
} }
/* The reason to do that is the same as in pci_pm_suspend(). */
pm_runtime_resume(dev);
pci_dev->state_saved = false; pci_dev->state_saved = false;
if (pm->poweroff) { if (pm->poweroff) {
int error; int error;
......
...@@ -264,9 +264,9 @@ typedef struct pm_message { ...@@ -264,9 +264,9 @@ typedef struct pm_message {
* registers, so that it is fully operational. * registers, so that it is fully operational.
* *
* @runtime_idle: Device appears to be inactive and it might be put into a * @runtime_idle: Device appears to be inactive and it might be put into a
* low-power state if all of the necessary conditions are satisfied. Check * low-power state if all of the necessary conditions are satisfied.
* these conditions and handle the device as appropriate, possibly queueing * Check these conditions, and return 0 if it's appropriate to let the PM
* a suspend request for it. The return value is ignored by the PM core. * core queue a suspend request for the device.
* *
* Refer to Documentation/power/runtime_pm.txt for more information about the * Refer to Documentation/power/runtime_pm.txt for more information about the
* role of the above callbacks in device runtime power management. * role of the above callbacks in device runtime power management.
...@@ -352,7 +352,7 @@ const struct dev_pm_ops name = { \ ...@@ -352,7 +352,7 @@ const struct dev_pm_ops name = { \
/* /*
* Use this for defining a set of PM operations to be used in all situations * Use this for defining a set of PM operations to be used in all situations
* (sustem suspend, hibernation or runtime PM). * (system suspend, hibernation or runtime PM).
* NOTE: In general, system suspend callbacks, .suspend() and .resume(), should * NOTE: In general, system suspend callbacks, .suspend() and .resume(), should
* be different from the corresponding runtime PM callbacks, .runtime_suspend(), * be different from the corresponding runtime PM callbacks, .runtime_suspend(),
* and .runtime_resume(), because .runtime_suspend() always works on an already * and .runtime_resume(), because .runtime_suspend() always works on an already
...@@ -542,6 +542,8 @@ struct dev_pm_info { ...@@ -542,6 +542,8 @@ struct dev_pm_info {
unsigned int async_suspend:1; unsigned int async_suspend:1;
bool is_prepared:1; /* Owned by the PM core */ bool is_prepared:1; /* Owned by the PM core */
bool is_suspended:1; /* Ditto */ bool is_suspended:1; /* Ditto */
bool is_noirq_suspended:1;
bool is_late_suspended:1;
bool ignore_children:1; bool ignore_children:1;
bool early_init:1; /* Owned by the PM core */ bool early_init:1; /* Owned by the PM core */
spinlock_t lock; spinlock_t lock;
...@@ -719,11 +721,23 @@ static inline void dpm_for_each_dev(void *data, void (*fn)(struct device *, void ...@@ -719,11 +721,23 @@ static inline void dpm_for_each_dev(void *data, void (*fn)(struct device *, void
} }
#define pm_generic_prepare NULL #define pm_generic_prepare NULL
#define pm_generic_suspend_late NULL
#define pm_generic_suspend_noirq NULL
#define pm_generic_suspend NULL #define pm_generic_suspend NULL
#define pm_generic_resume_early NULL
#define pm_generic_resume_noirq NULL
#define pm_generic_resume NULL #define pm_generic_resume NULL
#define pm_generic_freeze_noirq NULL
#define pm_generic_freeze_late NULL
#define pm_generic_freeze NULL #define pm_generic_freeze NULL
#define pm_generic_thaw_noirq NULL
#define pm_generic_thaw_early NULL
#define pm_generic_thaw NULL #define pm_generic_thaw NULL
#define pm_generic_restore_noirq NULL
#define pm_generic_restore_early NULL
#define pm_generic_restore NULL #define pm_generic_restore NULL
#define pm_generic_poweroff_noirq NULL
#define pm_generic_poweroff_late NULL
#define pm_generic_poweroff NULL #define pm_generic_poweroff NULL
#define pm_generic_complete NULL #define pm_generic_complete NULL
#endif /* !CONFIG_PM_SLEEP */ #endif /* !CONFIG_PM_SLEEP */
......
...@@ -973,16 +973,20 @@ static ssize_t resume_show(struct kobject *kobj, struct kobj_attribute *attr, ...@@ -973,16 +973,20 @@ static ssize_t resume_show(struct kobject *kobj, struct kobj_attribute *attr,
static ssize_t resume_store(struct kobject *kobj, struct kobj_attribute *attr, static ssize_t resume_store(struct kobject *kobj, struct kobj_attribute *attr,
const char *buf, size_t n) const char *buf, size_t n)
{ {
unsigned int maj, min;
dev_t res; dev_t res;
int ret = -EINVAL; int len = n;
char *name;
if (sscanf(buf, "%u:%u", &maj, &min) != 2)
goto out; if (len && buf[len-1] == '\n')
len--;
res = MKDEV(maj,min); name = kstrndup(buf, len, GFP_KERNEL);
if (maj != MAJOR(res) || min != MINOR(res)) if (!name)
goto out; return -ENOMEM;
res = name_to_dev_t(name);
kfree(name);
if (!res)
return -EINVAL;
lock_system_sleep(); lock_system_sleep();
swsusp_resume_device = res; swsusp_resume_device = res;
...@@ -990,9 +994,7 @@ static ssize_t resume_store(struct kobject *kobj, struct kobj_attribute *attr, ...@@ -990,9 +994,7 @@ static ssize_t resume_store(struct kobject *kobj, struct kobj_attribute *attr,
printk(KERN_INFO "PM: Starting manual resume from disk\n"); printk(KERN_INFO "PM: Starting manual resume from disk\n");
noresume = 0; noresume = 0;
software_resume(); software_resume();
ret = n; return n;
out:
return ret;
} }
power_attr(resume); power_attr(resume);
......
...@@ -282,8 +282,8 @@ struct kobject *power_kobj; ...@@ -282,8 +282,8 @@ struct kobject *power_kobj;
* state - control system power state. * state - control system power state.
* *
* show() returns what states are supported, which is hard-coded to * show() returns what states are supported, which is hard-coded to
* 'standby' (Power-On Suspend), 'mem' (Suspend-to-RAM), and * 'freeze' (Low-Power Idle), 'standby' (Power-On Suspend),
* 'disk' (Suspend-to-Disk). * 'mem' (Suspend-to-RAM), and 'disk' (Suspend-to-Disk).
* *
* store() accepts one of those strings, translates it into the * store() accepts one of those strings, translates it into the
* proper enumerated value, and initiates a suspend transition. * proper enumerated value, and initiates a suspend transition.
......
...@@ -49,6 +49,8 @@ static inline char *check_image_kernel(struct swsusp_info *info) ...@@ -49,6 +49,8 @@ static inline char *check_image_kernel(struct swsusp_info *info)
*/ */
#define SPARE_PAGES ((1024 * 1024) >> PAGE_SHIFT) #define SPARE_PAGES ((1024 * 1024) >> PAGE_SHIFT)
asmlinkage int swsusp_save(void);
/* kernel/power/hibernate.c */ /* kernel/power/hibernate.c */
extern bool freezer_test_done; extern bool freezer_test_done;
......
...@@ -1268,7 +1268,7 @@ static void free_unnecessary_pages(void) ...@@ -1268,7 +1268,7 @@ static void free_unnecessary_pages(void)
* [number of saveable pages] - [number of pages that can be freed in theory] * [number of saveable pages] - [number of pages that can be freed in theory]
* *
* where the second term is the sum of (1) reclaimable slab pages, (2) active * where the second term is the sum of (1) reclaimable slab pages, (2) active
* and (3) inactive anonymouns pages, (4) active and (5) inactive file pages, * and (3) inactive anonymous pages, (4) active and (5) inactive file pages,
* minus mapped file pages. * minus mapped file pages.
*/ */
static unsigned long minimum_image_size(unsigned long saveable) static unsigned long minimum_image_size(unsigned long saveable)
......
...@@ -39,7 +39,7 @@ static const struct platform_suspend_ops *suspend_ops; ...@@ -39,7 +39,7 @@ static const struct platform_suspend_ops *suspend_ops;
static bool need_suspend_ops(suspend_state_t state) static bool need_suspend_ops(suspend_state_t state)
{ {
return !!(state > PM_SUSPEND_FREEZE); return state > PM_SUSPEND_FREEZE;
} }
static DECLARE_WAIT_QUEUE_HEAD(suspend_freeze_wait_head); static DECLARE_WAIT_QUEUE_HEAD(suspend_freeze_wait_head);
......
...@@ -18,6 +18,8 @@ ...@@ -18,6 +18,8 @@
#include <linux/rbtree.h> #include <linux/rbtree.h>
#include <linux/slab.h> #include <linux/slab.h>
#include "power.h"
static DEFINE_MUTEX(wakelocks_lock); static DEFINE_MUTEX(wakelocks_lock);
struct wakelock { struct wakelock {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment