2
* syscore.c - Execution of system core operations.
4
* Copyright (C) 2011 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc.
6
* This file is released under the GPLv2.
9
#include <linux/syscore_ops.h>
10
#include <linux/mutex.h>
11
#include <linux/module.h>
12
#include <linux/interrupt.h>
14
static LIST_HEAD(syscore_ops_list);
15
static DEFINE_MUTEX(syscore_ops_lock);
18
* register_syscore_ops - Register a set of system core operations.
19
* @ops: System core operations to register.
21
void register_syscore_ops(struct syscore_ops *ops)
23
mutex_lock(&syscore_ops_lock);
24
list_add_tail(&ops->node, &syscore_ops_list);
25
mutex_unlock(&syscore_ops_lock);
27
EXPORT_SYMBOL_GPL(register_syscore_ops);
30
* unregister_syscore_ops - Unregister a set of system core operations.
31
* @ops: System core operations to unregister.
33
void unregister_syscore_ops(struct syscore_ops *ops)
35
mutex_lock(&syscore_ops_lock);
37
mutex_unlock(&syscore_ops_lock);
39
EXPORT_SYMBOL_GPL(unregister_syscore_ops);
41
#ifdef CONFIG_PM_SLEEP
43
* syscore_suspend - Execute all the registered system core suspend callbacks.
45
* This function is executed with one CPU on-line and disabled interrupts.
47
int syscore_suspend(void)
49
struct syscore_ops *ops;
52
pr_debug("Checking wakeup interrupts\n");
54
/* Return error code if there are any wakeup interrupts pending. */
55
ret = check_wakeup_irqs();
59
WARN_ONCE(!irqs_disabled(),
60
"Interrupts enabled before system core suspend.\n");
62
list_for_each_entry_reverse(ops, &syscore_ops_list, node)
65
pr_info("PM: Calling %pF\n", ops->suspend);
69
WARN_ONCE(!irqs_disabled(),
70
"Interrupts enabled after %pF\n", ops->suspend);
76
pr_err("PM: System core suspend callback %pF failed.\n", ops->suspend);
78
list_for_each_entry_continue(ops, &syscore_ops_list, node)
84
EXPORT_SYMBOL_GPL(syscore_suspend);
87
* syscore_resume - Execute all the registered system core resume callbacks.
89
* This function is executed with one CPU on-line and disabled interrupts.
91
void syscore_resume(void)
93
struct syscore_ops *ops;
95
WARN_ONCE(!irqs_disabled(),
96
"Interrupts enabled before system core resume.\n");
98
list_for_each_entry(ops, &syscore_ops_list, node)
101
pr_info("PM: Calling %pF\n", ops->resume);
103
WARN_ONCE(!irqs_disabled(),
104
"Interrupts enabled after %pF\n", ops->resume);
107
EXPORT_SYMBOL_GPL(syscore_resume);
108
#endif /* CONFIG_PM_SLEEP */
111
* syscore_shutdown - Execute all the registered system core shutdown callbacks.
113
void syscore_shutdown(void)
115
struct syscore_ops *ops;
117
mutex_lock(&syscore_ops_lock);
119
list_for_each_entry_reverse(ops, &syscore_ops_list, node)
122
pr_info("PM: Calling %pF\n", ops->shutdown);
126
mutex_unlock(&syscore_ops_lock);