Release 4.15 kernel/power/suspend.c
/*
* kernel/power/suspend.c - Suspend to RAM and standby functionality.
*
* Copyright (c) 2003 Patrick Mochel
* Copyright (c) 2003 Open Source Development Lab
* Copyright (c) 2009 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc.
*
* This file is released under the GPLv2.
*/
#define pr_fmt(fmt) "PM: " fmt
#include <linux/string.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/console.h>
#include <linux/cpu.h>
#include <linux/cpuidle.h>
#include <linux/syscalls.h>
#include <linux/gfp.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/export.h>
#include <linux/suspend.h>
#include <linux/syscore_ops.h>
#include <linux/ftrace.h>
#include <trace/events/power.h>
#include <linux/compiler.h>
#include <linux/moduleparam.h>
#include "power.h"
const char * const pm_labels[] = {
[PM_SUSPEND_TO_IDLE] = "freeze",
[PM_SUSPEND_STANDBY] = "standby",
[PM_SUSPEND_MEM] = "mem",
};
const char *pm_states[PM_SUSPEND_MAX];
static const char * const mem_sleep_labels[] = {
[PM_SUSPEND_TO_IDLE] = "s2idle",
[PM_SUSPEND_STANDBY] = "shallow",
[PM_SUSPEND_MEM] = "deep",
};
const char *mem_sleep_states[PM_SUSPEND_MAX];
suspend_state_t mem_sleep_current = PM_SUSPEND_TO_IDLE;
suspend_state_t mem_sleep_default = PM_SUSPEND_MAX;
suspend_state_t pm_suspend_target_state;
EXPORT_SYMBOL_GPL(pm_suspend_target_state);
unsigned int pm_suspend_global_flags;
EXPORT_SYMBOL_GPL(pm_suspend_global_flags);
static const struct platform_suspend_ops *suspend_ops;
static const struct platform_s2idle_ops *s2idle_ops;
static DECLARE_WAIT_QUEUE_HEAD(s2idle_wait_head);
enum s2idle_states __read_mostly s2idle_state;
static DEFINE_SPINLOCK(s2idle_lock);
void s2idle_set_ops(const struct platform_s2idle_ops *ops)
{
lock_system_sleep();
s2idle_ops = ops;
unlock_system_sleep();
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Rafael J. Wysocki | 21 | 100.00% | 2 | 100.00% |
Total | 21 | 100.00% | 2 | 100.00% |
static void s2idle_begin(void)
{
s2idle_state = S2IDLE_STATE_NONE;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Rui Zhang | 9 | 75.00% | 1 | 50.00% |
Rafael J. Wysocki | 3 | 25.00% | 1 | 50.00% |
Total | 12 | 100.00% | 2 | 100.00% |
static void s2idle_enter(void)
{
trace_suspend_resume(TPS("machine_suspend"), PM_SUSPEND_TO_IDLE, true);
spin_lock_irq(&s2idle_lock);
if (pm_wakeup_pending())
goto out;
s2idle_state = S2IDLE_STATE_ENTER;
spin_unlock_irq(&s2idle_lock);
get_online_cpus();
cpuidle_resume();
/* Push all the CPUs into the idle loop. */
wake_up_all_idle_cpus();
/* Make the current CPU wait so it can enter the idle loop too. */
wait_event(s2idle_wait_head,
s2idle_state == S2IDLE_STATE_WAKE);
cpuidle_pause();
put_online_cpus();
spin_lock_irq(&s2idle_lock);
out:
s2idle_state = S2IDLE_STATE_NONE;
spin_unlock_irq(&s2idle_lock);
trace_suspend_resume(TPS("machine_suspend"), PM_SUSPEND_TO_IDLE, false);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Rafael J. Wysocki | 91 | 91.00% | 6 | 85.71% |
Rui Zhang | 9 | 9.00% | 1 | 14.29% |
Total | 100 | 100.00% | 7 | 100.00% |
static void s2idle_loop(void)
{
pm_pr_dbg("suspend-to-idle\n");
for (;;) {
int error;
dpm_noirq_begin();
/*
* Suspend-to-idle equals
* frozen processes + suspended devices + idle processors.
* Thus s2idle_enter() should be called right after
* all devices have been suspended.
*
* Wakeups during the noirq suspend of devices may be spurious,
* so prevent them from terminating the loop right away.
*/
error = dpm_noirq_suspend_devices(PMSG_SUSPEND);
if (!error)
s2idle_enter();
else if (error == -EBUSY && pm_wakeup_pending())
error = 0;
if (!error && s2idle_ops && s2idle_ops->wake)
s2idle_ops->wake();
dpm_noirq_resume_devices(PMSG_RESUME);
dpm_noirq_end();
if (error)
break;
if (s2idle_ops && s2idle_ops->sync)
s2idle_ops->sync();
if (pm_wakeup_pending())
break;
pm_wakeup_clear(false);
}
pm_pr_dbg("resume from suspend-to-idle\n");
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Rafael J. Wysocki | 114 | 99.13% | 7 | 87.50% |
Rui Zhang | 1 | 0.87% | 1 | 12.50% |
Total | 115 | 100.00% | 8 | 100.00% |
void s2idle_wake(void)
{
unsigned long flags;
spin_lock_irqsave(&s2idle_lock, flags);
if (s2idle_state > S2IDLE_STATE_NONE) {
s2idle_state = S2IDLE_STATE_WAKE;
wake_up(&s2idle_wait_head);
}
spin_unlock_irqrestore(&s2idle_lock, flags);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Rafael J. Wysocki | 32 | 71.11% | 2 | 66.67% |
Rui Zhang | 13 | 28.89% | 1 | 33.33% |
Total | 45 | 100.00% | 3 | 100.00% |
EXPORT_SYMBOL_GPL(s2idle_wake);
static bool valid_state(suspend_state_t state)
{
/*
* PM_SUSPEND_STANDBY and PM_SUSPEND_MEM states need low level
* support and need to be valid to the low level
* implementation, no valid callback implies that none are valid.
*/
return suspend_ops && suspend_ops->valid && suspend_ops->valid(state);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Rafael J. Wysocki | 24 | 100.00% | 1 | 100.00% |
Total | 24 | 100.00% | 1 | 100.00% |
void __init pm_states_init(void)
{
/* "mem" and "freeze" are always present in /sys/power/state. */
pm_states[PM_SUSPEND_MEM] = pm_labels[PM_SUSPEND_MEM];
pm_states[PM_SUSPEND_TO_IDLE] = pm_labels[PM_SUSPEND_TO_IDLE];
/*
* Suspend-to-idle should be supported even without any suspend_ops,
* initialize mem_sleep_states[] accordingly here.
*/
mem_sleep_states[PM_SUSPEND_TO_IDLE] = mem_sleep_labels[PM_SUSPEND_TO_IDLE];
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Rafael J. Wysocki | 24 | 60.00% | 2 | 66.67% |
Sudeep Holla | 16 | 40.00% | 1 | 33.33% |
Total | 40 | 100.00% | 3 | 100.00% |
static int __init mem_sleep_default_setup(char *str)
{
suspend_state_t state;
for (state = PM_SUSPEND_TO_IDLE; state <= PM_SUSPEND_MEM; state++)
if (mem_sleep_labels[state] &&
!strcmp(str, mem_sleep_labels[state])) {
mem_sleep_default = state;
break;
}
return 1;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Rafael J. Wysocki | 55 | 100.00% | 3 | 100.00% |
Total | 55 | 100.00% | 3 | 100.00% |
__setup("mem_sleep_default=", mem_sleep_default_setup);
/**
* suspend_set_ops - Set the global suspend method table.
* @ops: Suspend operations to use.
*/
void suspend_set_ops(const struct platform_suspend_ops *ops)
{
lock_system_sleep();
suspend_ops = ops;
if (valid_state(PM_SUSPEND_STANDBY)) {
mem_sleep_states[PM_SUSPEND_STANDBY] = mem_sleep_labels[PM_SUSPEND_STANDBY];
pm_states[PM_SUSPEND_STANDBY] = pm_labels[PM_SUSPEND_STANDBY];
if (mem_sleep_default == PM_SUSPEND_STANDBY)
mem_sleep_current = PM_SUSPEND_STANDBY;
}
if (valid_state(PM_SUSPEND_MEM)) {
mem_sleep_states[PM_SUSPEND_MEM] = mem_sleep_labels[PM_SUSPEND_MEM];
if (mem_sleep_default >= PM_SUSPEND_MEM)
mem_sleep_current = PM_SUSPEND_MEM;
}
unlock_system_sleep();
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Rafael J. Wysocki | 84 | 94.38% | 6 | 75.00% |
Srivatsa S. Bhat | 4 | 4.49% | 1 | 12.50% |
Lionel Debroux | 1 | 1.12% | 1 | 12.50% |
Total | 89 | 100.00% | 8 | 100.00% |
EXPORT_SYMBOL_GPL(suspend_set_ops);
/**
* suspend_valid_only_mem - Generic memory-only valid callback.
*
* Platform drivers that implement mem suspend only and only need to check for
* that in their .valid() callback can use this instead of rolling their own
* .valid() callback.
*/
int suspend_valid_only_mem(suspend_state_t state)
{
return state == PM_SUSPEND_MEM;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Rafael J. Wysocki | 13 | 100.00% | 1 | 100.00% |
Total | 13 | 100.00% | 1 | 100.00% |
EXPORT_SYMBOL_GPL(suspend_valid_only_mem);
static bool sleep_state_supported(suspend_state_t state)
{
return state == PM_SUSPEND_TO_IDLE || (suspend_ops && suspend_ops->enter);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Rafael J. Wysocki | 22 | 100.00% | 2 | 100.00% |
Total | 22 | 100.00% | 2 | 100.00% |
static int platform_suspend_prepare(suspend_state_t state)
{
return state != PM_SUSPEND_TO_IDLE && suspend_ops->prepare ?
suspend_ops->prepare() : 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Rafael J. Wysocki | 25 | 100.00% | 2 | 100.00% |
Total | 25 | 100.00% | 2 | 100.00% |
static int platform_suspend_prepare_late(suspend_state_t state)
{
return state == PM_SUSPEND_TO_IDLE && s2idle_ops && s2idle_ops->prepare ?
s2idle_ops->prepare() : 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Rafael J. Wysocki | 26 | 96.30% | 3 | 75.00% |
Dmitry Baryshkov | 1 | 3.70% | 1 | 25.00% |
Total | 27 | 100.00% | 4 | 100.00% |
static int platform_suspend_prepare_noirq(suspend_state_t state)
{
return state != PM_SUSPEND_TO_IDLE && suspend_ops->prepare_late ?
suspend_ops->prepare_late() : 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Rafael J. Wysocki | 25 | 100.00% | 3 | 100.00% |
Total | 25 | 100.00% | 3 | 100.00% |
static void platform_resume_noirq(suspend_state_t state)
{
if (state != PM_SUSPEND_TO_IDLE && suspend_ops->wake)
suspend_ops->wake();
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Rafael J. Wysocki | 24 | 100.00% | 3 | 100.00% |
Total | 24 | 100.00% | 3 | 100.00% |
static void platform_resume_early(suspend_state_t state)
{
if (state == PM_SUSPEND_TO_IDLE && s2idle_ops && s2idle_ops->restore)
s2idle_ops->restore();
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Rafael J. Wysocki | 25 | 96.15% | 3 | 75.00% |
Dmitry Baryshkov | 1 | 3.85% | 1 | 25.00% |
Total | 26 | 100.00% | 4 | 100.00% |
static void platform_resume_finish(suspend_state_t state)
{
if (state != PM_SUSPEND_TO_IDLE && suspend_ops->finish)
suspend_ops->finish();
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Rafael J. Wysocki | 24 | 100.00% | 3 | 100.00% |
Total | 24 | 100.00% | 3 | 100.00% |
static int platform_suspend_begin(suspend_state_t state)
{
if (state == PM_SUSPEND_TO_IDLE && s2idle_ops && s2idle_ops->begin)
return s2idle_ops->begin();
else if (suspend_ops && suspend_ops->begin)
return suspend_ops->begin(state);
else
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Rafael J. Wysocki | 46 | 95.83% | 3 | 75.00% |
Sudeep Holla | 2 | 4.17% | 1 | 25.00% |
Total | 48 | 100.00% | 4 | 100.00% |
static void platform_resume_end(suspend_state_t state)
{
if (state == PM_SUSPEND_TO_IDLE && s2idle_ops && s2idle_ops->end)
s2idle_ops->end();
else if (suspend_ops && suspend_ops->end)
suspend_ops->end();
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Rafael J. Wysocki | 38 | 95.00% | 4 | 80.00% |
Sudeep Holla | 2 | 5.00% | 1 | 20.00% |
Total | 40 | 100.00% | 5 | 100.00% |
static void platform_recover(suspend_state_t state)
{
if (state != PM_SUSPEND_TO_IDLE && suspend_ops->recover)
suspend_ops->recover();
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Rafael J. Wysocki | 23 | 95.83% | 6 | 85.71% |
Srivatsa S. Bhat | 1 | 4.17% | 1 | 14.29% |
Total | 24 | 100.00% | 7 | 100.00% |
static bool platform_suspend_again(suspend_state_t state)
{
return state != PM_SUSPEND_TO_IDLE && suspend_ops->suspend_again ?
suspend_ops->suspend_again() : false;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Rafael J. Wysocki | 25 | 100.00% | 3 | 100.00% |
Total | 25 | 100.00% | 3 | 100.00% |
#ifdef CONFIG_PM_DEBUG
static unsigned int pm_test_delay = 5;
module_param(pm_test_delay, uint, 0644);
MODULE_PARM_DESC(pm_test_delay,
"Number of seconds to wait before resuming from suspend test");
#endif
static int suspend_test(int level)
{
#ifdef CONFIG_PM_DEBUG
if (pm_test_level == level) {
pr_info("suspend debug: Waiting for %d second(s).\n",
pm_test_delay);
mdelay(pm_test_delay * 1000);
return 1;
}
#endif /* !CONFIG_PM_DEBUG */
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Rafael J. Wysocki | 36 | 83.72% | 1 | 33.33% |
Brian Norris | 6 | 13.95% | 1 | 33.33% |
Saurabh Sengar | 1 | 2.33% | 1 | 33.33% |
Total | 43 | 100.00% | 3 | 100.00% |
/**
* suspend_prepare - Prepare for entering system sleep state.
*
* Common code run for every system sleep state that can be entered (except for
* hibernation). Run suspend notifiers, allocate the "suspend" console and
* freeze processes.
*/
static int suspend_prepare(suspend_state_t state)
{
int error, nr_calls = 0;
if (!sleep_state_supported(state))
return -EPERM;
pm_prepare_console();
error = __pm_notifier_call_chain(PM_SUSPEND_PREPARE, -1, &nr_calls);
if (error) {
nr_calls--;
goto Finish;
}
trace_suspend_resume(TPS("freeze_processes"), 0, true);
error = suspend_freeze_processes();
trace_suspend_resume(TPS("freeze_processes"), 0, false);
if (!error)
return 0;
suspend_stats.failed_freeze++;
dpm_save_failed_step(SUSPEND_FREEZE);
Finish:
__pm_notifier_call_chain(PM_POST_SUSPEND, nr_calls, NULL);
pm_restore_console();
return error;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Rafael J. Wysocki | 56 | 46.67% | 2 | 28.57% |
Todd E Brandt | 24 | 20.00% | 1 | 14.29% |
Lianwei Wang | 21 | 17.50% | 1 | 14.29% |
Liu ShuoX | 10 | 8.33% | 1 | 14.29% |
Rui Zhang | 5 | 4.17% | 1 | 14.29% |
Tejun Heo | 4 | 3.33% | 1 | 14.29% |
Total | 120 | 100.00% | 7 | 100.00% |
/* default implementation */
void __weak arch_suspend_disable_irqs(void)
{
local_irq_disable();
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Rafael J. Wysocki | 8 | 72.73% | 1 | 50.00% |
Gideon Israel Dsouza | 3 | 27.27% | 1 | 50.00% |
Total | 11 | 100.00% | 2 | 100.00% |
/* default implementation */
void __weak arch_suspend_enable_irqs(void)
{
local_irq_enable();
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Rafael J. Wysocki | 8 | 72.73% | 1 | 50.00% |
Gideon Israel Dsouza | 3 | 27.27% | 1 | 50.00% |
Total | 11 | 100.00% | 2 | 100.00% |
/**
* suspend_enter - Make the system enter the given sleep state.
* @state: System sleep state to enter.
* @wakeup: Returns information that the sleep state should not be re-entered.
*
* This function should be called after devices have been suspended.
*/
static int suspend_enter(suspend_state_t state, bool *wakeup)
{
int error;
error = platform_suspend_prepare(state);
if (error)
goto Platform_finish;
error = dpm_suspend_late(PMSG_SUSPEND);
if (error) {
pr_err("late suspend of devices failed\n");
goto Platform_finish;
}
error = platform_suspend_prepare_late(state);
if (error)
goto Devices_early_resume;
if (state == PM_SUSPEND_TO_IDLE && pm_test_level != TEST_PLATFORM) {
s2idle_loop();
goto Platform_early_resume;
}
error = dpm_suspend_noirq(PMSG_SUSPEND);
if (error) {
pr_err("noirq suspend of devices failed\n");
goto Platform_early_resume;
}
error = platform_suspend_prepare_noirq(state);
if (error)
goto Platform_wake;
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 = syscore_suspend();
if (!error) {
*wakeup = pm_wakeup_pending();
if (!(suspend_test(TEST_CORE) || *wakeup)) {
trace_suspend_resume(TPS("machine_suspend"),
state, true);
error = suspend_ops->enter(state);
trace_suspend_resume(TPS("machine_suspend"),
state, false);
} else if (*wakeup) {
error = -EBUSY;
}
syscore_resume();
}
arch_suspend_enable_irqs();
BUG_ON(irqs_disabled());
Enable_cpus:
enable_nonboot_cpus();
Platform_wake:
platform_resume_noirq(state);
dpm_resume_noirq(PMSG_RESUME);
Platform_early_resume:
platform_resume_early(state);
Devices_early_resume:
dpm_resume_early(PMSG_RESUME);
Platform_finish:
platform_resume_finish(state);
return error;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Rafael J. Wysocki | 214 | 74.56% | 12 | 66.67% |
Todd E Brandt | 24 | 8.36% | 1 | 5.56% |
Rui Zhang | 22 | 7.67% | 2 | 11.11% |
Ruchi Kandoi | 13 | 4.53% | 1 | 5.56% |
MyungJoo Ham | 12 | 4.18% | 1 | 5.56% |
Saurabh Sengar | 2 | 0.70% | 1 | 5.56% |
Total | 287 | 100.00% | 18 | 100.00% |
/**
* suspend_devices_and_enter - Suspend devices and enter system sleep state.
* @state: System sleep state to enter.
*/
int suspend_devices_and_enter(suspend_state_t state)
{
int error;
bool wakeup = false;
if (!sleep_state_supported(state))
return -ENOSYS;
pm_suspend_target_state = state;
error = platform_suspend_begin(state);
if (error)
goto Close;
suspend_console();
suspend_test_start();
error = dpm_suspend_start(PMSG_SUSPEND);
if (error) {
pr_err("Some devices failed to suspend, or early wake event detected\n");
goto Recover_platform;
}
suspend_test_finish("suspend devices");
if (suspend_test(TEST_DEVICES))
goto Recover_platform;
do {
error = suspend_enter(state, &wakeup);
} while (!error && !wakeup && platform_suspend_again(state));
Resume_devices:
suspend_test_start();
dpm_resume_end(PMSG_RESUME);
suspend_test_finish("resume devices");
trace_suspend_resume(TPS("resume_console"), state, true);
resume_console();
trace_suspend_resume(TPS("resume_console"), state, false);
Close:
platform_resume_end(state);
pm_suspend_target_state = PM_SUSPEND_ON;
return error;
Recover_platform:
platform_recover(state);
goto Resume_devices;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Rafael J. Wysocki | 113 | 62.43% | 5 | 45.45% |
Todd E Brandt | 24 | 13.26% | 1 | 9.09% |
MyungJoo Ham | 23 | 12.71% | 2 | 18.18% |
Rui Zhang | 12 | 6.63% | 1 | 9.09% |
Florian Fainelli | 8 | 4.42% | 1 | 9.09% |
Bernie Thompson | 1 | 0.55% | 1 | 9.09% |
Total | 181 | 100.00% | 11 | 100.00% |
/**
* suspend_finish - Clean up before finishing the suspend sequence.
*
* Call platform code to clean up, restart processes, and free the console that
* we've allocated. This routine is not called for hibernation.
*/
static void suspend_finish(void)
{
suspend_thaw_processes();
pm_notifier_call_chain(PM_POST_SUSPEND);
pm_restore_console();
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Rafael J. Wysocki | 19 | 100.00% | 1 | 100.00% |
Total | 19 | 100.00% | 1 | 100.00% |
/**
* enter_state - Do common work needed to enter system sleep state.
* @state: System sleep state to enter.
*
* Make sure that no one else is trying to put the system into a sleep state.
* Fail if that's not the case. Otherwise, prepare for system suspend, make the
* system enter the given sleep state and clean up after wakeup.
*/
static int enter_state(suspend_state_t state)
{
int error;
trace_suspend_resume(TPS("suspend_enter"), state, true);
if (state == PM_SUSPEND_TO_IDLE) {
#ifdef CONFIG_PM_DEBUG
if (pm_test_level != TEST_NONE && pm_test_level <= TEST_CPUS) {
pr_warn("Unsupported test mode for suspend to idle, please choose none/freezer/devices/platform.\n");
return -EAGAIN;
}
#endif
} else if (!valid_state(state)) {
return -EINVAL;
}
if (!mutex_trylock(&pm_mutex))
return -EBUSY;
if (state == PM_SUSPEND_TO_IDLE)
s2idle_begin();
#ifndef CONFIG_SUSPEND_SKIP_SYNC
trace_suspend_resume(TPS("sync_filesystems"), 0, true);
pr_info("Syncing filesystems ... ");
sys_sync();
pr_cont("done.\n");
trace_suspend_resume(TPS("sync_filesystems"), 0, false);
#endif
pm_pr_dbg("Preparing system for sleep (%s)\n", mem_sleep_labels[state]);
pm_suspend_clear_flags();
error = suspend_prepare(state);
if (error)
goto Unlock;
if (suspend_test(TEST_FREEZER))
goto Finish;
trace_suspend_resume(TPS("suspend_enter"), state, false);
pm_pr_dbg("Suspending system (%s)\n", mem_sleep_labels[state]);
pm_restrict_gfp_mask();
error = suspend_devices_and_enter(state);
pm_restore_gfp_mask();
Finish:
events_check_enabled = false;
pm_pr_dbg("Finishing wakeup.\n");
suspend_finish();
Unlock:
mutex_unlock(&pm_mutex);
return error;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Rafael J. Wysocki | 164 | 70.09% | 10 | 62.50% |
Todd E Brandt | 48 | 20.51% | 1 | 6.25% |
Rui Zhang | 10 | 4.27% | 1 | 6.25% |
Len Brown | 5 | 2.14% | 1 | 6.25% |
Rajat Jain | 4 | 1.71% | 1 | 6.25% |
Jon Hunter | 2 | 0.85% | 1 | 6.25% |
Joe Perches | 1 | 0.43% | 1 | 6.25% |
Total | 234 | 100.00% | 16 | 100.00% |
/**
* pm_suspend - Externally visible function for suspending the system.
* @state: System sleep state to enter.
*
* Check if the value of @state represents one of the supported states,
* execute enter_state() and update system suspend statistics.
*/
int pm_suspend(suspend_state_t state)
{
int error;
if (state <= PM_SUSPEND_ON || state >= PM_SUSPEND_MAX)
return -EINVAL;
pr_info("suspend entry (%s)\n", mem_sleep_labels[state]);
error = enter_state(state);
if (error) {
suspend_stats.fail++;
dpm_save_failed_errno(error);
} else {
suspend_stats.success++;
}
pr_info("suspend exit\n");
return error;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Rafael J. Wysocki | 66 | 89.19% | 5 | 83.33% |
Liu ShuoX | 8 | 10.81% | 1 | 16.67% |
Total | 74 | 100.00% | 6 | 100.00% |
EXPORT_SYMBOL(pm_suspend);
Overall Contributors
Person | Tokens | Prop | Commits | CommitProp |
Rafael J. Wysocki | 1623 | 78.33% | 35 | 54.69% |
Todd E Brandt | 120 | 5.79% | 2 | 3.12% |
Rui Zhang | 91 | 4.39% | 2 | 3.12% |
Brian Norris | 37 | 1.79% | 1 | 1.56% |
MyungJoo Ham | 35 | 1.69% | 2 | 3.12% |
Lianwei Wang | 21 | 1.01% | 1 | 1.56% |
Sudeep Holla | 20 | 0.97% | 1 | 1.56% |
Matthew Garrett | 18 | 0.87% | 1 | 1.56% |
Liu ShuoX | 18 | 0.87% | 1 | 1.56% |
Florian Fainelli | 16 | 0.77% | 1 | 1.56% |
Ruchi Kandoi | 13 | 0.63% | 1 | 1.56% |
Kevin Hilman | 10 | 0.48% | 1 | 1.56% |
Gideon Israel Dsouza | 9 | 0.43% | 1 | 1.56% |
Srivatsa S. Bhat | 8 | 0.39% | 2 | 3.12% |
Tejun Heo | 7 | 0.34% | 2 | 3.12% |
Len Brown | 5 | 0.24% | 1 | 1.56% |
Rajat Jain | 4 | 0.19% | 1 | 1.56% |
Paul Gortmaker | 3 | 0.14% | 1 | 1.56% |
Saurabh Sengar | 3 | 0.14% | 1 | 1.56% |
Jean Pihet | 3 | 0.14% | 1 | 1.56% |
Dmitry Baryshkov | 2 | 0.10% | 1 | 1.56% |
Jon Hunter | 2 | 0.10% | 1 | 1.56% |
Lionel Debroux | 2 | 0.10% | 1 | 1.56% |
Joe Perches | 1 | 0.05% | 1 | 1.56% |
Bernie Thompson | 1 | 0.05% | 1 | 1.56% |
Total | 2072 | 100.00% | 64 | 100.00% |
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.