[PATCH] spinlock consolidation
[pandora-kernel.git] / Documentation / pm.txt
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);