OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [Documentation/] [pm.txt] - Blame information for rev 1275

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
               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
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
 * Device idle/use detection
95
 *
96
 * In general, drivers for all devices should call "pm_access"
97
 * before accessing the hardware (ie. before reading or modifying
98
 * a hardware register).  Request or packet-driven drivers should
99
 * additionally call "pm_dev_idle" when a device is not being used.
100
 *
101
 * Examples:
102
 * 1) A keyboard driver would call pm_access whenever a key is pressed
103
 * 2) A network driver would call pm_access before submitting
104
 *    a packet for transmit or receive and pm_dev_idle when its
105
 *    transfer and receive queues are empty.
106
 * 3) A VGA driver would call pm_access before it accesses any
107
 *    of the video controller registers
108
 *
109
 * Ultimately, the PM policy manager uses the access and idle
110
 * information to decide when to suspend individual devices
111
 * or when to suspend the entire system
112
 */
113
 
114
/*
115
 * Description: Update device access time and wake up device, if necessary
116
 *
117
 * Parameters:
118
 *   dev - PM device previously returned from pm_register
119
 *
120
 * Details: If called from an interrupt handler pm_access updates
121
 *          access time but should never need to wake up the device
122
 *          (if device is generating interrupts, it should be awake
123
 *          already)  This is important as we can not wake up
124
 *          devices from an interrupt handler.
125
 */
126
void pm_access(struct pm_dev *dev);
127
 
128
/*
129
 * Description: Identify device as currently being idle
130
 *
131
 * Parameters:
132
 *   dev - PM device previously returned from pm_register
133
 *
134
 * Details: A call to pm_dev_idle might signal to the policy manager
135
 *          to put a device to sleep.  If a new device request arrives
136
 *          between the call to pm_dev_idle and the pm_callback
137
 *          callback, the driver should fail the pm_callback request.
138
 */
139
void pm_dev_idle(struct pm_dev *dev);
140
 
141
/*
142
 * Power management request callback
143
 *
144
 * Parameters:
145
 *   dev - PM device previously returned from pm_register
146
 *   rqst - request type
147
 *   data - data, if any, associated with the request
148
 *
149
 * Returns: 0 if the request is successful
150
 *          EINVAL if the request is not supported
151
 *          EBUSY if the device is now busy and can not handle the request
152
 *          ENOMEM if the device was unable to handle the request due to memory
153
 *
154
 * Details: The device request callback will be called before the
155
 *          device/system enters a suspend state (ACPI D1-D3) or
156
 *          or after the device/system resumes from suspend (ACPI D0).
157
 *          For PM_SUSPEND, the ACPI D-state being entered is passed
158
 *          as the "data" argument to the callback.  The device
159
 *          driver should save (PM_SUSPEND) or restore (PM_RESUME)
160
 *          device context when the request callback is called.
161
 *
162
 *          Once a driver returns 0 (success) from a suspend
163
 *          request, it should not process any further requests or
164
 *          access the device hardware until a call to "pm_access" is made.
165
 */
166
typedef int (*pm_callback)(struct pm_dev *dev, pm_request_t rqst, void *data);
167
 
168
Driver Details
169
--------------
170
This is just a quick Q&A as a stopgap until a real driver writers'
171
power management guide is available.
172
 
173
Q: When is a device suspended?
174
 
175
Devices can be suspended based on direct user request (eg. laptop lid
176
closes), system power policy (eg.  sleep after 30 minutes of console
177
inactivity), or device power policy (eg. power down device after 5
178
minutes of inactivity)
179
 
180
Q: Must a driver honor a suspend request?
181
 
182
No, a driver can return -EBUSY from a suspend request and this
183
will stop the system from suspending.  When a suspend request
184
fails, all suspended devices are resumed and the system continues
185
to run.  Suspend can be retried at a later time.
186
 
187
Q: Can the driver block suspend/resume requests?
188
 
189
Yes, a driver can delay its return from a suspend or resume
190
request until the device is ready to handle requests.  It
191
is advantageous to return as quickly as possible from a
192
request as suspend/resume are done serially.
193
 
194
Q: What context is a suspend/resume initiated from?
195
 
196
A suspend or resume is initiated from a kernel thread context.
197
It is safe to block, allocate memory, initiate requests
198
or anything else you can do within the kernel.
199
 
