Contents of /alx-src/tags/kernel26-2.6.12-alx-r9/Documentation/pm.txt
Parent Directory | Revision Log
Revision 630 -
(show annotations)
(download)
Wed Mar 4 11:03:09 2009 UTC (15 years, 6 months ago) by niro
File MIME type: text/plain
File size: 9710 byte(s)
Wed Mar 4 11:03:09 2009 UTC (15 years, 6 months ago) by niro
File MIME type: text/plain
File size: 9710 byte(s)
Tag kernel26-2.6.12-alx-r9
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); |