Power manager options
[*] Power Management Debug Support
[*] Verbose Power Management debugging
[*] Suspend to RAM and standby
[*] Test suspend/resume and walealarm during bootup
上面幾個 option 打開。這樣 config 就會有
CONFIG_PM_DEBUG=y
CONFIG_PM_VREBOSE=y
CONFIG_PM_TEST_SUSPEND=y
這樣,在 kernel/power 下
main.c:
static struct attribute * g[] = {
&state_attr.attr,
#ifdef CONFIG_PM_TRACE
&pm_trace_attr.attr,
#endif
#ifdef CONFIG_SUSPEND_DEVICE_TIME_DEBUG
&device_suspend_time_threshold_attr.attr,
#endif
#ifdef CONFIG_PM_SLEEP
&pm_async_attr.attr,
#ifdef CONFIG_PM_DEBUG
&pm_test_attr.attr,
#endif
#ifdef CONFIG_USER_WAKELOCK
&wake_lock_attr.attr,
&wake_unlock_attr.attr,
#endif
#endif
NULL,
};
可以看到每個 option 增加的 entry.
CONFIG_PM_DEBUG,就會有 pm_test_attr 這個 entry
宣告的 pm_test_attr 有:
#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",
};
static ssize_t pm_test_show(struct kobject *kobj, struct kobj_attribute *attr,
char *buf)
{
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);
}
static ssize_t pm_test_store(struct kobject *kobj, struct kobj_attribute *attr,
const char *buf, size_t n)
{
const char * const *s;
int level;
char *p;
int len;
int error = -EINVAL;
p = memchr(buf, '\n', n);
len = p ? p - buf : n;
mutex_lock(&pm_mutex);
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;
}
mutex_unlock(&pm_mutex);
return error ? error : n;
}
power_attr(pm_test);
#endif /* CONFIG_PM_DEBUG */
所以在 /sys/power 下會多一個 pm_test。 cat 出來會是
none core processors platform devices freezser
這個功能是用來測試 suspend/resume 的。
從 source code : kernel/power/suspend.c
static int suspend_enter(suspend_state_t state)
{
.....
if (suspend_test(TEST_PLATFORM))
goto Platform_wake;
error = disable_nonboot_cpus();
if (error || suspend_test(TEST_CPUS))
goto Enable_cpus;
arch_suspend_disable_irqs();
BUG_ON(!irqs_disabled());
error = sysdev_suspend(PMSG_SUSPEND);
if (!error) {
if (!suspend_test(TEST_CORE))
error = suspend_ops->enter(state);
sysdev_resume();
}
...
和 suspend_test( ) function :
static int suspend_test(int level)
{
#ifdef CONFIG_PM_DEBUG
if (pm_test_level == level) {
printk(KERN_INFO "suspend debug: Waiting for 5 seconds.\n");
mdelay(5000);
return 1;
}
#endif /* !CONFIG_PM_DEBUG */
return 0;
}
可以看到, core, processors, platform, devices, freezer 各是不同的 suspend level。利用 suspend_test( ) 可以讓 suspend 在不同 level 後 resume。
所以可以用來坐測試。
使用方法就是在 console 把要 test 的 level 寫入 /sys/power/pm_test 中。
#echo core > /sys/power/pm_test
然後再 trigger suspend...
就會看到 suspend 後 5 sec 就自己 wakeup 了
沒有留言:
張貼留言