| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 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 |  | 
| Matt LaPlante | 84eb8d0 | 2006-10-03 22:53:09 +0200 | [diff] [blame] | 21 | No, sorry, you cannot have both ACPI and APM enabled and running at | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 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 | 
| Matt LaPlante | 84eb8d0 | 2006-10-03 22:53:09 +0200 | [diff] [blame] | 24 | simply cannot mix and match the two.  Only one power management | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 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 | ----------------************************* | 
| Pavel Machek | f4f9eb0 | 2005-09-13 01:25:46 -0700 | [diff] [blame] | 41 |  | 
 | 42 | Note: pm_register(), pm_access(), pm_dev_idle() and friends are | 
 | 43 | obsolete. Please do not use them. Instead you should properly hook | 
 | 44 | your driver into the driver model, and use its suspend()/resume() | 
 | 45 | callbacks to do this kind of stuff. | 
 | 46 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 47 | If you are writing a new driver or maintaining an old driver, it | 
 | 48 | should include power management support.  Without power management | 
 | 49 | support, a single driver may prevent a system with power management | 
 | 50 | capabilities from ever being able to suspend (safely). | 
 | 51 |  | 
 | 52 | Overview: | 
 | 53 | 1) Register each instance of a device with "pm_register" | 
 | 54 | 2) Call "pm_access" before accessing the hardware. | 
 | 55 |    (this will ensure that the hardware is awake and ready) | 
 | 56 | 3) Your "pm_callback" is called before going into a | 
 | 57 |    suspend state (ACPI D1-D3) or after resuming (ACPI D0) | 
 | 58 |    from a suspend. | 
 | 59 | 4) Call "pm_dev_idle" when the device is not being used | 
 | 60 |    (optional but will improve device idle detection) | 
 | 61 | 5) When unloaded, unregister the device with "pm_unregister" | 
 | 62 |  | 
 | 63 | /* | 
 | 64 |  * Description: Register a device with the power-management subsystem | 
 | 65 |  * | 
 | 66 |  * Parameters: | 
 | 67 |  *   type - device type (PCI device, system device, ...) | 
 | 68 |  *   id - instance number or unique identifier | 
 | 69 |  *   cback - request handler callback (suspend, resume, ...) | 
 | 70 |  * | 
 | 71 |  * Returns: Registered PM device or NULL on error | 
 | 72 |  * | 
 | 73 |  * Examples: | 
 | 74 |  *   dev = pm_register(PM_SYS_DEV, PM_SYS_VGA, vga_callback); | 
 | 75 |  * | 
 | 76 |  *   struct pci_dev *pci_dev = pci_find_dev(...); | 
 | 77 |  *   dev = pm_register(PM_PCI_DEV, PM_PCI_ID(pci_dev), callback); | 
 | 78 |  */ | 
 | 79 | struct pm_dev *pm_register(pm_dev_t type, unsigned long id, pm_callback cback); | 
 | 80 |  | 
 | 81 | /* | 
 | 82 |  * Description: Unregister a device with the power management subsystem | 
 | 83 |  * | 
 | 84 |  * Parameters: | 
 | 85 |  *   dev - PM device previously returned from pm_register | 
 | 86 |  */ | 
 | 87 | void pm_unregister(struct pm_dev *dev); | 
 | 88 |  | 
 | 89 | /* | 
 | 90 |  * Description: Unregister all devices with a matching callback function | 
 | 91 |  * | 
 | 92 |  * Parameters: | 
 | 93 |  *   cback - previously registered request callback | 
 | 94 |  * | 
 | 95 |  * Notes: Provided for easier porting from old APM interface | 
 | 96 |  */ | 
 | 97 | void pm_unregister_all(pm_callback cback); | 
 | 98 |  | 
 | 99 | /* | 
 | 100 |  * Power management request callback | 
 | 101 |  * | 
 | 102 |  * Parameters: | 
 | 103 |  *   dev - PM device previously returned from pm_register | 
 | 104 |  *   rqst - request type | 
 | 105 |  *   data - data, if any, associated with the request | 
 | 106 |  * | 
 | 107 |  * Returns: 0 if the request is successful | 
 | 108 |  *          EINVAL if the request is not supported | 
| Matt LaPlante | 84eb8d0 | 2006-10-03 22:53:09 +0200 | [diff] [blame] | 109 |  *          EBUSY if the device is now busy and cannot handle the request | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 110 |  *          ENOMEM if the device was unable to handle the request due to memory | 
 | 111 |  *           | 
 | 112 |  * Details: The device request callback will be called before the | 
 | 113 |  *          device/system enters a suspend state (ACPI D1-D3) or | 
 | 114 |  *          or after the device/system resumes from suspend (ACPI D0). | 
 | 115 |  *          For PM_SUSPEND, the ACPI D-state being entered is passed | 
 | 116 |  *          as the "data" argument to the callback.  The device | 
 | 117 |  *          driver should save (PM_SUSPEND) or restore (PM_RESUME) | 
 | 118 |  *          device context when the request callback is called. | 
 | 119 |  * | 
 | 120 |  *          Once a driver returns 0 (success) from a suspend | 
 | 121 |  *          request, it should not process any further requests or | 
 | 122 |  *          access the device hardware until a call to "pm_access" is made. | 
 | 123 |  */ | 
 | 124 | typedef int (*pm_callback)(struct pm_dev *dev, pm_request_t rqst, void *data); | 
 | 125 |  | 
 | 126 | Driver Details | 
 | 127 | -------------- | 
 | 128 | This is just a quick Q&A as a stopgap until a real driver writers' | 
 | 129 | power management guide is available. | 
 | 130 |  | 
 | 131 | Q: When is a device suspended? | 
 | 132 |  | 
 | 133 | Devices can be suspended based on direct user request (eg. laptop lid | 
 | 134 | closes), system power policy (eg.  sleep after 30 minutes of console | 
 | 135 | inactivity), or device power policy (eg. power down device after 5 | 
 | 136 | minutes of inactivity) | 
 | 137 |  | 
 | 138 | Q: Must a driver honor a suspend request? | 
 | 139 |  | 
 | 140 | No, a driver can return -EBUSY from a suspend request and this | 
 | 141 | will stop the system from suspending.  When a suspend request | 
 | 142 | fails, all suspended devices are resumed and the system continues | 
 | 143 | to run.  Suspend can be retried at a later time. | 
 | 144 |  | 
 | 145 | Q: Can the driver block suspend/resume requests? | 
 | 146 |  | 
 | 147 | Yes, a driver can delay its return from a suspend or resume | 
 | 148 | request until the device is ready to handle requests.  It | 
 | 149 | is advantageous to return as quickly as possible from a | 
 | 150 | request as suspend/resume are done serially. | 
 | 151 |  | 
 | 152 | Q: What context is a suspend/resume initiated from? | 
 | 153 |  | 
 | 154 | A suspend or resume is initiated from a kernel thread context. | 
 | 155 | It is safe to block, allocate memory, initiate requests | 
 | 156 | or anything else you can do within the kernel. | 
 | 157 |  | 
 | 158 | Q: Will requests continue to arrive after a suspend? | 
 | 159 |  | 
 | 160 | Possibly.  It is the driver's responsibility to queue(*), | 
 | 161 | fail, or drop any requests that arrive after returning | 
 | 162 | success to a suspend request.  It is important that the | 
 | 163 | driver not access its device until after it receives | 
 | 164 | a resume request as the device's bus may no longer | 
 | 165 | be active. | 
 | 166 |  | 
 | 167 | (*) If a driver queues requests for processing after | 
 | 168 |     resume be aware that the device, network, etc. | 
 | 169 |     might be in a different state than at suspend time. | 
 | 170 |     It's probably better to drop requests unless | 
 | 171 |     the driver is a storage device. | 
 | 172 |  | 
 | 173 | Q: Do I have to manage bus-specific power management registers | 
 | 174 |  | 
 | 175 | No.  It is the responsibility of the bus driver to manage | 
 | 176 | PCI, USB, etc. power management registers.  The bus driver | 
 | 177 | or the power management subsystem will also enable any | 
 | 178 | wake-on functionality that the device has. | 
 | 179 |  | 
 | 180 | Q: So, really, what do I need to do to support suspend/resume? | 
 | 181 |  | 
 | 182 | You need to save any device context that would | 
 | 183 | be lost if the device was powered off and then restore | 
 | 184 | it at resume time.  When ACPI is active, there are | 
 | 185 | three levels of device suspend states; D1, D2, and D3. | 
 | 186 | (The suspend state is passed as the "data" argument | 
 | 187 | to the device callback.)  With D3, the device is powered | 
 | 188 | off and loses all context, D1 and D2 are shallower power | 
 | 189 | states and require less device context to be saved.  To | 
 | 190 | play it safe, just save everything at suspend and restore | 
 | 191 | everything at resume. | 
 | 192 |  | 
 | 193 | Q: Where do I store device context for suspend? | 
 | 194 |  | 
 | 195 | Anywhere in memory, kmalloc a buffer or store it | 
 | 196 | in the device descriptor.  You are guaranteed that the | 
 | 197 | contents of memory will be restored and accessible | 
 | 198 | before resume, even when the system suspends to disk. | 
 | 199 |  | 
 | 200 | Q: What do I need to do for ACPI vs. APM vs. etc? | 
 | 201 |  | 
 | 202 | Drivers need not be aware of the specific power management | 
 | 203 | technology that is active.  They just need to be aware | 
 | 204 | of when the overlying power management system requests | 
 | 205 | that they suspend or resume. | 
 | 206 |  | 
 | 207 | Q: What about device dependencies? | 
 | 208 |  | 
 | 209 | When a driver registers a device, the power management | 
 | 210 | subsystem uses the information provided to build a | 
 | 211 | tree of device dependencies (eg. USB device X is on | 
 | 212 | USB controller Y which is on PCI bus Z)  When power | 
 | 213 | management wants to suspend a device, it first sends | 
 | 214 | a suspend request to its driver, then the bus driver, | 
 | 215 | and so on up to the system bus.  Device resumes | 
 | 216 | proceed in the opposite direction. | 
 | 217 |  | 
 | 218 | Q: Who do I contact for additional information about | 
 | 219 |    enabling power management for my specific driver/device? | 
 | 220 |  | 
