]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/base/power/resume.c
0c961068854268d384c2da354c7e12daafaaaff9
[linux-2.6-omap-h63xx.git] / drivers / base / power / resume.c
1 /*
2  * resume.c - Functions for waking devices up.
3  *
4  * Copyright (c) 2003 Patrick Mochel
5  * Copyright (c) 2003 Open Source Development Labs
6  *
7  * This file is released under the GPLv2
8  *
9  */
10
11 #include <linux/device.h>
12 #include <linux/resume-trace.h>
13 #include "../base.h"
14 #include "power.h"
15
16
17 /**
18  *      resume_device - Restore state for one device.
19  *      @dev:   Device.
20  *
21  */
22
23 int resume_device(struct device * dev)
24 {
25         int error = 0;
26
27         TRACE_DEVICE(dev);
28         TRACE_RESUME(0);
29
30         down(&dev->sem);
31
32         if (dev->parent && dev->parent->power.power_state.event) {
33                 dev_err(dev, "PM: resume from %d, parent %s still %d\n",
34                         dev->power.power_state.event,
35                         dev->parent->bus_id,
36                         dev->parent->power.power_state.event);
37         }
38
39         if (dev->bus && dev->bus->resume) {
40                 dev_dbg(dev,"resuming\n");
41                 error = dev->bus->resume(dev);
42         }
43
44         if (!error && dev->type && dev->type->resume) {
45                 dev_dbg(dev,"resuming\n");
46                 error = dev->type->resume(dev);
47         }
48
49         if (!error && dev->class && dev->class->resume) {
50                 dev_dbg(dev,"class resume\n");
51                 error = dev->class->resume(dev);
52         }
53
54         up(&dev->sem);
55
56         TRACE_RESUME(error);
57         return error;
58 }
59
60
61 static int resume_device_early(struct device * dev)
62 {
63         int error = 0;
64
65         TRACE_DEVICE(dev);
66         TRACE_RESUME(0);
67         if (dev->bus && dev->bus->resume_early) {
68                 dev_dbg(dev,"EARLY resume\n");
69                 error = dev->bus->resume_early(dev);
70         }
71         TRACE_RESUME(error);
72         return error;
73 }
74
75 /*
76  * Resume the devices that have either not gone through
77  * the late suspend, or that did go through it but also
78  * went through the early resume
79  */
80 void dpm_resume(void)
81 {
82         mutex_lock(&dpm_list_mtx);
83         while(!list_empty(&dpm_off)) {
84                 struct list_head * entry = dpm_off.next;
85                 struct device * dev = to_device(entry);
86
87                 get_device(dev);
88                 list_move_tail(entry, &dpm_active);
89
90                 mutex_unlock(&dpm_list_mtx);
91                 resume_device(dev);
92                 mutex_lock(&dpm_list_mtx);
93                 put_device(dev);
94         }
95         mutex_unlock(&dpm_list_mtx);
96 }
97
98
99 /**
100  *      device_resume - Restore state of each device in system.
101  *
102  *      Walk the dpm_off list, remove each entry, resume the device,
103  *      then add it to the dpm_active list.
104  */
105
106 void device_resume(void)
107 {
108         might_sleep();
109         mutex_lock(&dpm_mtx);
110         dpm_resume();
111         mutex_unlock(&dpm_mtx);
112 }
113
114 EXPORT_SYMBOL_GPL(device_resume);
115
116
117 /**
118  *      dpm_power_up - Power on some devices.
119  *
120  *      Walk the dpm_off_irq list and power each device up. This
121  *      is used for devices that required they be powered down with
122  *      interrupts disabled. As devices are powered on, they are moved
123  *      to the dpm_active list.
124  *
125  *      Interrupts must be disabled when calling this.
126  */
127
128 void dpm_power_up(void)
129 {
130         while(!list_empty(&dpm_off_irq)) {
131                 struct list_head * entry = dpm_off_irq.next;
132                 struct device * dev = to_device(entry);
133
134                 list_move_tail(entry, &dpm_off);
135                 resume_device_early(dev);
136         }
137 }
138
139
140 /**
141  *      device_power_up - Turn on all devices that need special attention.
142  *
143  *      Power on system devices then devices that required we shut them down
144  *      with interrupts disabled.
145  *      Called with interrupts disabled.
146  */
147
148 void device_power_up(void)
149 {
150         sysdev_resume();
151         dpm_power_up();
152 }
153
154 EXPORT_SYMBOL_GPL(device_power_up);
155
156