2005-04-17 06:20:36 +08:00
|
|
|
/*
|
|
|
|
* kernel/power/main.c - PM subsystem core functionality.
|
|
|
|
*
|
|
|
|
* Copyright (c) 2003 Patrick Mochel
|
|
|
|
* Copyright (c) 2003 Open Source Development Lab
|
2011-11-19 21:39:01 +08:00
|
|
|
*
|
2005-04-17 06:20:36 +08:00
|
|
|
* This file is released under the GPLv2
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2011-05-27 04:00:52 +08:00
|
|
|
#include <linux/export.h>
|
2005-04-17 06:20:36 +08:00
|
|
|
#include <linux/kobject.h>
|
|
|
|
#include <linux/string.h>
|
2006-09-26 14:32:58 +08:00
|
|
|
#include <linux/resume-trace.h>
|
2009-08-19 05:38:32 +08:00
|
|
|
#include <linux/workqueue.h>
|
PM / Suspend: Add statistics debugfs file for suspend to RAM
Record S3 failure time about each reason and the latest two failed
devices' names in S3 progress.
We can check it through 'suspend_stats' entry in debugfs.
The motivation of the patch:
We are enabling power features on Medfield. Comparing with PC/notebook,
a mobile enters/exits suspend-2-ram (we call it s3 on Medfield) far
more frequently. If it can't enter suspend-2-ram in time, the power
might be used up soon.
We often find sometimes, a device suspend fails. Then, system retries
s3 over and over again. As display is off, testers and developers
don't know what happens.
Some testers and developers complain they don't know if system
tries suspend-2-ram, and what device fails to suspend. They need
such info for a quick check. The patch adds suspend_stats under
debugfs for users to check suspend to RAM statistics quickly.
If not using this patch, we have other methods to get info about
what device fails. One is to turn on CONFIG_PM_DEBUG, but users
would get too much info and testers need recompile the system.
In addition, dynamic debug is another good tool to dump debug info.
But it still doesn't match our utilization scenario closely.
1) user need write a user space parser to process the syslog output;
2) Our testing scenario is we leave the mobile for at least hours.
Then, check its status. No serial console available during the
testing. One is because console would be suspended, and the other
is serial console connecting with spi or HSU devices would consume
power. These devices are powered off at suspend-2-ram.
Signed-off-by: ShuoX Liu <shuox.liu@intel.com>
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
2011-08-11 05:01:26 +08:00
|
|
|
#include <linux/debugfs.h>
|
|
|
|
#include <linux/seq_file.h>
|
2005-04-17 06:20:36 +08:00
|
|
|
|
|
|
|
#include "power.h"
|
|
|
|
|
2006-12-07 12:34:35 +08:00
|
|
|
DEFINE_MUTEX(pm_mutex);
|
2005-04-17 06:20:36 +08:00
|
|
|
|
2011-02-11 07:04:52 +08:00
|
|
|
#ifdef CONFIG_PM_SLEEP
|
|
|
|
|
2007-11-20 06:49:18 +08:00
|
|
|
/* Routines for PM-transition notifications */
|
|
|
|
|
|
|
|
static BLOCKING_NOTIFIER_HEAD(pm_chain_head);
|
|
|
|
|
|
|
|
int register_pm_notifier(struct notifier_block *nb)
|
|
|
|
{
|
|
|
|
return blocking_notifier_chain_register(&pm_chain_head, nb);
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL_GPL(register_pm_notifier);
|
|
|
|
|
|
|
|
int unregister_pm_notifier(struct notifier_block *nb)
|
|
|
|
{
|
|
|
|
return blocking_notifier_chain_unregister(&pm_chain_head, nb);
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL_GPL(unregister_pm_notifier);
|
|
|
|
|
|
|
|
int pm_notifier_call_chain(unsigned long val)
|
|
|
|
{
|
2011-07-09 02:53:36 +08:00
|
|
|
int ret = blocking_notifier_call_chain(&pm_chain_head, val, NULL);
|
|
|
|
|
|
|
|
return notifier_to_errno(ret);
|
2007-11-20 06:49:18 +08:00
|
|
|
}
|
|
|
|
|
2010-01-24 05:25:15 +08:00
|
|
|
/* If set, devices may be suspended and resumed asynchronously. */
|
|
|
|
int pm_async_enabled = 1;
|
|
|
|
|
|
|
|
static ssize_t pm_async_show(struct kobject *kobj, struct kobj_attribute *attr,
|
|
|
|
char *buf)
|
|
|
|
{
|
|
|
|
return sprintf(buf, "%d\n", pm_async_enabled);
|
|
|
|
}
|
|
|
|
|
|
|
|
static ssize_t pm_async_store(struct kobject *kobj, struct kobj_attribute *attr,
|
|
|
|
const char *buf, size_t n)
|
|
|
|
{
|
|
|
|
unsigned long val;
|
|
|
|
|
2012-10-23 07:20:35 +08:00
|
|
|
if (kstrtoul(buf, 10, &val))
|
2010-01-24 05:25:15 +08:00
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
if (val > 1)
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
pm_async_enabled = val;
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
|
|
|
power_attr(pm_async);
|
|
|
|
|
Suspend: Testing facility (rev. 2)
Introduce sysfs attribute /sys/power/pm_test allowing one to test the suspend
core code. Namely, writing one of the strings:
freezer
devices
platform
processors
core
to this file causes the suspend code to work in one of the test modes defined as
follows:
freezer
- test the freezing of processes
devices
- test the freezing of processes and suspending of devices
platform
- test the freezing of processes, suspending of devices and platform global
control methods(*)
processors
- test the freezing of processes, suspending of devices, platform global
control methods and the disabling of nonboot CPUs
core
- test the freezing of processes, suspending of devices, platform global
control methods, the disabling of nonboot CPUs and suspending of
platform/system devices
(*) These are ACPI global control methods on ACPI systems
Then, if a suspend is started by normal means, the suspend core will perform
its normal operations up to the point indicated by given test level. Next, it
will wait for 5 seconds and carry out the resume operations needed to transition
the system back to the fully functional state.
Writing "none" to /sys/power/pm_test turns the testing off.
When open for reading, /sys/power/pm_test contains a space-separated list of all
available tests (including "none" that represents the normal functionality) in
which the current test level is indicated by square brackets.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Len Brown <len.brown@intel.com>
2007-11-20 06:41:19 +08:00
|
|
|
#ifdef CONFIG_PM_DEBUG
|
|
|
|
int pm_test_level = TEST_NONE;
|
|
|
|
|
|
|
|
static const char * const pm_tests[__TEST_AFTER_LAST] = {
|
|
|
|
[TEST_NONE] = "none",
|
|
|
|
[TEST_CORE] = "core",
|
|
|
|
[TEST_CPUS] = "processors",
|
|
|
|
[TEST_PLATFORM] = "platform",
|
|
|
|
[TEST_DEVICES] = "devices",
|
|
|
|
[TEST_FREEZER] = "freezer",
|
|
|
|
};
|
|
|
|
|
2008-01-29 07:29:06 +08:00
|
|
|
static ssize_t pm_test_show(struct kobject *kobj, struct kobj_attribute *attr,
|
|
|
|
char *buf)
|
Suspend: Testing facility (rev. 2)
Introduce sysfs attribute /sys/power/pm_test allowing one to test the suspend
core code. Namely, writing one of the strings:
freezer
devices
platform
processors
core
to this file causes the suspend code to work in one of the test modes defined as
follows:
freezer
- test the freezing of processes
devices
- test the freezing of processes and suspending of devices
platform
- test the freezing of processes, suspending of devices and platform global
control methods(*)
processors
- test the freezing of processes, suspending of devices, platform global
control methods and the disabling of nonboot CPUs
core
- test the freezing of processes, suspending of devices, platform global
control methods, the disabling of nonboot CPUs and suspending of
platform/system devices
(*) These are ACPI global control methods on ACPI systems
Then, if a suspend is started by normal means, the suspend core will perform
its normal operations up to the point indicated by given test level. Next, it
will wait for 5 seconds and carry out the resume operations needed to transition
the system back to the fully functional state.
Writing "none" to /sys/power/pm_test turns the testing off.
When open for reading, /sys/power/pm_test contains a space-separated list of all
available tests (including "none" that represents the normal functionality) in
which the current test level is indicated by square brackets.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Len Brown <len.brown@intel.com>
2007-11-20 06:41:19 +08:00
|
|
|
{
|
|
|
|
char *s = buf;
|
|
|
|
int level;
|
|
|
|
|
|
|
|
for (level = TEST_FIRST; level <= TEST_MAX; level++)
|
|
|
|
if (pm_tests[level]) {
|
|
|
|
if (level == pm_test_level)
|
|
|
|
s += sprintf(s, "[%s] ", pm_tests[level]);
|
|
|
|
else
|
|
|
|
s += sprintf(s, "%s ", pm_tests[level]);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (s != buf)
|
|
|
|
/* convert the last space to a newline */
|
|
|
|
*(s-1) = '\n';
|
|
|
|
|
|
|
|
return (s - buf);
|
|
|
|
}
|
|
|
|
|
2008-01-29 07:29:06 +08:00
|
|
|
static ssize_t pm_test_store(struct kobject *kobj, struct kobj_attribute *attr,
|
|
|
|
const char *buf, size_t n)
|
Suspend: Testing facility (rev. 2)
Introduce sysfs attribute /sys/power/pm_test allowing one to test the suspend
core code. Namely, writing one of the strings:
freezer
devices
platform
processors
core
to this file causes the suspend code to work in one of the test modes defined as
follows:
freezer
- test the freezing of processes
devices
- test the freezing of processes and suspending of devices
platform
- test the freezing of processes, suspending of devices and platform global
control methods(*)
processors
- test the freezing of processes, suspending of devices, platform global
control methods and the disabling of nonboot CPUs
core
- test the freezing of processes, suspending of devices, platform global
control methods, the disabling of nonboot CPUs and suspending of
platform/system devices
(*) These are ACPI global control methods on ACPI systems
Then, if a suspend is started by normal means, the suspend core will perform
its normal operations up to the point indicated by given test level. Next, it
will wait for 5 seconds and carry out the resume operations needed to transition
the system back to the fully functional state.
Writing "none" to /sys/power/pm_test turns the testing off.
When open for reading, /sys/power/pm_test contains a space-separated list of all
available tests (including "none" that represents the normal functionality) in
which the current test level is indicated by square brackets.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Len Brown <len.brown@intel.com>
2007-11-20 06:41:19 +08:00
|
|
|
{
|
|
|
|
const char * const *s;
|
|
|
|
int level;
|
|
|
|
char *p;
|
|
|
|
int len;
|
|
|
|
int error = -EINVAL;
|
|
|
|
|
|
|
|
p = memchr(buf, '\n', n);
|
|
|
|
len = p ? p - buf : n;
|
|
|
|
|
2011-12-08 05:29:54 +08:00
|
|
|
lock_system_sleep();
|
Suspend: Testing facility (rev. 2)
Introduce sysfs attribute /sys/power/pm_test allowing one to test the suspend
core code. Namely, writing one of the strings:
freezer
devices
platform
processors
core
to this file causes the suspend code to work in one of the test modes defined as
follows:
freezer
- test the freezing of processes
devices
- test the freezing of processes and suspending of devices
platform
- test the freezing of processes, suspending of devices and platform global
control methods(*)
processors
- test the freezing of processes, suspending of devices, platform global
control methods and the disabling of nonboot CPUs
core
- test the freezing of processes, suspending of devices, platform global
control methods, the disabling of nonboot CPUs and suspending of
platform/system devices
(*) These are ACPI global control methods on ACPI systems
Then, if a suspend is started by normal means, the suspend core will perform
its normal operations up to the point indicated by given test level. Next, it
will wait for 5 seconds and carry out the resume operations needed to transition
the system back to the fully functional state.
Writing "none" to /sys/power/pm_test turns the testing off.
When open for reading, /sys/power/pm_test contains a space-separated list of all
available tests (including "none" that represents the normal functionality) in
which the current test level is indicated by square brackets.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Len Brown <len.brown@intel.com>
2007-11-20 06:41:19 +08:00
|
|
|
|
|
|
|
level = TEST_FIRST;
|
|
|
|
for (s = &pm_tests[level]; level <= TEST_MAX; s++, level++)
|
|
|
|
if (*s && len == strlen(*s) && !strncmp(buf, *s, len)) {
|
|
|
|
pm_test_level = level;
|
|
|
|
error = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2011-12-08 05:29:54 +08:00
|
|
|
unlock_system_sleep();
|
Suspend: Testing facility (rev. 2)
Introduce sysfs attribute /sys/power/pm_test allowing one to test the suspend
core code. Namely, writing one of the strings:
freezer
devices
platform
processors
core
to this file causes the suspend code to work in one of the test modes defined as
follows:
freezer
- test the freezing of processes
devices
- test the freezing of processes and suspending of devices
platform
- test the freezing of processes, suspending of devices and platform global
control methods(*)
processors
- test the freezing of processes, suspending of devices, platform global
control methods and the disabling of nonboot CPUs
core
- test the freezing of processes, suspending of devices, platform global
control methods, the disabling of nonboot CPUs and suspending of
platform/system devices
(*) These are ACPI global control methods on ACPI systems
Then, if a suspend is started by normal means, the suspend core will perform
its normal operations up to the point indicated by given test level. Next, it
will wait for 5 seconds and carry out the resume operations needed to transition
the system back to the fully functional state.
Writing "none" to /sys/power/pm_test turns the testing off.
When open for reading, /sys/power/pm_test contains a space-separated list of all
available tests (including "none" that represents the normal functionality) in
which the current test level is indicated by square brackets.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Len Brown <len.brown@intel.com>
2007-11-20 06:41:19 +08:00
|
|
|
|
|
|
|
return error ? error : n;
|
|
|
|
}
|
|
|
|
|
|
|
|
power_attr(pm_test);
|
2009-01-17 07:10:45 +08:00
|
|
|
#endif /* CONFIG_PM_DEBUG */
|
Suspend: Testing facility (rev. 2)
Introduce sysfs attribute /sys/power/pm_test allowing one to test the suspend
core code. Namely, writing one of the strings:
freezer
devices
platform
processors
core
to this file causes the suspend code to work in one of the test modes defined as
follows:
freezer
- test the freezing of processes
devices
- test the freezing of processes and suspending of devices
platform
- test the freezing of processes, suspending of devices and platform global
control methods(*)
processors
- test the freezing of processes, suspending of devices, platform global
control methods and the disabling of nonboot CPUs
core
- test the freezing of processes, suspending of devices, platform global
control methods, the disabling of nonboot CPUs and suspending of
platform/system devices
(*) These are ACPI global control methods on ACPI systems
Then, if a suspend is started by normal means, the suspend core will perform
its normal operations up to the point indicated by given test level. Next, it
will wait for 5 seconds and carry out the resume operations needed to transition
the system back to the fully functional state.
Writing "none" to /sys/power/pm_test turns the testing off.
When open for reading, /sys/power/pm_test contains a space-separated list of all
available tests (including "none" that represents the normal functionality) in
which the current test level is indicated by square brackets.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Len Brown <len.brown@intel.com>
2007-11-20 06:41:19 +08:00
|
|
|
|
PM / Suspend: Add statistics debugfs file for suspend to RAM
Record S3 failure time about each reason and the latest two failed
devices' names in S3 progress.
We can check it through 'suspend_stats' entry in debugfs.
The motivation of the patch:
We are enabling power features on Medfield. Comparing with PC/notebook,
a mobile enters/exits suspend-2-ram (we call it s3 on Medfield) far
more frequently. If it can't enter suspend-2-ram in time, the power
might be used up soon.
We often find sometimes, a device suspend fails. Then, system retries
s3 over and over again. As display is off, testers and developers
don't know what happens.
Some testers and developers complain they don't know if system
tries suspend-2-ram, and what device fails to suspend. They need
such info for a quick check. The patch adds suspend_stats under
debugfs for users to check suspend to RAM statistics quickly.
If not using this patch, we have other methods to get info about
what device fails. One is to turn on CONFIG_PM_DEBUG, but users
would get too much info and testers need recompile the system.
In addition, dynamic debug is another good tool to dump debug info.
But it still doesn't match our utilization scenario closely.
1) user need write a user space parser to process the syslog output;
2) Our testing scenario is we leave the mobile for at least hours.
Then, check its status. No serial console available during the
testing. One is because console would be suspended, and the other
is serial console connecting with spi or HSU devices would consume
power. These devices are powered off at suspend-2-ram.
Signed-off-by: ShuoX Liu <shuox.liu@intel.com>
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
2011-08-11 05:01:26 +08:00
|
|
|
#ifdef CONFIG_DEBUG_FS
|
|
|
|
static char *suspend_step_name(enum suspend_stat_step step)
|
|
|
|
{
|
|
|
|
switch (step) {
|
|
|
|
case SUSPEND_FREEZE:
|
|
|
|
return "freeze";
|
|
|
|
case SUSPEND_PREPARE:
|
|
|
|
return "prepare";
|
|
|
|
case SUSPEND_SUSPEND:
|
|
|
|
return "suspend";
|
|
|
|
case SUSPEND_SUSPEND_NOIRQ:
|
|
|
|
return "suspend_noirq";
|
|
|
|
case SUSPEND_RESUME_NOIRQ:
|
|
|
|
return "resume_noirq";
|
|
|
|
case SUSPEND_RESUME:
|
|
|
|
return "resume";
|
|
|
|
default:
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static int suspend_stats_show(struct seq_file *s, void *unused)
|
|
|
|
{
|
|
|
|
int i, index, last_dev, last_errno, last_step;
|
|
|
|
|
|
|
|
last_dev = suspend_stats.last_failed_dev + REC_FAILED_NUM - 1;
|
|
|
|
last_dev %= REC_FAILED_NUM;
|
|
|
|
last_errno = suspend_stats.last_failed_errno + REC_FAILED_NUM - 1;
|
|
|
|
last_errno %= REC_FAILED_NUM;
|
|
|
|
last_step = suspend_stats.last_failed_step + REC_FAILED_NUM - 1;
|
|
|
|
last_step %= REC_FAILED_NUM;
|
2012-01-30 03:38:29 +08:00
|
|
|
seq_printf(s, "%s: %d\n%s: %d\n%s: %d\n%s: %d\n%s: %d\n"
|
|
|
|
"%s: %d\n%s: %d\n%s: %d\n%s: %d\n%s: %d\n",
|
PM / Suspend: Add statistics debugfs file for suspend to RAM
Record S3 failure time about each reason and the latest two failed
devices' names in S3 progress.
We can check it through 'suspend_stats' entry in debugfs.
The motivation of the patch:
We are enabling power features on Medfield. Comparing with PC/notebook,
a mobile enters/exits suspend-2-ram (we call it s3 on Medfield) far
more frequently. If it can't enter suspend-2-ram in time, the power
might be used up soon.
We often find sometimes, a device suspend fails. Then, system retries
s3 over and over again. As display is off, testers and developers
don't know what happens.
Some testers and developers complain they don't know if system
tries suspend-2-ram, and what device fails to suspend. They need
such info for a quick check. The patch adds suspend_stats under
debugfs for users to check suspend to RAM statistics quickly.
If not using this patch, we have other methods to get info about
what device fails. One is to turn on CONFIG_PM_DEBUG, but users
would get too much info and testers need recompile the system.
In addition, dynamic debug is another good tool to dump debug info.
But it still doesn't match our utilization scenario closely.
1) user need write a user space parser to process the syslog output;
2) Our testing scenario is we leave the mobile for at least hours.
Then, check its status. No serial console available during the
testing. One is because console would be suspended, and the other
is serial console connecting with spi or HSU devices would consume
power. These devices are powered off at suspend-2-ram.
Signed-off-by: ShuoX Liu <shuox.liu@intel.com>
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
2011-08-11 05:01:26 +08:00
|
|
|
"success", suspend_stats.success,
|
|
|
|
"fail", suspend_stats.fail,
|
|
|
|
"failed_freeze", suspend_stats.failed_freeze,
|
|
|
|
"failed_prepare", suspend_stats.failed_prepare,
|
|
|
|
"failed_suspend", suspend_stats.failed_suspend,
|
2012-01-30 03:38:29 +08:00
|
|
|
"failed_suspend_late",
|
|
|
|
suspend_stats.failed_suspend_late,
|
PM / Suspend: Add statistics debugfs file for suspend to RAM
Record S3 failure time about each reason and the latest two failed
devices' names in S3 progress.
We can check it through 'suspend_stats' entry in debugfs.
The motivation of the patch:
We are enabling power features on Medfield. Comparing with PC/notebook,
a mobile enters/exits suspend-2-ram (we call it s3 on Medfield) far
more frequently. If it can't enter suspend-2-ram in time, the power
might be used up soon.
We often find sometimes, a device suspend fails. Then, system retries
s3 over and over again. As display is off, testers and developers
don't know what happens.
Some testers and developers complain they don't know if system
tries suspend-2-ram, and what device fails to suspend. They need
such info for a quick check. The patch adds suspend_stats under
debugfs for users to check suspend to RAM statistics quickly.
If not using this patch, we have other methods to get info about
what device fails. One is to turn on CONFIG_PM_DEBUG, but users
would get too much info and testers need recompile the system.
In addition, dynamic debug is another good tool to dump debug info.
But it still doesn't match our utilization scenario closely.
1) user need write a user space parser to process the syslog output;
2) Our testing scenario is we leave the mobile for at least hours.
Then, check its status. No serial console available during the
testing. One is because console would be suspended, and the other
is serial console connecting with spi or HSU devices would consume
power. These devices are powered off at suspend-2-ram.
Signed-off-by: ShuoX Liu <shuox.liu@intel.com>
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
2011-08-11 05:01:26 +08:00
|
|
|
"failed_suspend_noirq",
|
|
|
|
suspend_stats.failed_suspend_noirq,
|
|
|
|
"failed_resume", suspend_stats.failed_resume,
|
2012-01-30 03:38:29 +08:00
|
|
|
"failed_resume_early",
|
|
|
|
suspend_stats.failed_resume_early,
|
PM / Suspend: Add statistics debugfs file for suspend to RAM
Record S3 failure time about each reason and the latest two failed
devices' names in S3 progress.
We can check it through 'suspend_stats' entry in debugfs.
The motivation of the patch:
We are enabling power features on Medfield. Comparing with PC/notebook,
a mobile enters/exits suspend-2-ram (we call it s3 on Medfield) far
more frequently. If it can't enter suspend-2-ram in time, the power
might be used up soon.
We often find sometimes, a device suspend fails. Then, system retries
s3 over and over again. As display is off, testers and developers
don't know what happens.
Some testers and developers complain they don't know if system
tries suspend-2-ram, and what device fails to suspend. They need
such info for a quick check. The patch adds suspend_stats under
debugfs for users to check suspend to RAM statistics quickly.
If not using this patch, we have other methods to get info about
what device fails. One is to turn on CONFIG_PM_DEBUG, but users
would get too much info and testers need recompile the system.
In addition, dynamic debug is another good tool to dump debug info.
But it still doesn't match our utilization scenario closely.
1) user need write a user space parser to process the syslog output;
2) Our testing scenario is we leave the mobile for at least hours.
Then, check its status. No serial console available during the
testing. One is because console would be suspended, and the other
is serial console connecting with spi or HSU devices would consume
power. These devices are powered off at suspend-2-ram.
Signed-off-by: ShuoX Liu <shuox.liu@intel.com>
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
2011-08-11 05:01:26 +08:00
|
|
|
"failed_resume_noirq",
|
|
|
|
suspend_stats.failed_resume_noirq);
|
|
|
|
seq_printf(s, "failures:\n last_failed_dev:\t%-s\n",
|
|
|
|
suspend_stats.failed_devs[last_dev]);
|
|
|
|
for (i = 1; i < REC_FAILED_NUM; i++) {
|
|
|
|
index = last_dev + REC_FAILED_NUM - i;
|
|
|
|
index %= REC_FAILED_NUM;
|
|
|
|
seq_printf(s, "\t\t\t%-s\n",
|
|
|
|
suspend_stats.failed_devs[index]);
|
|
|
|
}
|
|
|
|
seq_printf(s, " last_failed_errno:\t%-d\n",
|
|
|
|
suspend_stats.errno[last_errno]);
|
|
|
|
for (i = 1; i < REC_FAILED_NUM; i++) {
|
|
|
|
index = last_errno + REC_FAILED_NUM - i;
|
|
|
|
index %= REC_FAILED_NUM;
|
|
|
|
seq_printf(s, "\t\t\t%-d\n",
|
|
|
|
suspend_stats.errno[index]);
|
|
|
|
}
|
|
|
|
seq_printf(s, " last_failed_step:\t%-s\n",
|
|
|
|
suspend_step_name(
|
|
|
|
suspend_stats.failed_steps[last_step]));
|
|
|
|
for (i = 1; i < REC_FAILED_NUM; i++) {
|
|
|
|
index = last_step + REC_FAILED_NUM - i;
|
|
|
|
index %= REC_FAILED_NUM;
|
|
|
|
seq_printf(s, "\t\t\t%-s\n",
|
|
|
|
suspend_step_name(
|
|
|
|
suspend_stats.failed_steps[index]));
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int suspend_stats_open(struct inode *inode, struct file *file)
|
|
|
|
{
|
|
|
|
return single_open(file, suspend_stats_show, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct file_operations suspend_stats_operations = {
|
|
|
|
.open = suspend_stats_open,
|
|
|
|
.read = seq_read,
|
|
|
|
.llseek = seq_lseek,
|
|
|
|
.release = single_release,
|
|
|
|
};
|
|
|
|
|
|
|
|
static int __init pm_debugfs_init(void)
|
|
|
|
{
|
|
|
|
debugfs_create_file("suspend_stats", S_IFREG | S_IRUGO,
|
|
|
|
NULL, NULL, &suspend_stats_operations);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
late_initcall(pm_debugfs_init);
|
|
|
|
#endif /* CONFIG_DEBUG_FS */
|
|
|
|
|
2011-08-12 04:38:12 +08:00
|
|
|
#endif /* CONFIG_PM_SLEEP */
|
|
|
|
|
2012-06-21 06:19:33 +08:00
|
|
|
#ifdef CONFIG_PM_SLEEP_DEBUG
|
|
|
|
/*
|
|
|
|
* pm_print_times: print time taken by devices to suspend and resume.
|
|
|
|
*
|
|
|
|
* show() returns whether printing of suspend and resume times is enabled.
|
|
|
|
* store() accepts 0 or 1. 0 disables printing and 1 enables it.
|
|
|
|
*/
|
|
|
|
bool pm_print_times_enabled;
|
|
|
|
|
|
|
|
static ssize_t pm_print_times_show(struct kobject *kobj,
|
|
|
|
struct kobj_attribute *attr, char *buf)
|
|
|
|
{
|
|
|
|
return sprintf(buf, "%d\n", pm_print_times_enabled);
|
|
|
|
}
|
|
|
|
|
|
|
|
static ssize_t pm_print_times_store(struct kobject *kobj,
|
|
|
|
struct kobj_attribute *attr,
|
|
|
|
const char *buf, size_t n)
|
|
|
|
{
|
|
|
|
unsigned long val;
|
|
|
|
|
|
|
|
if (kstrtoul(buf, 10, &val))
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
if (val > 1)
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
pm_print_times_enabled = !!val;
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
|
|
|
power_attr(pm_print_times);
|
|
|
|
|
|
|
|
static inline void pm_print_times_init(void)
|
|
|
|
{
|
|
|
|
pm_print_times_enabled = !!initcall_debug;
|
|
|
|
}
|
|
|
|
#else /* !CONFIG_PP_SLEEP_DEBUG */
|
|
|
|
static inline void pm_print_times_init(void) {}
|
|
|
|
#endif /* CONFIG_PM_SLEEP_DEBUG */
|
|
|
|
|
2007-11-28 03:28:26 +08:00
|
|
|
struct kobject *power_kobj;
|
2005-04-17 06:20:36 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* state - control system power state.
|
|
|
|
*
|
|
|
|
* show() returns what states are supported, which is hard-coded to
|
|
|
|
* 'standby' (Power-On Suspend), 'mem' (Suspend-to-RAM), and
|
|
|
|
* 'disk' (Suspend-to-Disk).
|
|
|
|
*
|
2011-11-19 21:39:01 +08:00
|
|
|
* store() accepts one of those strings, translates it into the
|
2005-04-17 06:20:36 +08:00
|
|
|
* proper enumerated value, and initiates a suspend transition.
|
|
|
|
*/
|
2007-11-02 20:47:53 +08:00
|
|
|
static ssize_t state_show(struct kobject *kobj, struct kobj_attribute *attr,
|
|
|
|
char *buf)
|
2005-04-17 06:20:36 +08:00
|
|
|
{
|
2007-07-30 05:27:18 +08:00
|
|
|
char *s = buf;
|
|
|
|
#ifdef CONFIG_SUSPEND
|
2005-04-17 06:20:36 +08:00
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < PM_SUSPEND_MAX; i++) {
|
2005-11-30 11:34:37 +08:00
|
|
|
if (pm_states[i] && valid_state(i))
|
|
|
|
s += sprintf(s,"%s ", pm_states[i]);
|
2005-04-17 06:20:36 +08:00
|
|
|
}
|
2007-07-30 05:27:18 +08:00
|
|
|
#endif
|
2007-07-30 05:24:36 +08:00
|
|
|
#ifdef CONFIG_HIBERNATION
|
2007-05-09 17:33:18 +08:00
|
|
|
s += sprintf(s, "%s\n", "disk");
|
|
|
|
#else
|
|
|
|
if (s != buf)
|
|
|
|
/* convert the last space to a newline */
|
|
|
|
*(s-1) = '\n';
|
|
|
|
#endif
|
2005-04-17 06:20:36 +08:00
|
|
|
return (s - buf);
|
|
|
|
}
|
|
|
|
|
2012-04-30 04:53:22 +08:00
|
|
|
static suspend_state_t decode_state(const char *buf, size_t n)
|
2005-04-17 06:20:36 +08:00
|
|
|
{
|
2007-07-30 05:27:18 +08:00
|
|
|
#ifdef CONFIG_SUSPEND
|
PM: Introduce suspend state PM_SUSPEND_FREEZE
PM_SUSPEND_FREEZE state is a general state that
does not need any platform specific support, it equals
frozen processes + suspended devices + idle processors.
Compared with PM_SUSPEND_MEMORY,
PM_SUSPEND_FREEZE saves less power
because the system is still in a running state.
PM_SUSPEND_FREEZE has less resume latency because it does not
touch BIOS, and the processors are in idle state.
Compared with RTPM/idle,
PM_SUSPEND_FREEZE saves more power as
1. the processor has longer sleep time because processes are frozen.
The deeper c-state the processor supports, more power saving we can get.
2. PM_SUSPEND_FREEZE uses system suspend code path, thus we can get
more power saving from the devices that does not have good RTPM support.
This state is useful for
1) platforms that do not have STR, or have a broken STR.
2) platforms that have an extremely low power idle state,
which can be used to replace STR.
The following describes how PM_SUSPEND_FREEZE state works.
1. echo freeze > /sys/power/state
2. the processes are frozen.
3. all the devices are suspended.
4. all the processors are blocked by a wait queue
5. all the processors idles and enters (Deep) c-state.
6. an interrupt fires.
7. a processor is woken up and handles the irq.
8. if it is a general event,
a) the irq handler runs and quites.
b) goto step 4.
9. if it is a real wake event, say, power button pressing, keyboard touch, mouse moving,
a) the irq handler runs and activate the wakeup source
b) wakeup_source_activate() notifies the wait queue.
c) system starts resuming from PM_SUSPEND_FREEZE
10. all the devices are resumed.
11. all the processes are unfrozen.
12. system is back to working.
Known Issue:
The wakeup of this new PM_SUSPEND_FREEZE state may behave differently
from the previous suspend state.
Take ACPI platform for example, there are some GPEs that only enabled
when the system is in sleep state, to wake the system backk from S3/S4.
But we are not touching these GPEs during transition to PM_SUSPEND_FREEZE.
This means we may lose some wake event.
But on the other hand, as we do not disable all the Interrupts during
PM_SUSPEND_FREEZE, we may get some extra "wakeup" Interrupts, that are
not available for S3/S4.
The patches has been tested on an old Sony laptop, and here are the results:
Average Power:
1. RPTM/idle for half an hour:
14.8W, 12.6W, 14.1W, 12.5W, 14.4W, 13.2W, 12.9W
2. Freeze for half an hour:
11W, 10.4W, 9.4W, 11.3W 10.5W
3. RTPM/idle for three hours:
11.6W
4. Freeze for three hours:
10W
5. Suspend to Memory:
0.5~0.9W
Average Resume Latency:
1. RTPM/idle with a black screen: (From pressing keyboard to screen back)
Less than 0.2s
2. Freeze: (From pressing power button to screen back)
2.50s
3. Suspend to Memory: (From pressing power button to screen back)
4.33s
>From the results, we can see that all the platforms should benefit from
this patch, even if it does not have Low Power S0.
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2013-02-06 20:00:36 +08:00
|
|
|
suspend_state_t state = PM_SUSPEND_MIN;
|
2006-06-25 20:47:56 +08:00
|
|
|
const char * const *s;
|
2007-07-30 05:27:18 +08:00
|
|
|
#endif
|
2005-04-17 06:20:36 +08:00
|
|
|
char *p;
|
|
|
|
int len;
|
|
|
|
|
|
|
|
p = memchr(buf, '\n', n);
|
|
|
|
len = p ? p - buf : n;
|
|
|
|
|
2012-04-30 04:53:22 +08:00
|
|
|
/* Check hibernation first. */
|
|
|
|
if (len == 4 && !strncmp(buf, "disk", len))
|
|
|
|
return PM_SUSPEND_MAX;
|
2007-05-09 17:33:18 +08:00
|
|
|
|
2007-07-30 05:27:18 +08:00
|
|
|
#ifdef CONFIG_SUSPEND
|
2012-04-30 04:53:22 +08:00
|
|
|
for (s = &pm_states[state]; state < PM_SUSPEND_MAX; s++, state++)
|
|
|
|
if (*s && len == strlen(*s) && !strncmp(buf, *s, len))
|
|
|
|
return state;
|
2007-07-30 05:27:18 +08:00
|
|
|
#endif
|
|
|
|
|
2012-04-30 04:53:22 +08:00
|
|
|
return PM_SUSPEND_ON;
|
|
|
|
}
|
|
|
|
|
|
|
|
static ssize_t state_store(struct kobject *kobj, struct kobj_attribute *attr,
|
|
|
|
const char *buf, size_t n)
|
|
|
|
{
|
|
|
|
suspend_state_t state;
|
|
|
|
int error;
|
|
|
|
|
|
|
|
error = pm_autosleep_lock();
|
|
|
|
if (error)
|
|
|
|
return error;
|
|
|
|
|
|
|
|
if (pm_autosleep_state() > PM_SUSPEND_ON) {
|
|
|
|
error = -EBUSY;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
state = decode_state(buf, n);
|
|
|
|
if (state < PM_SUSPEND_MAX)
|
|
|
|
error = pm_suspend(state);
|
|
|
|
else if (state == PM_SUSPEND_MAX)
|
|
|
|
error = hibernate();
|
|
|
|
else
|
|
|
|
error = -EINVAL;
|
|
|
|
|
|
|
|
out:
|
|
|
|
pm_autosleep_unlock();
|
2005-04-17 06:20:36 +08:00
|
|
|
return error ? error : n;
|
|
|
|
}
|
|
|
|
|
|
|
|
power_attr(state);
|
|
|
|
|
PM: Make it possible to avoid races between wakeup and system sleep
One of the arguments during the suspend blockers discussion was that
the mainline kernel didn't contain any mechanisms making it possible
to avoid races between wakeup and system suspend.
Generally, there are two problems in that area. First, if a wakeup
event occurs exactly when /sys/power/state is being written to, it
may be delivered to user space right before the freezer kicks in, so
the user space consumer of the event may not be able to process it
before the system is suspended. Second, if a wakeup event occurs
after user space has been frozen, it is not generally guaranteed that
the ongoing transition of the system into a sleep state will be
aborted.
To address these issues introduce a new global sysfs attribute,
/sys/power/wakeup_count, associated with a running counter of wakeup
events and three helper functions, pm_stay_awake(), pm_relax(), and
pm_wakeup_event(), that may be used by kernel subsystems to control
the behavior of this attribute and to request the PM core to abort
system transitions into a sleep state already in progress.
The /sys/power/wakeup_count file may be read from or written to by
user space. Reads will always succeed (unless interrupted by a
signal) and return the current value of the wakeup events counter.
Writes, however, will only succeed if the written number is equal to
the current value of the wakeup events counter. If a write is
successful, it will cause the kernel to save the current value of the
wakeup events counter and to abort the subsequent system transition
into a sleep state if any wakeup events are reported after the write
has returned.
[The assumption is that before writing to /sys/power/state user space
will first read from /sys/power/wakeup_count. Next, user space
consumers of wakeup events will have a chance to acknowledge or
veto the upcoming system transition to a sleep state. Finally, if
the transition is allowed to proceed, /sys/power/wakeup_count will
be written to and if that succeeds, /sys/power/state will be written
to as well. Still, if any wakeup events are reported to the PM core
by kernel subsystems after that point, the transition will be
aborted.]
Additionally, put a wakeup events counter into struct dev_pm_info and
make these per-device wakeup event counters available via sysfs,
so that it's possible to check the activity of various wakeup event
sources within the kernel.
To illustrate how subsystems can use pm_wakeup_event(), make the
low-level PCI runtime PM wakeup-handling code use it.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Acked-by: Greg Kroah-Hartman <gregkh@suse.de>
Acked-by: markgross <markgross@thegnar.org>
Reviewed-by: Alan Stern <stern@rowland.harvard.edu>
2010-07-06 04:43:53 +08:00
|
|
|
#ifdef CONFIG_PM_SLEEP
|
|
|
|
/*
|
|
|
|
* The 'wakeup_count' attribute, along with the functions defined in
|
|
|
|
* drivers/base/power/wakeup.c, provides a means by which wakeup events can be
|
|
|
|
* handled in a non-racy way.
|
|
|
|
*
|
|
|
|
* If a wakeup event occurs when the system is in a sleep state, it simply is
|
|
|
|
* woken up. In turn, if an event that would wake the system up from a sleep
|
|
|
|
* state occurs when it is undergoing a transition to that sleep state, the
|
|
|
|
* transition should be aborted. Moreover, if such an event occurs when the
|
|
|
|
* system is in the working state, an attempt to start a transition to the
|
|
|
|
* given sleep state should fail during certain period after the detection of
|
|
|
|
* the event. Using the 'state' attribute alone is not sufficient to satisfy
|
|
|
|
* these requirements, because a wakeup event may occur exactly when 'state'
|
|
|
|
* is being written to and may be delivered to user space right before it is
|
|
|
|
* frozen, so the event will remain only partially processed until the system is
|
|
|
|
* woken up by another event. In particular, it won't cause the transition to
|
|
|
|
* a sleep state to be aborted.
|
|
|
|
*
|
|
|
|
* This difficulty may be overcome if user space uses 'wakeup_count' before
|
|
|
|
* writing to 'state'. It first should read from 'wakeup_count' and store
|
|
|
|
* the read value. Then, after carrying out its own preparations for the system
|
|
|
|
* transition to a sleep state, it should write the stored value to
|
2011-03-31 09:57:33 +08:00
|
|
|
* 'wakeup_count'. If that fails, at least one wakeup event has occurred since
|
PM: Make it possible to avoid races between wakeup and system sleep
One of the arguments during the suspend blockers discussion was that
the mainline kernel didn't contain any mechanisms making it possible
to avoid races between wakeup and system suspend.
Generally, there are two problems in that area. First, if a wakeup
event occurs exactly when /sys/power/state is being written to, it
may be delivered to user space right before the freezer kicks in, so
the user space consumer of the event may not be able to process it
before the system is suspended. Second, if a wakeup event occurs
after user space has been frozen, it is not generally guaranteed that
the ongoing transition of the system into a sleep state will be
aborted.
To address these issues introduce a new global sysfs attribute,
/sys/power/wakeup_count, associated with a running counter of wakeup
events and three helper functions, pm_stay_awake(), pm_relax(), and
pm_wakeup_event(), that may be used by kernel subsystems to control
the behavior of this attribute and to request the PM core to abort
system transitions into a sleep state already in progress.
The /sys/power/wakeup_count file may be read from or written to by
user space. Reads will always succeed (unless interrupted by a
signal) and return the current value of the wakeup events counter.
Writes, however, will only succeed if the written number is equal to
the current value of the wakeup events counter. If a write is
successful, it will cause the kernel to save the current value of the
wakeup events counter and to abort the subsequent system transition
into a sleep state if any wakeup events are reported after the write
has returned.
[The assumption is that before writing to /sys/power/state user space
will first read from /sys/power/wakeup_count. Next, user space
consumers of wakeup events will have a chance to acknowledge or
veto the upcoming system transition to a sleep state. Finally, if
the transition is allowed to proceed, /sys/power/wakeup_count will
be written to and if that succeeds, /sys/power/state will be written
to as well. Still, if any wakeup events are reported to the PM core
by kernel subsystems after that point, the transition will be
aborted.]
Additionally, put a wakeup events counter into struct dev_pm_info and
make these per-device wakeup event counters available via sysfs,
so that it's possible to check the activity of various wakeup event
sources within the kernel.
To illustrate how subsystems can use pm_wakeup_event(), make the
low-level PCI runtime PM wakeup-handling code use it.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Acked-by: Greg Kroah-Hartman <gregkh@suse.de>
Acked-by: markgross <markgross@thegnar.org>
Reviewed-by: Alan Stern <stern@rowland.harvard.edu>
2010-07-06 04:43:53 +08:00
|
|
|
* 'wakeup_count' was read and 'state' should not be written to. Otherwise, it
|
|
|
|
* is allowed to write to 'state', but the transition will be aborted if there
|
|
|
|
* are any wakeup events detected after 'wakeup_count' was written to.
|
|
|
|
*/
|
|
|
|
|
|
|
|
static ssize_t wakeup_count_show(struct kobject *kobj,
|
|
|
|
struct kobj_attribute *attr,
|
|
|
|
char *buf)
|
|
|
|
{
|
2010-09-23 04:09:10 +08:00
|
|
|
unsigned int val;
|
PM: Make it possible to avoid races between wakeup and system sleep
One of the arguments during the suspend blockers discussion was that
the mainline kernel didn't contain any mechanisms making it possible
to avoid races between wakeup and system suspend.
Generally, there are two problems in that area. First, if a wakeup
event occurs exactly when /sys/power/state is being written to, it
may be delivered to user space right before the freezer kicks in, so
the user space consumer of the event may not be able to process it
before the system is suspended. Second, if a wakeup event occurs
after user space has been frozen, it is not generally guaranteed that
the ongoing transition of the system into a sleep state will be
aborted.
To address these issues introduce a new global sysfs attribute,
/sys/power/wakeup_count, associated with a running counter of wakeup
events and three helper functions, pm_stay_awake(), pm_relax(), and
pm_wakeup_event(), that may be used by kernel subsystems to control
the behavior of this attribute and to request the PM core to abort
system transitions into a sleep state already in progress.
The /sys/power/wakeup_count file may be read from or written to by
user space. Reads will always succeed (unless interrupted by a
signal) and return the current value of the wakeup events counter.
Writes, however, will only succeed if the written number is equal to
the current value of the wakeup events counter. If a write is
successful, it will cause the kernel to save the current value of the
wakeup events counter and to abort the subsequent system transition
into a sleep state if any wakeup events are reported after the write
has returned.
[The assumption is that before writing to /sys/power/state user space
will first read from /sys/power/wakeup_count. Next, user space
consumers of wakeup events will have a chance to acknowledge or
veto the upcoming system transition to a sleep state. Finally, if
the transition is allowed to proceed, /sys/power/wakeup_count will
be written to and if that succeeds, /sys/power/state will be written
to as well. Still, if any wakeup events are reported to the PM core
by kernel subsystems after that point, the transition will be
aborted.]
Additionally, put a wakeup events counter into struct dev_pm_info and
make these per-device wakeup event counters available via sysfs,
so that it's possible to check the activity of various wakeup event
sources within the kernel.
To illustrate how subsystems can use pm_wakeup_event(), make the
low-level PCI runtime PM wakeup-handling code use it.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Acked-by: Greg Kroah-Hartman <gregkh@suse.de>
Acked-by: markgross <markgross@thegnar.org>
Reviewed-by: Alan Stern <stern@rowland.harvard.edu>
2010-07-06 04:43:53 +08:00
|
|
|
|
2012-04-30 04:53:22 +08:00
|
|
|
return pm_get_wakeup_count(&val, true) ?
|
|
|
|
sprintf(buf, "%u\n", val) : -EINTR;
|
PM: Make it possible to avoid races between wakeup and system sleep
One of the arguments during the suspend blockers discussion was that
the mainline kernel didn't contain any mechanisms making it possible
to avoid races between wakeup and system suspend.
Generally, there are two problems in that area. First, if a wakeup
event occurs exactly when /sys/power/state is being written to, it
may be delivered to user space right before the freezer kicks in, so
the user space consumer of the event may not be able to process it
before the system is suspended. Second, if a wakeup event occurs
after user space has been frozen, it is not generally guaranteed that
the ongoing transition of the system into a sleep state will be
aborted.
To address these issues introduce a new global sysfs attribute,
/sys/power/wakeup_count, associated with a running counter of wakeup
events and three helper functions, pm_stay_awake(), pm_relax(), and
pm_wakeup_event(), that may be used by kernel subsystems to control
the behavior of this attribute and to request the PM core to abort
system transitions into a sleep state already in progress.
The /sys/power/wakeup_count file may be read from or written to by
user space. Reads will always succeed (unless interrupted by a
signal) and return the current value of the wakeup events counter.
Writes, however, will only succeed if the written number is equal to
the current value of the wakeup events counter. If a write is
successful, it will cause the kernel to save the current value of the
wakeup events counter and to abort the subsequent system transition
into a sleep state if any wakeup events are reported after the write
has returned.
[The assumption is that before writing to /sys/power/state user space
will first read from /sys/power/wakeup_count. Next, user space
consumers of wakeup events will have a chance to acknowledge or
veto the upcoming system transition to a sleep state. Finally, if
the transition is allowed to proceed, /sys/power/wakeup_count will
be written to and if that succeeds, /sys/power/state will be written
to as well. Still, if any wakeup events are reported to the PM core
by kernel subsystems after that point, the transition will be
aborted.]
Additionally, put a wakeup events counter into struct dev_pm_info and
make these per-device wakeup event counters available via sysfs,
so that it's possible to check the activity of various wakeup event
sources within the kernel.
To illustrate how subsystems can use pm_wakeup_event(), make the
low-level PCI runtime PM wakeup-handling code use it.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Acked-by: Greg Kroah-Hartman <gregkh@suse.de>
Acked-by: markgross <markgross@thegnar.org>
Reviewed-by: Alan Stern <stern@rowland.harvard.edu>
2010-07-06 04:43:53 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static ssize_t wakeup_count_store(struct kobject *kobj,
|
|
|
|
struct kobj_attribute *attr,
|
|
|
|
const char *buf, size_t n)
|
|
|
|
{
|
2010-09-23 04:09:10 +08:00
|
|
|
unsigned int val;
|
2012-04-30 04:53:22 +08:00
|
|
|
int error;
|
|
|
|
|
|
|
|
error = pm_autosleep_lock();
|
|
|
|
if (error)
|
|
|
|
return error;
|
PM: Make it possible to avoid races between wakeup and system sleep
One of the arguments during the suspend blockers discussion was that
the mainline kernel didn't contain any mechanisms making it possible
to avoid races between wakeup and system suspend.
Generally, there are two problems in that area. First, if a wakeup
event occurs exactly when /sys/power/state is being written to, it
may be delivered to user space right before the freezer kicks in, so
the user space consumer of the event may not be able to process it
before the system is suspended. Second, if a wakeup event occurs
after user space has been frozen, it is not generally guaranteed that
the ongoing transition of the system into a sleep state will be
aborted.
To address these issues introduce a new global sysfs attribute,
/sys/power/wakeup_count, associated with a running counter of wakeup
events and three helper functions, pm_stay_awake(), pm_relax(), and
pm_wakeup_event(), that may be used by kernel subsystems to control
the behavior of this attribute and to request the PM core to abort
system transitions into a sleep state already in progress.
The /sys/power/wakeup_count file may be read from or written to by
user space. Reads will always succeed (unless interrupted by a
signal) and return the current value of the wakeup events counter.
Writes, however, will only succeed if the written number is equal to
the current value of the wakeup events counter. If a write is
successful, it will cause the kernel to save the current value of the
wakeup events counter and to abort the subsequent system transition
into a sleep state if any wakeup events are reported after the write
has returned.
[The assumption is that before writing to /sys/power/state user space
will first read from /sys/power/wakeup_count. Next, user space
consumers of wakeup events will have a chance to acknowledge or
veto the upcoming system transition to a sleep state. Finally, if
the transition is allowed to proceed, /sys/power/wakeup_count will
be written to and if that succeeds, /sys/power/state will be written
to as well. Still, if any wakeup events are reported to the PM core
by kernel subsystems after that point, the transition will be
aborted.]
Additionally, put a wakeup events counter into struct dev_pm_info and
make these per-device wakeup event counters available via sysfs,
so that it's possible to check the activity of various wakeup event
sources within the kernel.
To illustrate how subsystems can use pm_wakeup_event(), make the
low-level PCI runtime PM wakeup-handling code use it.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Acked-by: Greg Kroah-Hartman <gregkh@suse.de>
Acked-by: markgross <markgross@thegnar.org>
Reviewed-by: Alan Stern <stern@rowland.harvard.edu>
2010-07-06 04:43:53 +08:00
|
|
|
|
2012-04-30 04:53:22 +08:00
|
|
|
if (pm_autosleep_state() > PM_SUSPEND_ON) {
|
|
|
|
error = -EBUSY;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
error = -EINVAL;
|
2010-09-23 04:09:10 +08:00
|
|
|
if (sscanf(buf, "%u", &val) == 1) {
|
PM: Make it possible to avoid races between wakeup and system sleep
One of the arguments during the suspend blockers discussion was that
the mainline kernel didn't contain any mechanisms making it possible
to avoid races between wakeup and system suspend.
Generally, there are two problems in that area. First, if a wakeup
event occurs exactly when /sys/power/state is being written to, it
may be delivered to user space right before the freezer kicks in, so
the user space consumer of the event may not be able to process it
before the system is suspended. Second, if a wakeup event occurs
after user space has been frozen, it is not generally guaranteed that
the ongoing transition of the system into a sleep state will be
aborted.
To address these issues introduce a new global sysfs attribute,
/sys/power/wakeup_count, associated with a running counter of wakeup
events and three helper functions, pm_stay_awake(), pm_relax(), and
pm_wakeup_event(), that may be used by kernel subsystems to control
the behavior of this attribute and to request the PM core to abort
system transitions into a sleep state already in progress.
The /sys/power/wakeup_count file may be read from or written to by
user space. Reads will always succeed (unless interrupted by a
signal) and return the current value of the wakeup events counter.
Writes, however, will only succeed if the written number is equal to
the current value of the wakeup events counter. If a write is
successful, it will cause the kernel to save the current value of the
wakeup events counter and to abort the subsequent system transition
into a sleep state if any wakeup events are reported after the write
has returned.
[The assumption is that before writing to /sys/power/state user space
will first read from /sys/power/wakeup_count. Next, user space
consumers of wakeup events will have a chance to acknowledge or
veto the upcoming system transition to a sleep state. Finally, if
the transition is allowed to proceed, /sys/power/wakeup_count will
be written to and if that succeeds, /sys/power/state will be written
to as well. Still, if any wakeup events are reported to the PM core
by kernel subsystems after that point, the transition will be
aborted.]
Additionally, put a wakeup events counter into struct dev_pm_info and
make these per-device wakeup event counters available via sysfs,
so that it's possible to check the activity of various wakeup event
sources within the kernel.
To illustrate how subsystems can use pm_wakeup_event(), make the
low-level PCI runtime PM wakeup-handling code use it.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Acked-by: Greg Kroah-Hartman <gregkh@suse.de>
Acked-by: markgross <markgross@thegnar.org>
Reviewed-by: Alan Stern <stern@rowland.harvard.edu>
2010-07-06 04:43:53 +08:00
|
|
|
if (pm_save_wakeup_count(val))
|
2012-04-30 04:53:22 +08:00
|
|
|
error = n;
|
PM: Make it possible to avoid races between wakeup and system sleep
One of the arguments during the suspend blockers discussion was that
the mainline kernel didn't contain any mechanisms making it possible
to avoid races between wakeup and system suspend.
Generally, there are two problems in that area. First, if a wakeup
event occurs exactly when /sys/power/state is being written to, it
may be delivered to user space right before the freezer kicks in, so
the user space consumer of the event may not be able to process it
before the system is suspended. Second, if a wakeup event occurs
after user space has been frozen, it is not generally guaranteed that
the ongoing transition of the system into a sleep state will be
aborted.
To address these issues introduce a new global sysfs attribute,
/sys/power/wakeup_count, associated with a running counter of wakeup
events and three helper functions, pm_stay_awake(), pm_relax(), and
pm_wakeup_event(), that may be used by kernel subsystems to control
the behavior of this attribute and to request the PM core to abort
system transitions into a sleep state already in progress.
The /sys/power/wakeup_count file may be read from or written to by
user space. Reads will always succeed (unless interrupted by a
signal) and return the current value of the wakeup events counter.
Writes, however, will only succeed if the written number is equal to
the current value of the wakeup events counter. If a write is
successful, it will cause the kernel to save the current value of the
wakeup events counter and to abort the subsequent system transition
into a sleep state if any wakeup events are reported after the write
has returned.
[The assumption is that before writing to /sys/power/state user space
will first read from /sys/power/wakeup_count. Next, user space
consumers of wakeup events will have a chance to acknowledge or
veto the upcoming system transition to a sleep state. Finally, if
the transition is allowed to proceed, /sys/power/wakeup_count will
be written to and if that succeeds, /sys/power/state will be written
to as well. Still, if any wakeup events are reported to the PM core
by kernel subsystems after that point, the transition will be
aborted.]
Additionally, put a wakeup events counter into struct dev_pm_info and
make these per-device wakeup event counters available via sysfs,
so that it's possible to check the activity of various wakeup event
sources within the kernel.
To illustrate how subsystems can use pm_wakeup_event(), make the
low-level PCI runtime PM wakeup-handling code use it.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Acked-by: Greg Kroah-Hartman <gregkh@suse.de>
Acked-by: markgross <markgross@thegnar.org>
Reviewed-by: Alan Stern <stern@rowland.harvard.edu>
2010-07-06 04:43:53 +08:00
|
|
|
}
|
2012-04-30 04:53:22 +08:00
|
|
|
|
|
|
|
out:
|
|
|
|
pm_autosleep_unlock();
|
|
|
|
return error;
|
PM: Make it possible to avoid races between wakeup and system sleep
One of the arguments during the suspend blockers discussion was that
the mainline kernel didn't contain any mechanisms making it possible
to avoid races between wakeup and system suspend.
Generally, there are two problems in that area. First, if a wakeup
event occurs exactly when /sys/power/state is being written to, it
may be delivered to user space right before the freezer kicks in, so
the user space consumer of the event may not be able to process it
before the system is suspended. Second, if a wakeup event occurs
after user space has been frozen, it is not generally guaranteed that
the ongoing transition of the system into a sleep state will be
aborted.
To address these issues introduce a new global sysfs attribute,
/sys/power/wakeup_count, associated with a running counter of wakeup
events and three helper functions, pm_stay_awake(), pm_relax(), and
pm_wakeup_event(), that may be used by kernel subsystems to control
the behavior of this attribute and to request the PM core to abort
system transitions into a sleep state already in progress.
The /sys/power/wakeup_count file may be read from or written to by
user space. Reads will always succeed (unless interrupted by a
signal) and return the current value of the wakeup events counter.
Writes, however, will only succeed if the written number is equal to
the current value of the wakeup events counter. If a write is
successful, it will cause the kernel to save the current value of the
wakeup events counter and to abort the subsequent system transition
into a sleep state if any wakeup events are reported after the write
has returned.
[The assumption is that before writing to /sys/power/state user space
will first read from /sys/power/wakeup_count. Next, user space
consumers of wakeup events will have a chance to acknowledge or
veto the upcoming system transition to a sleep state. Finally, if
the transition is allowed to proceed, /sys/power/wakeup_count will
be written to and if that succeeds, /sys/power/state will be written
to as well. Still, if any wakeup events are reported to the PM core
by kernel subsystems after that point, the transition will be
aborted.]
Additionally, put a wakeup events counter into struct dev_pm_info and
make these per-device wakeup event counters available via sysfs,
so that it's possible to check the activity of various wakeup event
sources within the kernel.
To illustrate how subsystems can use pm_wakeup_event(), make the
low-level PCI runtime PM wakeup-handling code use it.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Acked-by: Greg Kroah-Hartman <gregkh@suse.de>
Acked-by: markgross <markgross@thegnar.org>
Reviewed-by: Alan Stern <stern@rowland.harvard.edu>
2010-07-06 04:43:53 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
power_attr(wakeup_count);
|
2012-04-30 04:53:22 +08:00
|
|
|
|
|
|
|
#ifdef CONFIG_PM_AUTOSLEEP
|
|
|
|
static ssize_t autosleep_show(struct kobject *kobj,
|
|
|
|
struct kobj_attribute *attr,
|
|
|
|
char *buf)
|
|
|
|
{
|
|
|
|
suspend_state_t state = pm_autosleep_state();
|
|
|
|
|
|
|
|
if (state == PM_SUSPEND_ON)
|
|
|
|
return sprintf(buf, "off\n");
|
|
|
|
|
|
|
|
#ifdef CONFIG_SUSPEND
|
|
|
|
if (state < PM_SUSPEND_MAX)
|
|
|
|
return sprintf(buf, "%s\n", valid_state(state) ?
|
|
|
|
pm_states[state] : "error");
|
|
|
|
#endif
|
|
|
|
#ifdef CONFIG_HIBERNATION
|
|
|
|
return sprintf(buf, "disk\n");
|
|
|
|
#else
|
|
|
|
return sprintf(buf, "error");
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
static ssize_t autosleep_store(struct kobject *kobj,
|
|
|
|
struct kobj_attribute *attr,
|
|
|
|
const char *buf, size_t n)
|
|
|
|
{
|
|
|
|
suspend_state_t state = decode_state(buf, n);
|
|
|
|
int error;
|
|
|
|
|
|
|
|
if (state == PM_SUSPEND_ON
|
2012-05-04 06:14:21 +08:00
|
|
|
&& strcmp(buf, "off") && strcmp(buf, "off\n"))
|
2012-04-30 04:53:22 +08:00
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
error = pm_autosleep_set_state(state);
|
|
|
|
return error ? error : n;
|
|
|
|
}
|
|
|
|
|
|
|
|
power_attr(autosleep);
|
|
|
|
#endif /* CONFIG_PM_AUTOSLEEP */
|
PM / Sleep: Add user space interface for manipulating wakeup sources, v3
Android allows user space to manipulate wakelocks using two
sysfs file located in /sys/power/, wake_lock and wake_unlock.
Writing a wakelock name and optionally a timeout to the wake_lock
file causes the wakelock whose name was written to be acquired (it
is created before is necessary), optionally with the given timeout.
Writing the name of a wakelock to wake_unlock causes that wakelock
to be released.
Implement an analogous interface for user space using wakeup sources.
Add the /sys/power/wake_lock and /sys/power/wake_unlock files
allowing user space to create, activate and deactivate wakeup
sources, such that writing a name and optionally a timeout to
wake_lock causes the wakeup source of that name to be activated,
optionally with the given timeout. If that wakeup source doesn't
exist, it will be created and then activated. Writing a name to
wake_unlock causes the wakeup source of that name, if there is one,
to be deactivated. Wakeup sources created with the help of
wake_lock that haven't been used for more than 5 minutes are garbage
collected and destroyed. Moreover, there can be only WL_NUMBER_LIMIT
wakeup sources created with the help of wake_lock present at a time.
The data type used to track wakeup sources created by user space is
called "struct wakelock" to indicate the origins of this feature.
This version of the patch includes an rbtree manipulation fix from John Stultz.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Reviewed-by: NeilBrown <neilb@suse.de>
2012-04-30 04:53:42 +08:00
|
|
|
|
|
|
|
#ifdef CONFIG_PM_WAKELOCKS
|
|
|
|
static ssize_t wake_lock_show(struct kobject *kobj,
|
|
|
|
struct kobj_attribute *attr,
|
|
|
|
char *buf)
|
|
|
|
{
|
|
|
|
return pm_show_wakelocks(buf, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
static ssize_t wake_lock_store(struct kobject *kobj,
|
|
|
|
struct kobj_attribute *attr,
|
|
|
|
const char *buf, size_t n)
|
|
|
|
{
|
|
|
|
int error = pm_wake_lock(buf);
|
|
|
|
return error ? error : n;
|
|
|
|
}
|
|
|
|
|
|
|
|
power_attr(wake_lock);
|
|
|
|
|
|
|
|
static ssize_t wake_unlock_show(struct kobject *kobj,
|
|
|
|
struct kobj_attribute *attr,
|
|
|
|
char *buf)
|
|
|
|
{
|
|
|
|
return pm_show_wakelocks(buf, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
static ssize_t wake_unlock_store(struct kobject *kobj,
|
|
|
|
struct kobj_attribute *attr,
|
|
|
|
const char *buf, size_t n)
|
|
|
|
{
|
|
|
|
int error = pm_wake_unlock(buf);
|
|
|
|
return error ? error : n;
|
|
|
|
}
|
|
|
|
|
|
|
|
power_attr(wake_unlock);
|
|
|
|
|
|
|
|
#endif /* CONFIG_PM_WAKELOCKS */
|
PM: Make it possible to avoid races between wakeup and system sleep
One of the arguments during the suspend blockers discussion was that
the mainline kernel didn't contain any mechanisms making it possible
to avoid races between wakeup and system suspend.
Generally, there are two problems in that area. First, if a wakeup
event occurs exactly when /sys/power/state is being written to, it
may be delivered to user space right before the freezer kicks in, so
the user space consumer of the event may not be able to process it
before the system is suspended. Second, if a wakeup event occurs
after user space has been frozen, it is not generally guaranteed that
the ongoing transition of the system into a sleep state will be
aborted.
To address these issues introduce a new global sysfs attribute,
/sys/power/wakeup_count, associated with a running counter of wakeup
events and three helper functions, pm_stay_awake(), pm_relax(), and
pm_wakeup_event(), that may be used by kernel subsystems to control
the behavior of this attribute and to request the PM core to abort
system transitions into a sleep state already in progress.
The /sys/power/wakeup_count file may be read from or written to by
user space. Reads will always succeed (unless interrupted by a
signal) and return the current value of the wakeup events counter.
Writes, however, will only succeed if the written number is equal to
the current value of the wakeup events counter. If a write is
successful, it will cause the kernel to save the current value of the
wakeup events counter and to abort the subsequent system transition
into a sleep state if any wakeup events are reported after the write
has returned.
[The assumption is that before writing to /sys/power/state user space
will first read from /sys/power/wakeup_count. Next, user space
consumers of wakeup events will have a chance to acknowledge or
veto the upcoming system transition to a sleep state. Finally, if
the transition is allowed to proceed, /sys/power/wakeup_count will
be written to and if that succeeds, /sys/power/state will be written
to as well. Still, if any wakeup events are reported to the PM core
by kernel subsystems after that point, the transition will be
aborted.]
Additionally, put a wakeup events counter into struct dev_pm_info and
make these per-device wakeup event counters available via sysfs,
so that it's possible to check the activity of various wakeup event
sources within the kernel.
To illustrate how subsystems can use pm_wakeup_event(), make the
low-level PCI runtime PM wakeup-handling code use it.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Acked-by: Greg Kroah-Hartman <gregkh@suse.de>
Acked-by: markgross <markgross@thegnar.org>
Reviewed-by: Alan Stern <stern@rowland.harvard.edu>
2010-07-06 04:43:53 +08:00
|
|
|
#endif /* CONFIG_PM_SLEEP */
|
|
|
|
|
2006-09-26 14:32:58 +08:00
|
|
|
#ifdef CONFIG_PM_TRACE
|
|
|
|
int pm_trace_enabled;
|
|
|
|
|
2007-11-02 20:47:53 +08:00
|
|
|
static ssize_t pm_trace_show(struct kobject *kobj, struct kobj_attribute *attr,
|
|
|
|
char *buf)
|
2006-09-26 14:32:58 +08:00
|
|
|
{
|
|
|
|
return sprintf(buf, "%d\n", pm_trace_enabled);
|
|
|
|
}
|
|
|
|
|
|
|
|
static ssize_t
|
2007-11-02 20:47:53 +08:00
|
|
|
pm_trace_store(struct kobject *kobj, struct kobj_attribute *attr,
|
|
|
|
const char *buf, size_t n)
|
2006-09-26 14:32:58 +08:00
|
|
|
{
|
|
|
|
int val;
|
|
|
|
|
|
|
|
if (sscanf(buf, "%d", &val) == 1) {
|
|
|
|
pm_trace_enabled = !!val;
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
power_attr(pm_trace);
|
2010-10-12 06:00:25 +08:00
|
|
|
|
|
|
|
static ssize_t pm_trace_dev_match_show(struct kobject *kobj,
|
|
|
|
struct kobj_attribute *attr,
|
|
|
|
char *buf)
|
|
|
|
{
|
|
|
|
return show_trace_dev_match(buf, PAGE_SIZE);
|
|
|
|
}
|
|
|
|
|
|
|
|
static ssize_t
|
|
|
|
pm_trace_dev_match_store(struct kobject *kobj, struct kobj_attribute *attr,
|
|
|
|
const char *buf, size_t n)
|
|
|
|
{
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
power_attr(pm_trace_dev_match);
|
|
|
|
|
Suspend: Testing facility (rev. 2)
Introduce sysfs attribute /sys/power/pm_test allowing one to test the suspend
core code. Namely, writing one of the strings:
freezer
devices
platform
processors
core
to this file causes the suspend code to work in one of the test modes defined as
follows:
freezer
- test the freezing of processes
devices
- test the freezing of processes and suspending of devices
platform
- test the freezing of processes, suspending of devices and platform global
control methods(*)
processors
- test the freezing of processes, suspending of devices, platform global
control methods and the disabling of nonboot CPUs
core
- test the freezing of processes, suspending of devices, platform global
control methods, the disabling of nonboot CPUs and suspending of
platform/system devices
(*) These are ACPI global control methods on ACPI systems
Then, if a suspend is started by normal means, the suspend core will perform
its normal operations up to the point indicated by given test level. Next, it
will wait for 5 seconds and carry out the resume operations needed to transition
the system back to the fully functional state.
Writing "none" to /sys/power/pm_test turns the testing off.
When open for reading, /sys/power/pm_test contains a space-separated list of all
available tests (including "none" that represents the normal functionality) in
which the current test level is indicated by square brackets.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Len Brown <len.brown@intel.com>
2007-11-20 06:41:19 +08:00
|
|
|
#endif /* CONFIG_PM_TRACE */
|
2006-09-26 14:32:58 +08:00
|
|
|
|
|
|
|
static struct attribute * g[] = {
|
|
|
|
&state_attr.attr,
|
Suspend: Testing facility (rev. 2)
Introduce sysfs attribute /sys/power/pm_test allowing one to test the suspend
core code. Namely, writing one of the strings:
freezer
devices
platform
processors
core
to this file causes the suspend code to work in one of the test modes defined as
follows:
freezer
- test the freezing of processes
devices
- test the freezing of processes and suspending of devices
platform
- test the freezing of processes, suspending of devices and platform global
control methods(*)
processors
- test the freezing of processes, suspending of devices, platform global
control methods and the disabling of nonboot CPUs
core
- test the freezing of processes, suspending of devices, platform global
control methods, the disabling of nonboot CPUs and suspending of
platform/system devices
(*) These are ACPI global control methods on ACPI systems
Then, if a suspend is started by normal means, the suspend core will perform
its normal operations up to the point indicated by given test level. Next, it
will wait for 5 seconds and carry out the resume operations needed to transition
the system back to the fully functional state.
Writing "none" to /sys/power/pm_test turns the testing off.
When open for reading, /sys/power/pm_test contains a space-separated list of all
available tests (including "none" that represents the normal functionality) in
which the current test level is indicated by square brackets.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Len Brown <len.brown@intel.com>
2007-11-20 06:41:19 +08:00
|
|
|
#ifdef CONFIG_PM_TRACE
|
2006-09-26 14:32:58 +08:00
|
|
|
&pm_trace_attr.attr,
|
2010-10-12 06:00:25 +08:00
|
|
|
&pm_trace_dev_match_attr.attr,
|
Suspend: Testing facility (rev. 2)
Introduce sysfs attribute /sys/power/pm_test allowing one to test the suspend
core code. Namely, writing one of the strings:
freezer
devices
platform
processors
core
to this file causes the suspend code to work in one of the test modes defined as
follows:
freezer
- test the freezing of processes
devices
- test the freezing of processes and suspending of devices
platform
- test the freezing of processes, suspending of devices and platform global
control methods(*)
processors
- test the freezing of processes, suspending of devices, platform global
control methods and the disabling of nonboot CPUs
core
- test the freezing of processes, suspending of devices, platform global
control methods, the disabling of nonboot CPUs and suspending of
platform/system devices
(*) These are ACPI global control methods on ACPI systems
Then, if a suspend is started by normal means, the suspend core will perform
its normal operations up to the point indicated by given test level. Next, it
will wait for 5 seconds and carry out the resume operations needed to transition
the system back to the fully functional state.
Writing "none" to /sys/power/pm_test turns the testing off.
When open for reading, /sys/power/pm_test contains a space-separated list of all
available tests (including "none" that represents the normal functionality) in
which the current test level is indicated by square brackets.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Len Brown <len.brown@intel.com>
2007-11-20 06:41:19 +08:00
|
|
|
#endif
|
2010-01-24 05:25:15 +08:00
|
|
|
#ifdef CONFIG_PM_SLEEP
|
|
|
|
&pm_async_attr.attr,
|
PM: Make it possible to avoid races between wakeup and system sleep
One of the arguments during the suspend blockers discussion was that
the mainline kernel didn't contain any mechanisms making it possible
to avoid races between wakeup and system suspend.
Generally, there are two problems in that area. First, if a wakeup
event occurs exactly when /sys/power/state is being written to, it
may be delivered to user space right before the freezer kicks in, so
the user space consumer of the event may not be able to process it
before the system is suspended. Second, if a wakeup event occurs
after user space has been frozen, it is not generally guaranteed that
the ongoing transition of the system into a sleep state will be
aborted.
To address these issues introduce a new global sysfs attribute,
/sys/power/wakeup_count, associated with a running counter of wakeup
events and three helper functions, pm_stay_awake(), pm_relax(), and
pm_wakeup_event(), that may be used by kernel subsystems to control
the behavior of this attribute and to request the PM core to abort
system transitions into a sleep state already in progress.
The /sys/power/wakeup_count file may be read from or written to by
user space. Reads will always succeed (unless interrupted by a
signal) and return the current value of the wakeup events counter.
Writes, however, will only succeed if the written number is equal to
the current value of the wakeup events counter. If a write is
successful, it will cause the kernel to save the current value of the
wakeup events counter and to abort the subsequent system transition
into a sleep state if any wakeup events are reported after the write
has returned.
[The assumption is that before writing to /sys/power/state user space
will first read from /sys/power/wakeup_count. Next, user space
consumers of wakeup events will have a chance to acknowledge or
veto the upcoming system transition to a sleep state. Finally, if
the transition is allowed to proceed, /sys/power/wakeup_count will
be written to and if that succeeds, /sys/power/state will be written
to as well. Still, if any wakeup events are reported to the PM core
by kernel subsystems after that point, the transition will be
aborted.]
Additionally, put a wakeup events counter into struct dev_pm_info and
make these per-device wakeup event counters available via sysfs,
so that it's possible to check the activity of various wakeup event
sources within the kernel.
To illustrate how subsystems can use pm_wakeup_event(), make the
low-level PCI runtime PM wakeup-handling code use it.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Acked-by: Greg Kroah-Hartman <gregkh@suse.de>
Acked-by: markgross <markgross@thegnar.org>
Reviewed-by: Alan Stern <stern@rowland.harvard.edu>
2010-07-06 04:43:53 +08:00
|
|
|
&wakeup_count_attr.attr,
|
2012-04-30 04:53:22 +08:00
|
|
|
#ifdef CONFIG_PM_AUTOSLEEP
|
|
|
|
&autosleep_attr.attr,
|
|
|
|
#endif
|
PM / Sleep: Add user space interface for manipulating wakeup sources, v3
Android allows user space to manipulate wakelocks using two
sysfs file located in /sys/power/, wake_lock and wake_unlock.
Writing a wakelock name and optionally a timeout to the wake_lock
file causes the wakelock whose name was written to be acquired (it
is created before is necessary), optionally with the given timeout.
Writing the name of a wakelock to wake_unlock causes that wakelock
to be released.
Implement an analogous interface for user space using wakeup sources.
Add the /sys/power/wake_lock and /sys/power/wake_unlock files
allowing user space to create, activate and deactivate wakeup
sources, such that writing a name and optionally a timeout to
wake_lock causes the wakeup source of that name to be activated,
optionally with the given timeout. If that wakeup source doesn't
exist, it will be created and then activated. Writing a name to
wake_unlock causes the wakeup source of that name, if there is one,
to be deactivated. Wakeup sources created with the help of
wake_lock that haven't been used for more than 5 minutes are garbage
collected and destroyed. Moreover, there can be only WL_NUMBER_LIMIT
wakeup sources created with the help of wake_lock present at a time.
The data type used to track wakeup sources created by user space is
called "struct wakelock" to indicate the origins of this feature.
This version of the patch includes an rbtree manipulation fix from John Stultz.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Reviewed-by: NeilBrown <neilb@suse.de>
2012-04-30 04:53:42 +08:00
|
|
|
#ifdef CONFIG_PM_WAKELOCKS
|
|
|
|
&wake_lock_attr.attr,
|
|
|
|
&wake_unlock_attr.attr,
|
|
|
|
#endif
|
2010-01-24 05:25:15 +08:00
|
|
|
#ifdef CONFIG_PM_DEBUG
|
Suspend: Testing facility (rev. 2)
Introduce sysfs attribute /sys/power/pm_test allowing one to test the suspend
core code. Namely, writing one of the strings:
freezer
devices
platform
processors
core
to this file causes the suspend code to work in one of the test modes defined as
follows:
freezer
- test the freezing of processes
devices
- test the freezing of processes and suspending of devices
platform
- test the freezing of processes, suspending of devices and platform global
control methods(*)
processors
- test the freezing of processes, suspending of devices, platform global
control methods and the disabling of nonboot CPUs
core
- test the freezing of processes, suspending of devices, platform global
control methods, the disabling of nonboot CPUs and suspending of
platform/system devices
(*) These are ACPI global control methods on ACPI systems
Then, if a suspend is started by normal means, the suspend core will perform
its normal operations up to the point indicated by given test level. Next, it
will wait for 5 seconds and carry out the resume operations needed to transition
the system back to the fully functional state.
Writing "none" to /sys/power/pm_test turns the testing off.
When open for reading, /sys/power/pm_test contains a space-separated list of all
available tests (including "none" that represents the normal functionality) in
which the current test level is indicated by square brackets.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Len Brown <len.brown@intel.com>
2007-11-20 06:41:19 +08:00
|
|
|
&pm_test_attr.attr,
|
2012-06-21 06:19:33 +08:00
|
|
|
#endif
|
|
|
|
#ifdef CONFIG_PM_SLEEP_DEBUG
|
2012-06-20 04:23:33 +08:00
|
|
|
&pm_print_times_attr.attr,
|
2010-01-24 05:25:15 +08:00
|
|
|
#endif
|
Suspend: Testing facility (rev. 2)
Introduce sysfs attribute /sys/power/pm_test allowing one to test the suspend
core code. Namely, writing one of the strings:
freezer
devices
platform
processors
core
to this file causes the suspend code to work in one of the test modes defined as
follows:
freezer
- test the freezing of processes
devices
- test the freezing of processes and suspending of devices
platform
- test the freezing of processes, suspending of devices and platform global
control methods(*)
processors
- test the freezing of processes, suspending of devices, platform global
control methods and the disabling of nonboot CPUs
core
- test the freezing of processes, suspending of devices, platform global
control methods, the disabling of nonboot CPUs and suspending of
platform/system devices
(*) These are ACPI global control methods on ACPI systems
Then, if a suspend is started by normal means, the suspend core will perform
its normal operations up to the point indicated by given test level. Next, it
will wait for 5 seconds and carry out the resume operations needed to transition
the system back to the fully functional state.
Writing "none" to /sys/power/pm_test turns the testing off.
When open for reading, /sys/power/pm_test contains a space-separated list of all
available tests (including "none" that represents the normal functionality) in
which the current test level is indicated by square brackets.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Len Brown <len.brown@intel.com>
2007-11-20 06:41:19 +08:00
|
|
|
#endif
|
2006-09-26 14:32:58 +08:00
|
|
|
NULL,
|
|
|
|
};
|
2005-04-17 06:20:36 +08:00
|
|
|
|
|
|
|
static struct attribute_group attr_group = {
|
|
|
|
.attrs = g,
|
|
|
|
};
|
|
|
|
|
2009-08-19 05:38:32 +08:00
|
|
|
#ifdef CONFIG_PM_RUNTIME
|
|
|
|
struct workqueue_struct *pm_wq;
|
2009-12-04 03:22:21 +08:00
|
|
|
EXPORT_SYMBOL_GPL(pm_wq);
|
2009-08-19 05:38:32 +08:00
|
|
|
|
|
|
|
static int __init pm_start_workqueue(void)
|
|
|
|
{
|
2011-02-16 16:25:31 +08:00
|
|
|
pm_wq = alloc_workqueue("pm", WQ_FREEZABLE, 0);
|
2009-08-19 05:38:32 +08:00
|
|
|
|
|
|
|
return pm_wq ? 0 : -ENOMEM;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
static inline int pm_start_workqueue(void) { return 0; }
|
|
|
|
#endif
|
|
|
|
|
2005-04-17 06:20:36 +08:00
|
|
|
static int __init pm_init(void)
|
|
|
|
{
|
2009-08-19 05:38:32 +08:00
|
|
|
int error = pm_start_workqueue();
|
|
|
|
if (error)
|
|
|
|
return error;
|
2010-09-21 01:44:56 +08:00
|
|
|
hibernate_image_size_init();
|
2011-05-15 17:38:48 +08:00
|
|
|
hibernate_reserved_size_init();
|
2007-11-28 03:28:26 +08:00
|
|
|
power_kobj = kobject_create_and_add("power", NULL);
|
|
|
|
if (!power_kobj)
|
2007-11-02 01:39:50 +08:00
|
|
|
return -ENOMEM;
|
2012-04-30 04:53:22 +08:00
|
|
|
error = sysfs_create_group(power_kobj, &attr_group);
|
|
|
|
if (error)
|
|
|
|
return error;
|
2012-06-21 06:19:33 +08:00
|
|
|
pm_print_times_init();
|
2012-04-30 04:53:22 +08:00
|
|
|
return pm_autosleep_init();
|
2005-04-17 06:20:36 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
core_initcall(pm_init);
|