URL
https://opencores.org/ocsvn/test_project/test_project/trunk
Subversion Repositories test_project
[/] [test_project/] [trunk/] [linux_sd_driver/] [Documentation/] [pm.txt] - Rev 62
Compare with Previous | Blame | View Log
Linux Power Management SupportThis document briefly describes how to use power management with yourLinux system and how to add power management support to Linux drivers.APM or ACPI?------------If you have a relatively recent x86 mobile, desktop, or server system,odds are it supports either Advanced Power Management (APM) orAdvanced Configuration and Power Interface (ACPI). ACPI is the newerof the two technologies and puts power management in the hands of theoperating system, allowing for more intelligent power management thanis possible with BIOS controlled APM.The best way to determine which, if either, your system supports is tobuild a kernel with both ACPI and APM enabled (as of 2.3.x ACPI isenabled by default). If a working ACPI implementation is found, theACPI driver will override and disable APM, otherwise the APM driverwill be used.No, sorry, you cannot have both ACPI and APM enabled and running atonce. Some people with broken ACPI or broken APM implementationswould like to use both to get a full set of working features, but yousimply cannot mix and match the two. Only one power managementinterface can be in control of the machine at once. Think about it..User-space Daemons------------------Both APM and ACPI rely on user-space daemons, apmd and acpidrespectively, to be completely functional. Obtain both of thesedaemons from your Linux distribution or from the Internet (see below)and be sure that they are started sometime in the system boot process.Go ahead and start both. If ACPI or APM is not available on yoursystem the associated daemon will exit gracefully.apmd: http://worldvisions.ca/~apenwarr/apmd/acpid: http://acpid.sf.net/Driver Interface -- OBSOLETE, DO NOT USE!----------------*************************Note: pm_register(), pm_access(), pm_dev_idle() and friends areobsolete. Please do not use them. Instead you should properly hookyour driver into the driver model, and use its suspend()/resume()callbacks to do this kind of stuff.If you are writing a new driver or maintaining an old driver, itshould include power management support. Without power managementsupport, a single driver may prevent a system with power managementcapabilities from ever being able to suspend (safely).Overview:1) Register each instance of a device with "pm_register"2) Call "pm_access" before accessing the hardware.(this will ensure that the hardware is awake and ready)3) Your "pm_callback" is called before going into asuspend state (ACPI D1-D3) or after resuming (ACPI D0)from a suspend.4) Call "pm_dev_idle" when the device is not being used(optional but will improve device idle detection)5) When unloaded, unregister the device with "pm_unregister"/** Description: Register a device with the power-management subsystem** Parameters:* type - device type (PCI device, system device, ...)* id - instance number or unique identifier* cback - request handler callback (suspend, resume, ...)** Returns: Registered PM device or NULL on error** Examples:* dev = pm_register(PM_SYS_DEV, PM_SYS_VGA, vga_callback);** struct pci_dev *pci_dev = pci_find_dev(...);* dev = pm_register(PM_PCI_DEV, PM_PCI_ID(pci_dev), callback);*/struct pm_dev *pm_register(pm_dev_t type, unsigned long id, pm_callback cback);/** Description: Unregister a device with the power management subsystem** Parameters:* dev - PM device previously returned from pm_register*/void pm_unregister(struct pm_dev *dev);/** Description: Unregister all devices with a matching callback function** Parameters:* cback - previously registered request callback** Notes: Provided for easier porting from old APM interface*/void pm_unregister_all(pm_callback cback);/** Power management request callback** Parameters:* dev - PM device previously returned from pm_register* rqst - request type* data - data, if any, associated with the request** Returns: 0 if the request is successful* EINVAL if the request is not supported* EBUSY if the device is now busy and cannot handle the request* ENOMEM if the device was unable to handle the request due to memory** Details: The device request callback will be called before the* device/system enters a suspend state (ACPI D1-D3) or* or after the device/system resumes from suspend (ACPI D0).* For PM_SUSPEND, the ACPI D-state being entered is passed* as the "data" argument to the callback. The device* driver should save (PM_SUSPEND) or restore (PM_RESUME)* device context when the request callback is called.** Once a driver returns 0 (success) from a suspend* request, it should not process any further requests or* access the device hardware until a call to "pm_access" is made.*/typedef int (*pm_callback)(struct pm_dev *dev, pm_request_t rqst, void *data);Driver Details--------------This is just a quick Q&A as a stopgap until a real driver writers'power management guide is available.Q: When is a device suspended?Devices can be suspended based on direct user request (eg. laptop lidcloses), system power policy (eg. sleep after 30 minutes of consoleinactivity), or device power policy (eg. power down device after 5minutes of inactivity)Q: Must a driver honor a suspend request?No, a driver can return -EBUSY from a suspend request and thiswill stop the system from suspending. When a suspend requestfails, all suspended devices are resumed and the system continuesto run. Suspend can be retried at a later time.Q: Can the driver block suspend/resume requests?Yes, a driver can delay its return from a suspend or resumerequest until the device is ready to handle requests. Itis advantageous to return as quickly as possible from arequest as suspend/resume are done serially.Q: What context is a suspend/resume initiated from?A suspend or resume is initiated from a kernel thread context.It is safe to block, allocate memory, initiate requestsor anything else you can do within the kernel.Q: Will requests continue to arrive after a suspend?Possibly. It is the driver's responsibility to queue(*),fail, or drop any requests that arrive after returningsuccess to a suspend request. It is important that thedriver not access its device until after it receivesa resume request as the device's bus may no longerbe active.(*) If a driver queues requests for processing afterresume be aware that the device, network, etc.might be in a different state than at suspend time.It's probably better to drop requests unlessthe driver is a storage device.Q: Do I have to manage bus-specific power management registersNo. It is the responsibility of the bus driver to managePCI, USB, etc. power management registers. The bus driveror the power management subsystem will also enable anywake-on functionality that the device has.Q: So, really, what do I need to do to support suspend/resume?You need to save any device context that wouldbe lost if the device was powered off and then restoreit at resume time. When ACPI is active, there arethree levels of device suspend states; D1, D2, and D3.(The suspend state is passed as the "data" argumentto the device callback.) With D3, the device is poweredoff and loses all context, D1 and D2 are shallower powerstates and require less device context to be saved. Toplay it safe, just save everything at suspend and restoreeverything at resume.Q: Where do I store device context for suspend?Anywhere in memory, kmalloc a buffer or store itin the device descriptor. You are guaranteed that thecontents of memory will be restored and accessiblebefore resume, even when the system suspends to disk.Q: What do I need to do for ACPI vs. APM vs. etc?Drivers need not be aware of the specific power managementtechnology that is active. They just need to be awareof when the overlying power management system requeststhat they suspend or resume.Q: What about device dependencies?When a driver registers a device, the power managementsubsystem uses the information provided to build atree of device dependencies (eg. USB device X is onUSB controller Y which is on PCI bus Z) When powermanagement wants to suspend a device, it first sendsa suspend request to its driver, then the bus driver,and so on up to the system bus. Device resumesproceed in the opposite direction.Q: Who do I contact for additional information aboutenabling power management for my specific driver/device?ACPI Development mailing list: linux-acpi@vger.kernel.orgSystem Interface -- OBSOLETE, DO NOT USE!----------------*************************If you are providing new power management support to Linux (ie.adding support for something like APM or ACPI), you shouldcommunicate with drivers through the existing generic powermanagement interface./** Send a request to all devices** Parameters:* rqst - request type* data - data, if any, associated with the request** Returns: 0 if the request is successful* See "pm_callback" return for errors** Details: Walk list of registered devices and call pm_send* for each until complete or an error is encountered.* If an error is encountered for a suspend request,* return all devices to the state they were in before* the suspend request.*/int pm_send_all(pm_request_t rqst, void *data);/** Find a matching device** Parameters:* type - device type (PCI device, system device, or 0 to match all devices)* from - previous match or NULL to start from the beginning** Returns: Matching device or NULL if none found*/struct pm_dev *pm_find(pm_dev_t type, struct pm_dev *from);
