linux/kernel/power/main.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * kernel/power/main.c - PM subsystem core functionality.
 *
 * Copyright (c) 2003 Patrick Mochel
 * Copyright (c) 2003 Open Source Development Lab
 */

#include <linux/acpi.h>
#include <linux/export.h>
#include <linux/kobject.h>
#include <linux/string.h>
#include <linux/pm-trace.h>
#include <linux/workqueue.h>
#include <linux/debugfs.h>
#include <linux/seq_file.h>
#include <linux/suspend.h>
#include <linux/syscalls.h>
#include <linux/pm_runtime.h>

#include "power.h"

#ifdef CONFIG_PM_SLEEP
/*
 * The following functions are used by the suspend/hibernate code to temporarily
 * change gfp_allowed_mask in order to avoid using I/O during memory allocations
 * while devices are suspended.  To avoid races with the suspend/hibernate code,
 * they should always be called with system_transition_mutex held
 * (gfp_allowed_mask also should only be modified with system_transition_mutex
 * held, unless the suspend/hibernate code is guaranteed not to run in parallel
 * with that modification).
 */
static gfp_t saved_gfp_mask;

void pm_restore_gfp_mask(void)
{}

void pm_restrict_gfp_mask(void)
{}

unsigned int lock_system_sleep(void)
{}
EXPORT_SYMBOL_GPL();

void unlock_system_sleep(unsigned int flags)
{}
EXPORT_SYMBOL_GPL();

void ksys_sync_helper(void)
{}
EXPORT_SYMBOL_GPL();

/* Routines for PM-transition notifications */

static BLOCKING_NOTIFIER_HEAD(pm_chain_head);

int register_pm_notifier(struct notifier_block *nb)
{}
EXPORT_SYMBOL_GPL();

int unregister_pm_notifier(struct notifier_block *nb)
{}
EXPORT_SYMBOL_GPL();

int pm_notifier_call_chain_robust(unsigned long val_up, unsigned long val_down)
{}

int pm_notifier_call_chain(unsigned long val)
{}

/* If set, devices may be suspended and resumed asynchronously. */
int pm_async_enabled =;

static ssize_t pm_async_show(struct kobject *kobj, struct kobj_attribute *attr,
			     char *buf)
{}

static ssize_t pm_async_store(struct kobject *kobj, struct kobj_attribute *attr,
			      const char *buf, size_t n)
{}

power_attr();

#ifdef CONFIG_SUSPEND
static ssize_t mem_sleep_show(struct kobject *kobj, struct kobj_attribute *attr,
			      char *buf)
{}

static suspend_state_t decode_suspend_state(const char *buf, size_t n)
{}

static ssize_t mem_sleep_store(struct kobject *kobj, struct kobj_attribute *attr,
			       const char *buf, size_t n)
{}

power_attr();

/*
 * sync_on_suspend: invoke ksys_sync_helper() before suspend.
 *
 * show() returns whether ksys_sync_helper() is invoked before suspend.
 * store() accepts 0 or 1.  0 disables ksys_sync_helper() and 1 enables it.
 */
bool sync_on_suspend_enabled = !IS_ENABLED();

static ssize_t sync_on_suspend_show(struct kobject *kobj,
				   struct kobj_attribute *attr, char *buf)
{}

static ssize_t sync_on_suspend_store(struct kobject *kobj,
				    struct kobj_attribute *attr,
				    const char *buf, size_t n)
{}

power_attr();
#endif /* CONFIG_SUSPEND */

#ifdef CONFIG_PM_SLEEP_DEBUG
int pm_test_level =;

static const char * const pm_tests[__TEST_AFTER_LAST] =;

static ssize_t pm_test_show(struct kobject *kobj, struct kobj_attribute *attr,
				char *buf)
{}

static ssize_t pm_test_store(struct kobject *kobj, struct kobj_attribute *attr,
				const char *buf, size_t n)
{}

power_attr();
#endif /* CONFIG_PM_SLEEP_DEBUG */

#define SUSPEND_NR_STEPS
#define REC_FAILED_NUM

struct suspend_stats {};

static struct suspend_stats suspend_stats;
static DEFINE_MUTEX(suspend_stats_lock);

void dpm_save_failed_dev(const char *name)
{}

void dpm_save_failed_step(enum suspend_stat_step step)
{}

void dpm_save_errno(int err)
{}

void pm_report_hw_sleep_time(u64 t)
{}
EXPORT_SYMBOL_GPL();

void pm_report_max_hw_sleep(u64 t)
{}
EXPORT_SYMBOL_GPL();

static const char * const suspend_step_names[] =;

#define suspend_attr(_name, format_str)

suspend_attr();
suspend_attr();
suspend_attr();
suspend_attr();
suspend_attr();

#define suspend_step_attr(_name, step)

suspend_step_attr();
suspend_step_attr();
suspend_step_attr();
suspend_step_attr();
suspend_step_attr();
suspend_step_attr();
suspend_step_attr();
suspend_step_attr();

static ssize_t last_failed_dev_show(struct kobject *kobj,
		struct kobj_attribute *attr, char *buf)
{}
static struct kobj_attribute last_failed_dev =;

static ssize_t last_failed_errno_show(struct kobject *kobj,
		struct kobj_attribute *attr, char *buf)
{}
static struct kobj_attribute last_failed_errno =;