| Len Brown | 036d25f | 2006-01-06 16:19:26 -0500 | [diff] [blame] | 221 | ACPI Development mailing list: linux-acpi@vger.kernel.org | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 222 |  | 
 | 223 | System Interface -- OBSOLETE, DO NOT USE! | 
 | 224 | ----------------************************* | 
 | 225 | If you are providing new power management support to Linux (ie. | 
 | 226 | adding support for something like APM or ACPI), you should | 
 | 227 | communicate with drivers through the existing generic power | 
 | 228 | management interface. | 
 | 229 |  | 
 | 230 | /* | 
 | 231 |  * Send a request to all devices | 
 | 232 |  * | 
 | 233 |  * Parameters: | 
 | 234 |  *   rqst - request type | 
 | 235 |  *   data - data, if any, associated with the request | 
 | 236 |  * | 
 | 237 |  * Returns: 0 if the request is successful | 
 | 238 |  *          See "pm_callback" return for errors | 
 | 239 |  * | 
 | 240 |  * Details: Walk list of registered devices and call pm_send | 
 | 241 |  *          for each until complete or an error is encountered. | 
 | 242 |  *          If an error is encountered for a suspend request, | 
 | 243 |  *          return all devices to the state they were in before | 
 | 244 |  *          the suspend request. | 
 | 245 |  */ | 
 | 246 | int pm_send_all(pm_request_t rqst, void *data); | 
 | 247 |  | 
 | 248 | /* | 
 | 249 |  * Find a matching device | 
 | 250 |  * | 
 | 251 |  * Parameters: | 
 | 252 |  *   type - device type (PCI device, system device, or 0 to match all devices) | 
 | 253 |  *   from - previous match or NULL to start from the beginning | 
 | 254 |  * | 
 | 255 |  * Returns: Matching device or NULL if none found | 
 | 256 |  */ | 
 | 257 | struct pm_dev *pm_find(pm_dev_t type, struct pm_dev *from); |