pm.txt
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:12k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

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