diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /Documentation/pm.txt |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'Documentation/pm.txt')
-rw-r--r-- | Documentation/pm.txt | 251 |
1 files changed, 251 insertions, 0 deletions
diff --git a/Documentation/pm.txt b/Documentation/pm.txt new file mode 100644 index 000000000000..cc63ae18d147 --- /dev/null +++ b/Documentation/pm.txt | |||
@@ -0,0 +1,251 @@ | |||
1 | Linux Power Management Support | ||
2 | |||
3 | This document briefly describes how to use power management with your | ||
4 | Linux system and how to add power management support to Linux drivers. | ||
5 | |||
6 | APM or ACPI? | ||
7 | ------------ | ||
8 | If you have a relatively recent x86 mobile, desktop, or server system, | ||
9 | odds are it supports either Advanced Power Management (APM) or | ||
10 | Advanced Configuration and Power Interface (ACPI). ACPI is the newer | ||
11 | of the two technologies and puts power management in the hands of the | ||
12 | operating system, allowing for more intelligent power management than | ||
13 | is possible with BIOS controlled APM. | ||
14 | |||
15 | The best way to determine which, if either, your system supports is to | ||
16 | build a kernel with both ACPI and APM enabled (as of 2.3.x ACPI is | ||
17 | enabled by default). If a working ACPI implementation is found, the | ||
18 | ACPI driver will override and disable APM, otherwise the APM driver | ||
19 | will be used. | ||
20 | |||
21 | No sorry, you can not have both ACPI and APM enabled and running at | ||
22 | once. Some people with broken ACPI or broken APM implementations | ||
23 | would like to use both to get a full set of working features, but you | ||
24 | simply can not mix and match the two. Only one power management | ||
25 | interface can be in control of the machine at once. Think about it.. | ||
26 | |||
27 | User-space Daemons | ||
28 | ------------------ | ||
29 | Both APM and ACPI rely on user-space daemons, apmd and acpid | ||
30 | respectively, to be completely functional. Obtain both of these | ||
31 | daemons from your Linux distribution or from the Internet (see below) | ||
32 | and be sure that they are started sometime in the system boot process. | ||
33 | Go ahead and start both. If ACPI or APM is not available on your | ||
34 | system the associated daemon will exit gracefully. | ||
35 | |||
36 | apmd: http://worldvisions.ca/~apenwarr/apmd/ | ||
37 | acpid: http://acpid.sf.net/ | ||
38 | |||
39 | Driver Interface -- OBSOLETE, DO NOT USE! | ||
40 | ----------------************************* | ||
41 | If you are writing a new driver or maintaining an old driver, it | ||
42 | should include power management support. Without power management | ||
43 | support, a single driver may prevent a system with power management | ||
44 | capabilities from ever being able to suspend (safely). | ||
45 | |||
46 | Overview: | ||
47 | 1) Register each instance of a device with "pm_register" | ||
48 | 2) Call "pm_access" before accessing the hardware. | ||
49 | (this will ensure that the hardware is awake and ready) | ||
50 | 3) Your "pm_callback" is called before going into a | ||
51 | suspend state (ACPI D1-D3) or after resuming (ACPI D0) | ||
52 | from a suspend. | ||
53 | 4) Call "pm_dev_idle" when the device is not being used | ||
54 | (optional but will improve device idle detection) | ||
55 | 5) When unloaded, unregister the device with "pm_unregister" | ||
56 | |||
57 | /* | ||
58 | * Description: Register a device with the power-management subsystem | ||
59 | * | ||
60 | * Parameters: | ||
61 | * type - device type (PCI device, system device, ...) | ||
62 | * id - instance number or unique identifier | ||
63 | * cback - request handler callback (suspend, resume, ...) | ||
64 | * | ||
65 | * Returns: Registered PM device or NULL on error | ||
66 | * | ||
67 | * Examples: | ||
68 | * dev = pm_register(PM_SYS_DEV, PM_SYS_VGA, vga_callback); | ||
69 | * | ||
70 | * struct pci_dev *pci_dev = pci_find_dev(...); | ||
71 | * dev = pm_register(PM_PCI_DEV, PM_PCI_ID(pci_dev), callback); | ||
72 | */ | ||
73 | struct pm_dev *pm_register(pm_dev_t type, unsigned long id, pm_callback cback); | ||
74 | |||
75 | /* | ||
76 | * Description: Unregister a device with the power management subsystem | ||
77 | * | ||
78 | * Parameters: | ||
79 | * dev - PM device previously returned from pm_register | ||
80 | */ | ||
81 | void pm_unregister(struct pm_dev *dev); | ||
82 | |||
83 | /* | ||
84 | * Description: Unregister all devices with a matching callback function | ||
85 | * | ||
86 | * Parameters: | ||
87 | * cback - previously registered request callback | ||
88 | * | ||
89 | * Notes: Provided for easier porting from old APM interface | ||
90 | */ | ||
91 | void pm_unregister_all(pm_callback cback); | ||
92 | |||
93 | /* | ||
94 | * Power management request callback | ||
95 | * | ||
96 | * Parameters: | ||
97 | * dev - PM device previously returned from pm_register | ||
98 | * rqst - request type | ||
99 | * data - data, if any, associated with the request | ||
100 | * | ||
101 | * Returns: 0 if the request is successful | ||
102 | * EINVAL if the request is not supported | ||
103 | * EBUSY if the device is now busy and can not handle the request | ||
104 | * ENOMEM if the device was unable to handle the request due to memory | ||
105 | * | ||
106 | * Details: The device request callback will be called before the | ||
107 | * device/system enters a suspend state (ACPI D1-D3) or | ||
108 | * or after the device/system resumes from suspend (ACPI D0). | ||
109 | * For PM_SUSPEND, the ACPI D-state being entered is passed | ||
110 | * as the "data" argument to the callback. The device | ||
111 | * driver should save (PM_SUSPEND) or restore (PM_RESUME) | ||
112 | * device context when the request callback is called. | ||
113 | * | ||
114 | * Once a driver returns 0 (success) from a suspend | ||
115 | * request, it should not process any further requests or | ||
116 | * access the device hardware until a call to "pm_access" is made. | ||
117 | */ | ||
118 | typedef int (*pm_callback)(struct pm_dev *dev, pm_request_t rqst, void *data); | ||
119 | |||
120 | Driver Details | ||
121 | -------------- | ||
122 | This is just a quick Q&A as a stopgap until a real driver writers' | ||
123 | power management guide is available. | ||
124 | |||
125 | Q: When is a device suspended? | ||
126 | |||
127 | Devices can be suspended based on direct user request (eg. laptop lid | ||
128 | closes), system power policy (eg. sleep after 30 minutes of console | ||
129 | inactivity), or device power policy (eg. power down device after 5 | ||
130 | minutes of inactivity) | ||
131 | |||
132 | Q: Must a driver honor a suspend request? | ||
133 | |||
134 | No, a driver can return -EBUSY from a suspend request and this | ||
135 | will stop the system from suspending. When a suspend request | ||
136 | fails, all suspended devices are resumed and the system continues | ||
137 | to run. Suspend can be retried at a later time. | ||
138 | |||
139 | Q: Can the driver block suspend/resume requests? | ||
140 | |||
141 | Yes, a driver can delay its return from a suspend or resume | ||
142 | request until the device is ready to handle requests. It | ||
143 | is advantageous to return as quickly as possible from a | ||
144 | request as suspend/resume are done serially. | ||
145 | |||
146 | Q: What context is a suspend/resume initiated from? | ||
147 | |||
148 | A suspend or resume is initiated from a kernel thread context. | ||
149 | It is safe to block, allocate memory, initiate requests | ||
150 | or anything else you can do within the kernel. | ||
151 | |||
152 | Q: Will requests continue to arrive after a suspend? | ||
153 | |||
154 | Possibly. It is the driver's responsibility to queue(*), | ||
155 | fail, or drop any requests that arrive after returning | ||
156 | success to a suspend request. It is important that the | ||
157 | driver not access its device until after it receives | ||
158 | a resume request as the device's bus may no longer | ||
159 | be active. | ||
160 | |||
161 | (*) If a driver queues requests for processing after | ||
162 | resume be aware that the device, network, etc. | ||
163 | might be in a different state than at suspend time. | ||
164 | It's probably better to drop requests unless | ||
165 | the driver is a storage device. | ||
166 | |||
167 | Q: Do I have to manage bus-specific power management registers | ||
168 | |||
169 | No. It is the responsibility of the bus driver to manage | ||
170 | PCI, USB, etc. power management registers. The bus driver | ||
171 | or the power management subsystem will also enable any | ||
172 | wake-on functionality that the device has. | ||
173 | |||
174 | Q: So, really, what do I need to do to support suspend/resume? | ||
175 | |||
176 | You need to save any device context that would | ||
177 | be lost if the device was powered off and then restore | ||
178 | it at resume time. When ACPI is active, there are | ||
179 | three levels of device suspend states; D1, D2, and D3. | ||
180 | (The suspend state is passed as the "data" argument | ||
181 | to the device callback.) With D3, the device is powered | ||
182 | off and loses all context, D1 and D2 are shallower power | ||
183 | states and require less device context to be saved. To | ||
184 | play it safe, just save everything at suspend and restore | ||
185 | everything at resume. | ||
186 | |||
187 | Q: Where do I store device context for suspend? | ||
188 | |||
189 | Anywhere in memory, kmalloc a buffer or store it | ||
190 | in the device descriptor. You are guaranteed that the | ||
191 | contents of memory will be restored and accessible | ||
192 | before resume, even when the system suspends to disk. | ||
193 | |||
194 | Q: What do I need to do for ACPI vs. APM vs. etc? | ||
195 | |||
196 | Drivers need not be aware of the specific power management | ||
197 | technology that is active. They just need to be aware | ||
198 | of when the overlying power management system requests | ||
199 | that they suspend or resume. | ||
200 | |||
201 | Q: What about device dependencies? | ||
202 | |||
203 | When a driver registers a device, the power management | ||
204 | subsystem uses the information provided to build a | ||
205 | tree of device dependencies (eg. USB device X is on | ||
206 | USB controller Y which is on PCI bus Z) When power | ||
207 | management wants to suspend a device, it first sends | ||
208 | a suspend request to its driver, then the bus driver, | ||
209 | and so on up to the system bus. Device resumes | ||
210 | proceed in the opposite direction. | ||
211 | |||
212 | Q: Who do I contact for additional information about | ||
213 | enabling power management for my specific driver/device? | ||
214 | |||
215 | ACPI Development mailing list: acpi-devel@lists.sourceforge.net | ||
216 | |||
217 | System Interface -- OBSOLETE, DO NOT USE! | ||
218 | ----------------************************* | ||
219 | If you are providing new power management support to Linux (ie. | ||
220 | adding support for something like APM or ACPI), you should | ||
221 | communicate with drivers through the existing generic power | ||
222 | management interface. | ||
223 | |||
224 | /* | ||
225 | * Send a request to all devices | ||
226 | * | ||
227 | * Parameters: | ||
228 | * rqst - request type | ||
229 | * data - data, if any, associated with the request | ||
230 | * | ||
231 | * Returns: 0 if the request is successful | ||
232 | * See "pm_callback" return for errors | ||
233 | * | ||
234 | * Details: Walk list of registered devices and call pm_send | ||
235 | * for each until complete or an error is encountered. | ||
236 | * If an error is encountered for a suspend request, | ||
237 | * return all devices to the state they were in before | ||
238 | * the suspend request. | ||
239 | */ | ||
240 | int pm_send_all(pm_request_t rqst, void *data); | ||
241 | |||
242 | /* | ||
243 | * Find a matching device | ||
244 | * | ||
245 | * Parameters: | ||
246 | * type - device type (PCI device, system device, or 0 to match all devices) | ||
247 | * from - previous match or NULL to start from the beginning | ||
248 | * | ||
249 | * Returns: Matching device or NULL if none found | ||
250 | */ | ||
251 | struct pm_dev *pm_find(pm_dev_t type, struct pm_dev *from); | ||