static ssize_t last_failed_step_show(struct kobject *kobj,
		struct kobj_attribute *attr, char *buf)
{}
static struct kobj_attribute last_failed_step =;

static struct attribute *suspend_attrs[] =;

static umode_t suspend_attr_is_visible(struct kobject *kobj, struct attribute *attr, int idx)
{}

static const struct attribute_group suspend_attr_group =;

#ifdef CONFIG_DEBUG_FS
static int suspend_stats_show(struct seq_file *s, void *unused)
{}
DEFINE_SHOW_ATTRIBUTE();

static int __init pm_debugfs_init(void)
{}

late_initcall(pm_debugfs_init);
#endif /* CONFIG_DEBUG_FS */

#endif /* CONFIG_PM_SLEEP */

#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)
{}

static ssize_t pm_print_times_store(struct kobject *kobj,
				    struct kobj_attribute *attr,
				    const char *buf, size_t n)
{}

power_attr();

static inline void pm_print_times_init(void)
{}

static ssize_t pm_wakeup_irq_show(struct kobject *kobj,
					struct kobj_attribute *attr,
					char *buf)
{}

power_attr_ro();

bool pm_debug_messages_on __read_mostly;

bool pm_debug_messages_should_print(void)
{}
EXPORT_SYMBOL_GPL();

static ssize_t pm_debug_messages_show(struct kobject *kobj,
				      struct kobj_attribute *attr, char *buf)
{}

static ssize_t pm_debug_messages_store(struct kobject *kobj,
				       struct kobj_attribute *attr,
				       const char *buf, size_t n)
{}

power_attr();

static int __init pm_debug_messages_setup(char *str)
{}
__setup();

#else /* !CONFIG_PM_SLEEP_DEBUG */
static inline void pm_print_times_init(void) {}
#endif /* CONFIG_PM_SLEEP_DEBUG */

struct kobject *power_kobj;

/*
 * state - control system sleep states.
 *
 * show() returns available sleep state labels, which may be "mem", "standby",
 * "freeze" and "disk" (hibernation).
 * See Documentation/admin-guide/pm/sleep-states.rst for a description of
 * what they mean.
 *
 * store() accepts one of those strings, translates it into the proper
 * enumerated value, and initiates a suspend transition.
 */
static ssize_t state_show(struct kobject *kobj, struct kobj_attribute *attr,
			  char *buf)
{}

static suspend_state_t decode_state(const char *buf, size_t n)
{}

static ssize_t state_store(struct kobject *kobj, struct kobj_attribute *attr,
			   const char *buf, size_t n)
{}

power_attr();

#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
 * 'wakeup_count'.  If that fails, at least one wakeup event has occurred since
 * '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)
{}

static ssize_t wakeup_count_store(struct kobject *kobj,
				struct kobj_attribute *attr,
				const char *buf, size_t n)
{}

power_attr();

#ifdef CONFIG_PM_AUTOSLEEP
static ssize_t autosleep_show(struct kobject *kobj,
			      struct kobj_attribute *attr,
			      char *buf)
{}

static ssize_t autosleep_store(struct kobject *kobj,
			       struct kobj_attribute *attr,
			       const char *buf, size_t n)
{}

power_attr();
#endif /* CONFIG_PM_AUTOSLEEP */

#ifdef CONFIG_PM_WAKELOCKS
static ssize_t wake_lock_show(struct kobject *kobj,
			      struct kobj_attribute *attr,
			      char *buf)
{}

static ssize_t wake_lock_store(struct kobject *kobj,
			       struct kobj_attribute *attr,
			       const char *buf, size_t n)
{}

power_attr();

static ssize_t wake_unlock_show(struct kobject *kobj,
				struct kobj_attribute *attr,
				char *buf)
{}

static ssize_t wake_unlock_store(struct kobject *kobj,
				 struct kobj_attribute *attr,
				 const char *buf, size_t n)
{}

power_attr();

#endif /* CONFIG_PM_WAKELOCKS */
#endif /* CONFIG_PM_SLEEP */

#ifdef CONFIG_PM_TRACE
int pm_trace_enabled;

static ssize_t pm_trace_show(struct kobject *kobj, struct kobj_attribute *attr,
			     char *buf)
{}

static ssize_t
pm_trace_store(struct kobject *kobj, struct kobj_attribute *attr,
	       const char *buf, size_t n)
{}

power_attr();

static ssize_t pm_trace_dev_match_show(struct kobject *kobj,
				       struct kobj_attribute *attr,
				       char *buf)
{}

power_attr_ro();

#endif /* CONFIG_PM_TRACE */

#ifdef CONFIG_FREEZER
static ssize_t pm_freeze_timeout_show(struct kobject *kobj,
				      struct kobj_attribute *attr, char *buf)
{}

static ssize_t pm_freeze_timeout_store(struct kobject *kobj,
				       struct kobj_attribute *attr,
				       const char *buf, size_t n)
{}

power_attr();

#endif	/* CONFIG_FREEZER*/

static struct attribute * g[] =;

static const struct attribute_group attr_group =;

static const struct attribute_group *attr_groups[] =;

struct workqueue_struct *pm_wq;
EXPORT_SYMBOL_GPL();

static int __init pm_start_workqueue(void)
{}

static int __init pm_init(void)
{}

core_initcall(pm_init);