The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/Documentation/pm.txt

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    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
   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);

Cache object: b8128ddf312c46f64c5a8dd530a24d58


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.