Loading kernel/power/main.c +11 −10 Original line number Diff line number Diff line Loading @@ -296,8 +296,8 @@ static ssize_t state_show(struct kobject *kobj, struct kobj_attribute *attr, suspend_state_t i; for (i = PM_SUSPEND_MIN; i < PM_SUSPEND_MAX; i++) if (pm_states[i].state) s += sprintf(s,"%s ", pm_states[i].label); if (pm_states[i]) s += sprintf(s,"%s ", pm_states[i]); #endif if (hibernation_available()) Loading @@ -311,8 +311,7 @@ static ssize_t state_show(struct kobject *kobj, struct kobj_attribute *attr, static suspend_state_t decode_state(const char *buf, size_t n) { #ifdef CONFIG_SUSPEND suspend_state_t state = PM_SUSPEND_MIN; struct pm_sleep_state *s; suspend_state_t state; #endif char *p; int len; Loading @@ -325,10 +324,12 @@ static suspend_state_t decode_state(const char *buf, size_t n) return PM_SUSPEND_MAX; #ifdef CONFIG_SUSPEND for (s = &pm_states[state]; state < PM_SUSPEND_MAX; s++, state++) if (s->state && len == strlen(s->label) && !strncmp(buf, s->label, len)) return s->state; for (state = PM_SUSPEND_MIN; state < PM_SUSPEND_MAX; state++) { const char *label = pm_states[state]; if (label && len == strlen(label) && !strncmp(buf, label, len)) return state; } #endif return PM_SUSPEND_ON; Loading Loading @@ -446,8 +447,8 @@ static ssize_t autosleep_show(struct kobject *kobj, #ifdef CONFIG_SUSPEND if (state < PM_SUSPEND_MAX) return sprintf(buf, "%s\n", pm_states[state].state ? pm_states[state].label : "error"); return sprintf(buf, "%s\n", pm_states[state] ? pm_states[state] : "error"); #endif #ifdef CONFIG_HIBERNATION return sprintf(buf, "disk\n"); Loading kernel/power/power.h +1 −6 Original line number Diff line number Diff line Loading @@ -178,13 +178,8 @@ extern void swsusp_show_speed(struct timeval *, struct timeval *, unsigned int, char *); #ifdef CONFIG_SUSPEND struct pm_sleep_state { const char *label; suspend_state_t state; }; /* kernel/power/suspend.c */ extern struct pm_sleep_state pm_states[]; extern const char *pm_states[]; extern int suspend_devices_and_enter(suspend_state_t state); #else /* !CONFIG_SUSPEND */ Loading kernel/power/suspend.c +90 −62 Original line number Diff line number Diff line Loading @@ -31,20 +31,11 @@ #include "power.h" struct pm_sleep_state pm_states[PM_SUSPEND_MAX] = { [PM_SUSPEND_FREEZE] = { .label = "freeze", .state = PM_SUSPEND_FREEZE }, [PM_SUSPEND_STANDBY] = { .label = "standby", }, [PM_SUSPEND_MEM] = { .label = "mem", }, }; static const char *pm_labels[] = { "mem", "standby", "freeze", }; const char *pm_states[PM_SUSPEND_MAX]; static const struct platform_suspend_ops *suspend_ops; static const struct platform_freeze_ops *freeze_ops; static bool need_suspend_ops(suspend_state_t state) { return state > PM_SUSPEND_FREEZE; } static DECLARE_WAIT_QUEUE_HEAD(suspend_freeze_wait_head); static bool suspend_freeze_wake; Loading Loading @@ -97,10 +88,7 @@ static bool relative_states; static int __init sleep_states_setup(char *str) { relative_states = !strncmp(str, "1", 1); if (relative_states) { pm_states[PM_SUSPEND_MEM].state = PM_SUSPEND_FREEZE; pm_states[PM_SUSPEND_FREEZE].state = 0; } pm_states[PM_SUSPEND_FREEZE] = pm_labels[relative_states ? 0 : 2]; return 1; } Loading @@ -113,20 +101,20 @@ __setup("relative_sleep_states=", sleep_states_setup); void suspend_set_ops(const struct platform_suspend_ops *ops) { suspend_state_t i; int j = PM_SUSPEND_MAX - 1; int j = 0; lock_system_sleep(); suspend_ops = ops; for (i = PM_SUSPEND_MEM; i >= PM_SUSPEND_STANDBY; i--) if (valid_state(i)) pm_states[j--].state = i; else if (!relative_states) pm_states[j--].state = 0; if (valid_state(i)) { pm_states[i] = pm_labels[j++]; } else if (!relative_states) { pm_states[i] = NULL; j++; } pm_states[j--].state = PM_SUSPEND_FREEZE; while (j >= PM_SUSPEND_MIN) pm_states[j--].state = 0; pm_states[PM_SUSPEND_FREEZE] = pm_labels[j]; unlock_system_sleep(); } Loading @@ -145,6 +133,65 @@ int suspend_valid_only_mem(suspend_state_t state) } EXPORT_SYMBOL_GPL(suspend_valid_only_mem); static bool sleep_state_supported(suspend_state_t state) { return state == PM_SUSPEND_FREEZE || (suspend_ops && suspend_ops->enter); } static int platform_suspend_prepare(suspend_state_t state) { return state != PM_SUSPEND_FREEZE && suspend_ops->prepare ? suspend_ops->prepare() : 0; } static int platform_suspend_prepare_late(suspend_state_t state) { return state != PM_SUSPEND_FREEZE && suspend_ops->prepare_late ? suspend_ops->prepare_late() : 0; } static void platform_suspend_wake(suspend_state_t state) { if (state != PM_SUSPEND_FREEZE && suspend_ops->wake) suspend_ops->wake(); } static void platform_suspend_finish(suspend_state_t state) { if (state != PM_SUSPEND_FREEZE && suspend_ops->finish) suspend_ops->finish(); } static int platform_suspend_begin(suspend_state_t state) { if (state == PM_SUSPEND_FREEZE && freeze_ops && freeze_ops->begin) return freeze_ops->begin(); else if (suspend_ops->begin) return suspend_ops->begin(state); else return 0; } static void platform_suspend_end(suspend_state_t state) { if (state == PM_SUSPEND_FREEZE && freeze_ops && freeze_ops->end) freeze_ops->end(); else if (suspend_ops->end) suspend_ops->end(); } static void platform_suspend_recover(suspend_state_t state) { if (state != PM_SUSPEND_FREEZE && suspend_ops->recover) suspend_ops->recover(); } static bool platform_suspend_again(suspend_state_t state) { return state != PM_SUSPEND_FREEZE && suspend_ops->suspend_again ? suspend_ops->suspend_again() : false; } static int suspend_test(int level) { #ifdef CONFIG_PM_DEBUG Loading @@ -168,7 +215,7 @@ static int suspend_prepare(suspend_state_t state) { int error; if (need_suspend_ops(state) && (!suspend_ops || !suspend_ops->enter)) if (!sleep_state_supported(state)) return -EPERM; pm_prepare_console(); Loading Loading @@ -214,23 +261,18 @@ static int suspend_enter(suspend_state_t state, bool *wakeup) { int error; if (need_suspend_ops(state) && suspend_ops->prepare) { error = suspend_ops->prepare(); error = platform_suspend_prepare(state); if (error) goto Platform_finish; } error = dpm_suspend_end(PMSG_SUSPEND); if (error) { printk(KERN_ERR "PM: Some devices failed to power down\n"); goto Platform_finish; } if (need_suspend_ops(state) && suspend_ops->prepare_late) { error = suspend_ops->prepare_late(); error = platform_suspend_prepare_late(state); if (error) goto Platform_wake; } if (suspend_test(TEST_PLATFORM)) goto Platform_wake; Loading Loading @@ -278,15 +320,11 @@ static int suspend_enter(suspend_state_t state, bool *wakeup) ftrace_start(); Platform_wake: if (need_suspend_ops(state) && suspend_ops->wake) suspend_ops->wake(); platform_suspend_wake(state); dpm_resume_start(PMSG_RESUME); Platform_finish: if (need_suspend_ops(state) && suspend_ops->finish) suspend_ops->finish(); platform_suspend_finish(state); return error; } Loading @@ -299,18 +337,13 @@ int suspend_devices_and_enter(suspend_state_t state) int error; bool wakeup = false; if (need_suspend_ops(state) && !suspend_ops) if (!sleep_state_supported(state)) return -ENOSYS; if (need_suspend_ops(state) && suspend_ops->begin) { error = suspend_ops->begin(state); error = platform_suspend_begin(state); if (error) goto Close; } else if (state == PM_SUSPEND_FREEZE && freeze_ops && freeze_ops->begin) { error = freeze_ops->begin(); if (error) goto Close; } suspend_console(); suspend_test_start(); error = dpm_suspend_start(PMSG_SUSPEND); Loading @@ -324,25 +357,20 @@ int suspend_devices_and_enter(suspend_state_t state) do { error = suspend_enter(state, &wakeup); } while (!error && !wakeup && need_suspend_ops(state) && suspend_ops->suspend_again && suspend_ops->suspend_again()); } while (!error && !wakeup && platform_suspend_again(state)); Resume_devices: suspend_test_start(); dpm_resume_end(PMSG_RESUME); suspend_test_finish("resume devices"); resume_console(); Close: if (need_suspend_ops(state) && suspend_ops->end) suspend_ops->end(); else if (state == PM_SUSPEND_FREEZE && freeze_ops && freeze_ops->end) freeze_ops->end(); Close: platform_suspend_end(state); return error; Recover_platform: if (need_suspend_ops(state) && suspend_ops->recover) suspend_ops->recover(); platform_suspend_recover(state); goto Resume_devices; } Loading Loading @@ -395,7 +423,7 @@ static int enter_state(suspend_state_t state) printk("done.\n"); trace_suspend_resume(TPS("sync_filesystems"), 0, false); pr_debug("PM: Preparing system for %s sleep\n", pm_states[state].label); pr_debug("PM: Preparing system for %s sleep\n", pm_states[state]); error = suspend_prepare(state); if (error) goto Unlock; Loading @@ -404,7 +432,7 @@ static int enter_state(suspend_state_t state) goto Finish; trace_suspend_resume(TPS("suspend_enter"), state, false); pr_debug("PM: Entering %s sleep\n", pm_states[state].label); pr_debug("PM: Entering %s sleep\n", pm_states[state]); pm_restrict_gfp_mask(); error = suspend_devices_and_enter(state); pm_restore_gfp_mask(); Loading kernel/power/suspend_test.c +6 −6 Original line number Diff line number Diff line Loading @@ -92,13 +92,13 @@ static void __init test_wakealarm(struct rtc_device *rtc, suspend_state_t state) } if (state == PM_SUSPEND_MEM) { printk(info_test, pm_states[state].label); printk(info_test, pm_states[state]); status = pm_suspend(state); if (status == -ENODEV) state = PM_SUSPEND_STANDBY; } if (state == PM_SUSPEND_STANDBY) { printk(info_test, pm_states[state].label); printk(info_test, pm_states[state]); status = pm_suspend(state); } if (status < 0) Loading Loading @@ -141,8 +141,8 @@ static int __init setup_test_suspend(char *value) /* "=mem" ==> "mem" */ value++; for (i = PM_SUSPEND_MIN; i < PM_SUSPEND_MAX; i++) if (!strcmp(pm_states[i].label, value)) { test_state = pm_states[i].state; if (!strcmp(pm_states[i], value)) { test_state = i; return 0; } Loading @@ -162,8 +162,8 @@ static int __init test_suspend(void) /* PM is initialized by now; is that state testable? */ if (test_state == PM_SUSPEND_ON) goto done; if (!pm_states[test_state].state) { printk(warn_bad_state, pm_states[test_state].label); if (!pm_states[test_state]) { printk(warn_bad_state, pm_states[test_state]); goto done; } Loading Loading
kernel/power/main.c +11 −10 Original line number Diff line number Diff line Loading @@ -296,8 +296,8 @@ static ssize_t state_show(struct kobject *kobj, struct kobj_attribute *attr, suspend_state_t i; for (i = PM_SUSPEND_MIN; i < PM_SUSPEND_MAX; i++) if (pm_states[i].state) s += sprintf(s,"%s ", pm_states[i].label); if (pm_states[i]) s += sprintf(s,"%s ", pm_states[i]); #endif if (hibernation_available()) Loading @@ -311,8 +311,7 @@ static ssize_t state_show(struct kobject *kobj, struct kobj_attribute *attr, static suspend_state_t decode_state(const char *buf, size_t n) { #ifdef CONFIG_SUSPEND suspend_state_t state = PM_SUSPEND_MIN; struct pm_sleep_state *s; suspend_state_t state; #endif char *p; int len; Loading @@ -325,10 +324,12 @@ static suspend_state_t decode_state(const char *buf, size_t n) return PM_SUSPEND_MAX; #ifdef CONFIG_SUSPEND for (s = &pm_states[state]; state < PM_SUSPEND_MAX; s++, state++) if (s->state && len == strlen(s->label) && !strncmp(buf, s->label, len)) return s->state; for (state = PM_SUSPEND_MIN; state < PM_SUSPEND_MAX; state++) { const char *label = pm_states[state]; if (label && len == strlen(label) && !strncmp(buf, label, len)) return state; } #endif return PM_SUSPEND_ON; Loading Loading @@ -446,8 +447,8 @@ static ssize_t autosleep_show(struct kobject *kobj, #ifdef CONFIG_SUSPEND if (state < PM_SUSPEND_MAX) return sprintf(buf, "%s\n", pm_states[state].state ? pm_states[state].label : "error"); return sprintf(buf, "%s\n", pm_states[state] ? pm_states[state] : "error"); #endif #ifdef CONFIG_HIBERNATION return sprintf(buf, "disk\n"); Loading
kernel/power/power.h +1 −6 Original line number Diff line number Diff line Loading @@ -178,13 +178,8 @@ extern void swsusp_show_speed(struct timeval *, struct timeval *, unsigned int, char *); #ifdef CONFIG_SUSPEND struct pm_sleep_state { const char *label; suspend_state_t state; }; /* kernel/power/suspend.c */ extern struct pm_sleep_state pm_states[]; extern const char *pm_states[]; extern int suspend_devices_and_enter(suspend_state_t state); #else /* !CONFIG_SUSPEND */ Loading
kernel/power/suspend.c +90 −62 Original line number Diff line number Diff line Loading @@ -31,20 +31,11 @@ #include "power.h" struct pm_sleep_state pm_states[PM_SUSPEND_MAX] = { [PM_SUSPEND_FREEZE] = { .label = "freeze", .state = PM_SUSPEND_FREEZE }, [PM_SUSPEND_STANDBY] = { .label = "standby", }, [PM_SUSPEND_MEM] = { .label = "mem", }, }; static const char *pm_labels[] = { "mem", "standby", "freeze", }; const char *pm_states[PM_SUSPEND_MAX]; static const struct platform_suspend_ops *suspend_ops; static const struct platform_freeze_ops *freeze_ops; static bool need_suspend_ops(suspend_state_t state) { return state > PM_SUSPEND_FREEZE; } static DECLARE_WAIT_QUEUE_HEAD(suspend_freeze_wait_head); static bool suspend_freeze_wake; Loading Loading @@ -97,10 +88,7 @@ static bool relative_states; static int __init sleep_states_setup(char *str) { relative_states = !strncmp(str, "1", 1); if (relative_states) { pm_states[PM_SUSPEND_MEM].state = PM_SUSPEND_FREEZE; pm_states[PM_SUSPEND_FREEZE].state = 0; } pm_states[PM_SUSPEND_FREEZE] = pm_labels[relative_states ? 0 : 2]; return 1; } Loading @@ -113,20 +101,20 @@ __setup("relative_sleep_states=", sleep_states_setup); void suspend_set_ops(const struct platform_suspend_ops *ops) { suspend_state_t i; int j = PM_SUSPEND_MAX - 1; int j = 0; lock_system_sleep(); suspend_ops = ops; for (i = PM_SUSPEND_MEM; i >= PM_SUSPEND_STANDBY; i--) if (valid_state(i)) pm_states[j--].state = i; else if (!relative_states) pm_states[j--].state = 0; if (valid_state(i)) { pm_states[i] = pm_labels[j++]; } else if (!relative_states) { pm_states[i] = NULL; j++; } pm_states[j--].state = PM_SUSPEND_FREEZE; while (j >= PM_SUSPEND_MIN) pm_states[j--].state = 0; pm_states[PM_SUSPEND_FREEZE] = pm_labels[j]; unlock_system_sleep(); } Loading @@ -145,6 +133,65 @@ int suspend_valid_only_mem(suspend_state_t state) } EXPORT_SYMBOL_GPL(suspend_valid_only_mem); static bool sleep_state_supported(suspend_state_t state) { return state == PM_SUSPEND_FREEZE || (suspend_ops && suspend_ops->enter); } static int platform_suspend_prepare(suspend_state_t state) { return state != PM_SUSPEND_FREEZE && suspend_ops->prepare ? suspend_ops->prepare() : 0; } static int platform_suspend_prepare_late(suspend_state_t state) { return state != PM_SUSPEND_FREEZE && suspend_ops->prepare_late ? suspend_ops->prepare_late() : 0; } static void platform_suspend_wake(suspend_state_t state) { if (state != PM_SUSPEND_FREEZE && suspend_ops->wake) suspend_ops->wake(); } static void platform_suspend_finish(suspend_state_t state) { if (state != PM_SUSPEND_FREEZE && suspend_ops->finish) suspend_ops->finish(); } static int platform_suspend_begin(suspend_state_t state) { if (state == PM_SUSPEND_FREEZE && freeze_ops && freeze_ops->begin) return freeze_ops->begin(); else if (suspend_ops->begin) return suspend_ops->begin(state); else return 0; } static void platform_suspend_end(suspend_state_t state) { if (state == PM_SUSPEND_FREEZE && freeze_ops && freeze_ops->end) freeze_ops->end(); else if (suspend_ops->end) suspend_ops->end(); } static void platform_suspend_recover(suspend_state_t state) { if (state != PM_SUSPEND_FREEZE && suspend_ops->recover) suspend_ops->recover(); } static bool platform_suspend_again(suspend_state_t state) { return state != PM_SUSPEND_FREEZE && suspend_ops->suspend_again ? suspend_ops->suspend_again() : false; } static int suspend_test(int level) { #ifdef CONFIG_PM_DEBUG Loading @@ -168,7 +215,7 @@ static int suspend_prepare(suspend_state_t state) { int error; if (need_suspend_ops(state) && (!suspend_ops || !suspend_ops->enter)) if (!sleep_state_supported(state)) return -EPERM; pm_prepare_console(); Loading Loading @@ -214,23 +261,18 @@ static int suspend_enter(suspend_state_t state, bool *wakeup) { int error; if (need_suspend_ops(state) && suspend_ops->prepare) { error = suspend_ops->prepare(); error = platform_suspend_prepare(state); if (error) goto Platform_finish; } error = dpm_suspend_end(PMSG_SUSPEND); if (error) { printk(KERN_ERR "PM: Some devices failed to power down\n"); goto Platform_finish; } if (need_suspend_ops(state) && suspend_ops->prepare_late) { error = suspend_ops->prepare_late(); error = platform_suspend_prepare_late(state); if (error) goto Platform_wake; } if (suspend_test(TEST_PLATFORM)) goto Platform_wake; Loading Loading @@ -278,15 +320,11 @@ static int suspend_enter(suspend_state_t state, bool *wakeup) ftrace_start(); Platform_wake: if (need_suspend_ops(state) && suspend_ops->wake) suspend_ops->wake(); platform_suspend_wake(state); dpm_resume_start(PMSG_RESUME); Platform_finish: if (need_suspend_ops(state) && suspend_ops->finish) suspend_ops->finish(); platform_suspend_finish(state); return error; } Loading @@ -299,18 +337,13 @@ int suspend_devices_and_enter(suspend_state_t state) int error; bool wakeup = false; if (need_suspend_ops(state) && !suspend_ops) if (!sleep_state_supported(state)) return -ENOSYS; if (need_suspend_ops(state) && suspend_ops->begin) { error = suspend_ops->begin(state); error = platform_suspend_begin(state); if (error) goto Close; } else if (state == PM_SUSPEND_FREEZE && freeze_ops && freeze_ops->begin) { error = freeze_ops->begin(); if (error) goto Close; } suspend_console(); suspend_test_start(); error = dpm_suspend_start(PMSG_SUSPEND); Loading @@ -324,25 +357,20 @@ int suspend_devices_and_enter(suspend_state_t state) do { error = suspend_enter(state, &wakeup); } while (!error && !wakeup && need_suspend_ops(state) && suspend_ops->suspend_again && suspend_ops->suspend_again()); } while (!error && !wakeup && platform_suspend_again(state)); Resume_devices: suspend_test_start(); dpm_resume_end(PMSG_RESUME); suspend_test_finish("resume devices"); resume_console(); Close: if (need_suspend_ops(state) && suspend_ops->end) suspend_ops->end(); else if (state == PM_SUSPEND_FREEZE && freeze_ops && freeze_ops->end) freeze_ops->end(); Close: platform_suspend_end(state); return error; Recover_platform: if (need_suspend_ops(state) && suspend_ops->recover) suspend_ops->recover(); platform_suspend_recover(state); goto Resume_devices; } Loading Loading @@ -395,7 +423,7 @@ static int enter_state(suspend_state_t state) printk("done.\n"); trace_suspend_resume(TPS("sync_filesystems"), 0, false); pr_debug("PM: Preparing system for %s sleep\n", pm_states[state].label); pr_debug("PM: Preparing system for %s sleep\n", pm_states[state]); error = suspend_prepare(state); if (error) goto Unlock; Loading @@ -404,7 +432,7 @@ static int enter_state(suspend_state_t state) goto Finish; trace_suspend_resume(TPS("suspend_enter"), state, false); pr_debug("PM: Entering %s sleep\n", pm_states[state].label); pr_debug("PM: Entering %s sleep\n", pm_states[state]); pm_restrict_gfp_mask(); error = suspend_devices_and_enter(state); pm_restore_gfp_mask(); Loading
kernel/power/suspend_test.c +6 −6 Original line number Diff line number Diff line Loading @@ -92,13 +92,13 @@ static void __init test_wakealarm(struct rtc_device *rtc, suspend_state_t state) } if (state == PM_SUSPEND_MEM) { printk(info_test, pm_states[state].label); printk(info_test, pm_states[state]); status = pm_suspend(state); if (status == -ENODEV) state = PM_SUSPEND_STANDBY; } if (state == PM_SUSPEND_STANDBY) { printk(info_test, pm_states[state].label); printk(info_test, pm_states[state]); status = pm_suspend(state); } if (status < 0) Loading Loading @@ -141,8 +141,8 @@ static int __init setup_test_suspend(char *value) /* "=mem" ==> "mem" */ value++; for (i = PM_SUSPEND_MIN; i < PM_SUSPEND_MAX; i++) if (!strcmp(pm_states[i].label, value)) { test_state = pm_states[i].state; if (!strcmp(pm_states[i], value)) { test_state = i; return 0; } Loading @@ -162,8 +162,8 @@ static int __init test_suspend(void) /* PM is initialized by now; is that state testable? */ if (test_state == PM_SUSPEND_ON) goto done; if (!pm_states[test_state].state) { printk(warn_bad_state, pm_states[test_state].label); if (!pm_states[test_state]) { printk(warn_bad_state, pm_states[test_state]); goto done; } Loading