~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise

« back to all changes in this revision

Viewing changes to drivers/base/syscore.c

  • Committer: Bazaar Package Importer
  • Author(s): Paolo Pisati
  • Date: 2011-06-29 15:23:51 UTC
  • mfrom: (26.1.1 natty-proposed)
  • Revision ID: james.westby@ubuntu.com-20110629152351-xs96tm303d95rpbk
Tags: 3.0.0-1200.2
* Rebased against 3.0.0-6.7
* BSP from TI based on 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  syscore.c - Execution of system core operations.
 
3
 *
 
4
 *  Copyright (C) 2011 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc.
 
5
 *
 
6
 *  This file is released under the GPLv2.
 
7
 */
 
8
 
 
9
#include <linux/syscore_ops.h>
 
10
#include <linux/mutex.h>
 
11
#include <linux/module.h>
 
12
#include <linux/interrupt.h>
 
13
 
 
14
static LIST_HEAD(syscore_ops_list);
 
15
static DEFINE_MUTEX(syscore_ops_lock);
 
16
 
 
17
/**
 
18
 * register_syscore_ops - Register a set of system core operations.
 
19
 * @ops: System core operations to register.
 
20
 */
 
21
void register_syscore_ops(struct syscore_ops *ops)
 
22
{
 
23
        mutex_lock(&syscore_ops_lock);
 
24
        list_add_tail(&ops->node, &syscore_ops_list);
 
25
        mutex_unlock(&syscore_ops_lock);
 
26
}
 
27
EXPORT_SYMBOL_GPL(register_syscore_ops);
 
28
 
 
29
/**
 
30
 * unregister_syscore_ops - Unregister a set of system core operations.
 
31
 * @ops: System core operations to unregister.
 
32
 */
 
33
void unregister_syscore_ops(struct syscore_ops *ops)
 
34
{
 
35
        mutex_lock(&syscore_ops_lock);
 
36
        list_del(&ops->node);
 
37
        mutex_unlock(&syscore_ops_lock);
 
38
}
 
39
EXPORT_SYMBOL_GPL(unregister_syscore_ops);
 
40
 
 
41
#ifdef CONFIG_PM_SLEEP
 
42
/**
 
43
 * syscore_suspend - Execute all the registered system core suspend callbacks.
 
44
 *
 
45
 * This function is executed with one CPU on-line and disabled interrupts.
 
46
 */
 
47
int syscore_suspend(void)
 
48
{
 
49
        struct syscore_ops *ops;
 
50
        int ret = 0;
 
51
 
 
52
        pr_debug("Checking wakeup interrupts\n");
 
53
 
 
54
        /* Return error code if there are any wakeup interrupts pending. */
 
55
        ret = check_wakeup_irqs();
 
56
        if (ret)
 
57
                return ret;
 
58
 
 
59
        WARN_ONCE(!irqs_disabled(),
 
60
                "Interrupts enabled before system core suspend.\n");
 
61
 
 
62
        list_for_each_entry_reverse(ops, &syscore_ops_list, node)
 
63
                if (ops->suspend) {
 
64
                        if (initcall_debug)
 
65
                                pr_info("PM: Calling %pF\n", ops->suspend);
 
66
                        ret = ops->suspend();
 
67
                        if (ret)
 
68
                                goto err_out;
 
69
                        WARN_ONCE(!irqs_disabled(),
 
70
                                "Interrupts enabled after %pF\n", ops->suspend);
 
71
                }
 
72
 
 
73
        return 0;
 
74
 
 
75
 err_out:
 
76
        pr_err("PM: System core suspend callback %pF failed.\n", ops->suspend);
 
77
 
 
78
        list_for_each_entry_continue(ops, &syscore_ops_list, node)
 
79
                if (ops->resume)
 
80
                        ops->resume();
 
81
 
 
82
        return ret;
 
83
}
 
84
EXPORT_SYMBOL_GPL(syscore_suspend);
 
85
 
 
86
/**
 
87
 * syscore_resume - Execute all the registered system core resume callbacks.
 
88
 *
 
89
 * This function is executed with one CPU on-line and disabled interrupts.
 
90
 */
 
91
void syscore_resume(void)
 
92
{
 
93
        struct syscore_ops *ops;
 
94
 
 
95
        WARN_ONCE(!irqs_disabled(),
 
96
                "Interrupts enabled before system core resume.\n");
 
97
 
 
98
        list_for_each_entry(ops, &syscore_ops_list, node)
 
99
                if (ops->resume) {
 
100
                        if (initcall_debug)
 
101
                                pr_info("PM: Calling %pF\n", ops->resume);
 
102
                        ops->resume();
 
103
                        WARN_ONCE(!irqs_disabled(),
 
104
                                "Interrupts enabled after %pF\n", ops->resume);
 
105
                }
 
106
}
 
107
EXPORT_SYMBOL_GPL(syscore_resume);
 
108
#endif /* CONFIG_PM_SLEEP */
 
109
 
 
110
/**
 
111
 * syscore_shutdown - Execute all the registered system core shutdown callbacks.
 
112
 */
 
113
void syscore_shutdown(void)
 
114
{
 
115
        struct syscore_ops *ops;
 
116
 
 
117
        mutex_lock(&syscore_ops_lock);
 
118
 
 
119
        list_for_each_entry_reverse(ops, &syscore_ops_list, node)
 
120
                if (ops->shutdown) {
 
121
                        if (initcall_debug)
 
122
                                pr_info("PM: Calling %pF\n", ops->shutdown);
 
123
                        ops->shutdown();
 
124
                }
 
125
 
 
126
        mutex_unlock(&syscore_ops_lock);
 
127
}