200
Q: Will requests continue to arrive after a suspend?
201
 
202
Possibly.  It is the driver's responsibility to queue(*),
203
fail, or drop any requests that arrive after returning
204
success to a suspend request.  It is important that the
205
driver not access its device until after it receives
206
a resume request as the device's bus may no longer
207
be active.
208
 
209
(*) If a driver queues requests for processing after
210
    resume be aware that the device, network, etc.
211
    might be in a different state than at suspend time.
212
    It's probably better to drop requests unless
213
    the driver is a storage device.
214
 
215
Q: Do I have to manage bus-specific power management registers
216
 
217
No.  It is the responsibility of the bus driver to manage
218
PCI, USB, etc. power management registers.  The bus driver
219
or the power management subsystem will also enable any
220
wake-on functionality that the device has.
221
 
222
Q: So, really, what do I need to do to support suspend/resume?
223
 
224
You need to save any device context that would
225
be lost if the device was powered off and then restore
226
it at resume time.  When ACPI is active, there are
227
three levels of device suspend states; D1, D2, and D3.
228
(The suspend state is passed as the "data" argument
229
to the device callback.)  With D3, the device is powered
230
off and loses all context, D1 and D2 are shallower power
231
states and require less device context to be saved.  To
232
play it safe, just save everything at suspend and restore
233
everything at resume.
234
 
235
Q: Where do I store device context for suspend?
236
 
237
Anywhere in memory, kmalloc a buffer or store it
238
in the device descriptor.  You are guaranteed that the
239
contents of memory will be restored and accessible
240
before resume, even when the system suspends to disk.
241
 
242
Q: What do I need to do for ACPI vs. APM vs. etc?
243
 
244
Drivers need not be aware of the specific power management
245
technology that is active.  They just need to be aware
246
of when the overlying power management system requests
247
that they suspend or resume.
248
 
249
Q: What about device dependencies?
250
 
251
When a driver registers a device, the power management
252
subsystem uses the information provided to build a
253
tree of device dependencies (eg. USB device X is on
254
USB controller Y which is on PCI bus Z)  When power
255
management wants to suspend a device, it first sends
256
a suspend request to its driver, then the bus driver,
257
and so on up to the system bus.  Device resumes
258
proceed in the opposite direction.
259
 
260
Q: Who do I contact for additional information about
261
   enabling power management for my specific driver/device?
262
 
263
ACPI Development mailing list: acpi-devel@lists.sourceforge.net
264
 
265
System Interface
266
----------------
267
If you are providing new power management support to Linux (ie.
268
adding support for something like APM or ACPI), you should
269
communicate with drivers through the existing generic power
270
management interface.
271
 
272
/*
273
 * Send a request to a single device
274
 *
275
 * Parameters:
276
 *   dev - PM device previously returned from pm_register or pm_find
277
 *   rqst - request type
278
 *   data - data, if any, associated with the request
279
 *
280
 * Returns: 0 if the request is successful
281
 *          See "pm_callback" return for errors
282
 *
283
 * Details: Forward request to device callback and, if a suspend
284
 *          or resume request, update the pm_dev "state" field
285
 *          appropriately
286
 */
287
int pm_send(struct pm_dev *dev, pm_request_t rqst, void *data);
288
 
289
/*
290
 * Send a request to all devices
291
 *
292
 * Parameters:
293
 *   rqst - request type
294
 *   data - data, if any, associated with the request
295
 *
296
 * Returns: 0 if the request is successful
297
 *          See "pm_callback" return for errors
298
 *
299
 * Details: Walk list of registered devices and call pm_send
300
 *          for each until complete or an error is encountered.
301
 *          If an error is encountered for a suspend request,
302
 *          return all devices to the state they were in before
303
 *          the suspend request.
304
 */
305
int pm_send_all(pm_request_t rqst, void *data);
306
 
307
/*
308
 * Find a matching device
309
 *
310
 * Parameters:
311
 *   type - device type (PCI device, system device, or 0 to match all devices)
312
 *   from - previous match or NULL to start from the beginning
313
 *
314
 * Returns: Matching device or NULL if none found
315
 */
316
struct pm_dev *pm_find(pm_dev_t type, struct pm_dev *from);

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.