Commit | Line | Data |
---|---|---|
1da177e4 LT |
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> | |
d02f40e8 | 12 | #include <linux/resume-trace.h> |
f67d115f | 13 | #include "../base.h" |
1da177e4 LT |
14 | #include "power.h" |
15 | ||
1da177e4 LT |
16 | |
17 | /** | |
18 | * resume_device - Restore state for one device. | |
19 | * @dev: Device. | |
20 | * | |
21 | */ | |
22 | ||
23 | int resume_device(struct device * dev) | |
24 | { | |
af70316a | 25 | int error = 0; |
26 | ||
d02f40e8 LT |
27 | TRACE_DEVICE(dev); |
28 | TRACE_RESUME(0); | |
f89cbc39 | 29 | |
af70316a | 30 | down(&dev->sem); |
f89cbc39 | 31 | |
82428b62 DB |
32 | if (dev->bus && dev->bus->resume) { |
33 | dev_dbg(dev,"resuming\n"); | |
af70316a | 34 | error = dev->bus->resume(dev); |
82428b62 | 35 | } |
f89cbc39 DT |
36 | |
37 | if (!error && dev->type && dev->type->resume) { | |
38 | dev_dbg(dev,"resuming\n"); | |
39 | error = dev->type->resume(dev); | |
40 | } | |
41 | ||
42 | if (!error && dev->class && dev->class->resume) { | |
7c8265f5 LT |
43 | dev_dbg(dev,"class resume\n"); |
44 | error = dev->class->resume(dev); | |
45 | } | |
f89cbc39 | 46 | |
af70316a | 47 | up(&dev->sem); |
f89cbc39 | 48 | |
d02f40e8 | 49 | TRACE_RESUME(error); |
af70316a | 50 | return error; |
1da177e4 LT |
51 | } |
52 | ||
53 | ||
7c8265f5 LT |
54 | static int resume_device_early(struct device * dev) |
55 | { | |
56 | int error = 0; | |
1da177e4 | 57 | |
7c8265f5 LT |
58 | TRACE_DEVICE(dev); |
59 | TRACE_RESUME(0); | |
60 | if (dev->bus && dev->bus->resume_early) { | |
61 | dev_dbg(dev,"EARLY resume\n"); | |
62 | error = dev->bus->resume_early(dev); | |
63 | } | |
64 | TRACE_RESUME(error); | |
65 | return error; | |
66 | } | |
67 | ||
68 | /* | |
69 | * Resume the devices that have either not gone through | |
70 | * the late suspend, or that did go through it but also | |
71 | * went through the early resume | |
72 | */ | |
1da177e4 LT |
73 | void dpm_resume(void) |
74 | { | |
11048dcf | 75 | mutex_lock(&dpm_list_mtx); |
1da177e4 LT |
76 | while(!list_empty(&dpm_off)) { |
77 | struct list_head * entry = dpm_off.next; | |
78 | struct device * dev = to_device(entry); | |
79 | ||
80 | get_device(dev); | |
1bfba4e8 | 81 | list_move_tail(entry, &dpm_active); |
1da177e4 | 82 | |
11048dcf | 83 | mutex_unlock(&dpm_list_mtx); |
515c5357 | 84 | resume_device(dev); |
11048dcf | 85 | mutex_lock(&dpm_list_mtx); |
1da177e4 LT |
86 | put_device(dev); |
87 | } | |
11048dcf | 88 | mutex_unlock(&dpm_list_mtx); |
1da177e4 LT |
89 | } |
90 | ||
91 | ||
92 | /** | |
93 | * device_resume - Restore state of each device in system. | |
94 | * | |
95 | * Walk the dpm_off list, remove each entry, resume the device, | |
96 | * then add it to the dpm_active list. | |
97 | */ | |
98 | ||
99 | void device_resume(void) | |
100 | { | |
bb84c89f | 101 | might_sleep(); |
11048dcf | 102 | mutex_lock(&dpm_mtx); |
1da177e4 | 103 | dpm_resume(); |
11048dcf | 104 | mutex_unlock(&dpm_mtx); |
1da177e4 LT |
105 | } |
106 | ||
107 | EXPORT_SYMBOL_GPL(device_resume); | |
108 | ||
109 | ||
110 | /** | |
9de72ee5 | 111 | * dpm_power_up - Power on some devices. |
1da177e4 LT |
112 | * |
113 | * Walk the dpm_off_irq list and power each device up. This | |
114 | * is used for devices that required they be powered down with | |
9de72ee5 DT |
115 | * interrupts disabled. As devices are powered on, they are moved |
116 | * to the dpm_active list. | |
1da177e4 LT |
117 | * |
118 | * Interrupts must be disabled when calling this. | |
119 | */ | |
120 | ||
121 | void dpm_power_up(void) | |
122 | { | |
123 | while(!list_empty(&dpm_off_irq)) { | |
124 | struct list_head * entry = dpm_off_irq.next; | |
125 | struct device * dev = to_device(entry); | |
126 | ||
7c8265f5 LT |
127 | list_move_tail(entry, &dpm_off); |
128 | resume_device_early(dev); | |
1da177e4 LT |
129 | } |
130 | } | |
131 | ||
132 | ||
133 | /** | |
9de72ee5 | 134 | * device_power_up - Turn on all devices that need special attention. |
1da177e4 LT |
135 | * |
136 | * Power on system devices then devices that required we shut them down | |
137 | * with interrupts disabled. | |
138 | * Called with interrupts disabled. | |
139 | */ | |
140 | ||
141 | void device_power_up(void) | |
142 | { | |
143 | sysdev_resume(); | |
144 | dpm_power_up(); | |
145 | } | |
146 | ||
147 | EXPORT_SYMBOL_GPL(device_power_up); | |
148 | ||
149 |