Chinaunix首页 | 论坛 | 博客
  • 博客访问: 987974
  • 博文数量: 153
  • 博客积分: 4195
  • 博客等级: 上校
  • 技术积分: 2631
  • 用 户 组: 普通用户
  • 注册时间: 2009-06-22 11:32
文章存档

2012年(7)

2010年(35)

2009年(111)

分类:

2009-09-07 14:54:22

一直觉得linux源码中的/documentation是一个非常好的资源,比如讲device power management,
他认为一个驱动的电源管理应该满足两个条件:
1.当系统进入低功耗模式,驱动也能进入低功耗模式,也就是下面的System Power Management;
2.当系统处于正常运行时,用户能让驱动单独的进入低功耗模式,也就是Runtime Power Management。
这里需要我以后注意的是:
文档关于改变状态只这样说:
Writing to this file initiates a transition to the specified power state, 并没有具体说怎样write,开始我只是简单的用echo命令不行,后来查到需要用:echo -n "X" > state,注意格式,此文仅作以后备用查询。
 
Device power management encompasses two areas - the ability to save state and transition a device to a low-power state when the system is entering a low-power state; and the ability to transition a device to a low-power state while the system is running (and independently of any other power management activity).
Methods
The methods to suspend and resume devices reside in struct bus_type:
struct bus_type { ...
       int             (*suspend)(struct device * dev, pm_message_t state); int             (*resume)(struct device * dev); };
Each bus driver is responsible implementing these methods, translating the call into a bus-specific request and forwarding the call to the bus-specific drivers. For example, PCI drivers implement suspend() and resume() methods in struct pci_driver. The PCI core is simply responsible for translating the pointers to PCI-specific ones and calling the low-level driver.
This is done to a) ease transition to the new power management methods and leverage the existing PM code in various bus drivers; b) allow buses to implement generic and default PM routines for devices, and c) make the flow of execution obvious to the reader.

System Power Management
When the system enters a low-power state, the device tree is walked in a depth-first fashion to transition each device into a low-power state. The ordering of the device tree is guaranteed by the order in which devices get registered - children are never registered before their ancestors, and devices are placed at the back of the list when registered. By walking the list in reverse order, we are guaranteed to suspend devices in the proper order.
Devices are suspended once with interrupts enabled. Drivers are expected to stop I/O transactions, save device state, and place the device into a low-power state. Drivers may sleep, allocate memory, etc. at will.
Some devices are broken and will inevitably have problems powering down or disabling themselves with interrupts enabled. For these special cases, they may return -EAGAIN. This will put the device on a list to be taken care of later. When interrupts are disabled, before we enter the low-power state, their drivers are called again to put their device to sleep.
On resume, the devices that returned -EAGAIN will be called to power themselves back on with interrupts disabled. Once interrupts have been re-enabled, the rest of the drivers will be called to resume their devices. On resume, a driver is responsible for powering back on each device, restoring state, and re-enabling I/O transactions for that device.
System devices follow a slightly different API, which can be found in
 include/linux/sysdev.h
 drivers/base/sys.c
System devices will only be suspended with interrupts disabled, and after all other devices have been suspended. On resume, they will be resumed before any other devices, and also with interrupts disabled.

Runtime Power Management
Many devices are able to dynamically power down while the system is still running. This feature is useful for devices that are not being used, and can offer significant power savings on a running system.
In each device's directory, there is a 'power' directory, which contains at least a 'state' file. Reading from this file displays what power state the device is currently in. Writing to this file initiates a transition to the specified power state, which must be a decimal in the range 1-3, inclusive; or 0 for 'On'.
The PM core will call the ->suspend() method in the bus_type object that the device belongs to if the specified state is not 0, or
->resume() if it is.
Nothing will happen if the specified state is the same state the device is currently in.
If the device is already in a low-power state, and the specified state is another, but different, low-power state, the ->resume() method will first be called to power the device back on, then ->suspend() will be called again with the new state.
The driver is responsible for saving the working state of the device and putting it into the low-power state specified. If this was successful, it returns 0, and the device's power_state field is updated.
The driver must take care to know whether or not it is able to properly resume the device, including all step of reinitialization necessary. (This is the hardest part, and the one most protected by NDA'd documents).
The driver must also take care not to suspend a device that is currently in use. It is their responsibility to provide their own exclusion mechanisms.
The runtime power transition happens with interrupts enabled. If a device cannot support being powered down with interrupts, it may return -EAGAIN (as it would during a system power management transition),  but it will _not_ be called again, and the transaction will fail.
There is currently no way to know what states a device or driver supports a priori. This will change in the future.
阅读(1822) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

myleeming2009-09-07 15:55:05

关于echo还有如下文字: /sys/bus/pci/drivers/8139too/unbind" 这第一个写入命令以 "No such device" 为错误退出,而后续的 "echo -n" 命令则可以成功。这是因为内核在对总线号码进行匹配时过于严格了,通常的 "echo" 命令写入一个字符串会以一个换行符结束输出,内核所接收到的是带有这个换行符的 bus_id 字符串,将它与内核数据结构中的真正的 bus_id 字符串相比较,当然不能找到;所幸的是,这个问题在最新的 2.6.28 开发中的内核上已已经解决,它将这个比较函数改为一个特殊实现的字符串比较,自动忽略结尾处的换行符,在 2.6.28-rc6 内核上测试,不带"-n"参数的 echo 命令已经可以写入成功。