struct dev_pm_ops {
int (*prepare) (struct device *dev);
void (*complete) (struct device *dev);
int (*suspend) (struct device *dev);
int (*resume) (struct device *dev);
int (*freeze) (struct device *dev);
int (*thaw) (struct device *dev);
int (*poweroff) (struct device *dev);
int (*restore) (struct device *dev);
int (*suspend_late) (struct device *dev);
int (*resume_early) (struct device *dev);
int (*freeze_late) (struct device *dev);
int (*thaw_early) (struct device *dev);
int (*poweroff_late) (struct device *dev);
int (*restore_early) (struct device *dev);
int (*suspend_noirq) (struct device *dev);
int (*resume_noirq) (struct device *dev);
int (*freeze_noirq) (struct device *dev);
int (*thaw_noirq) (struct device *dev);
int (*poweroff_noirq) (struct device *dev);
int (*restore_noirq) (struct device *dev);
int (*runtime_suspend)(struct device *dev);
int (*runtime_resume) (struct device *dev);
int (*runtime_idle) (struct device *dev);
};
/**
//struct dev_pm_ops - device PM callbacks
//Several device power state transitions are externally visible, affecting
//the state of pending I/O queues and (for drivers that touch hardware)
//interrupts, wakeups, DMA, and other hardware state. There may also be
//internal transitions to various low-power modes which are transparent
//to the rest of the driver stack (such as a driver that's ON gating off
//clocks which are not in active use).
一些设备电源状态转换对外是可见的,影响pending I/O队列、中断、wakeups、DMA以及其他硬件的状态。
还有一些到各种低电模式内部转换对于driver stack其余部分是透明的(例如关闭没在active状态的时钟
的驱动)
//The externally visible transitions are handled with the help of callbacks
//included in this structure in such a way that two levels of callbacks are
//involved. First, the PM core executes callbacks provided by PM domains,
//device types, classes and bus types. They are the subsystem-level callbacks
//supposed to execute callbacks provided by device drivers, although they may
//choose not to do that. If the driver callbacks are executed, they have to
//collaborate with the subsystem-level callbacks to achieve the goals
//appropriate for the given system transition, given transition phase and the
//subsystem the device belongs to.
外部可见的转换是包含在dev_pm_ops结构中的回调函数的帮助下处理的,回调函数以"两级回调"的方式包含
在dev_pm_ops中。首先PM Core执行PM domain,device type, class , bus type提供的回调函数,
(尽管他们可以选择不调用这些函数).如果驱动的回调被执行,他们必需和给定的系统级的回调函数、给定的
转换阶段以及设备所属的子系统配合,来实现给定系统转换的目标.
//@prepare: The principal role of this callback is to prevent new children of
// the device from being registered after it has returned (the driver's
// subsystem and generally the rest of the kernel is supposed to prevent
// new calls to the probe method from being made too once @prepare() has
// succeeded). If @prepare() detects a situation it cannot handle (e.g.
// registration of a child already in progress), it may return -EAGAIN, so
// that the PM core can execute it once again (e.g. after a new child has
// been registered) to recover from the race condition.
// This method is executed for all kinds of suspend transitions and is
// followed by one of the suspend callbacks: @suspend(), @freeze(), or
// @poweroff(). The PM core executes subsystem-level @prepare() for all
// devices before starting to invoke suspend callbacks for any of them, so
// generally devices may be assumed to be functional or to respond to
// runtime resume requests while @prepare() is being executed. However,
// device drivers may NOT assume anything about the availability of user
// space at that time and it is NOT valid to request firmware from within
// @prepare() (it's too late to do that). It also is NOT valid to allocate
// substantial amounts of memory from @prepare() in the GFP_KERNEL mode.
// [To work around these limitations, drivers may register suspend and
// hibernation notifiers to be executed before the freezing of tasks.]
@prepare: 这个回调函数的主要角色是防止子设备在他返回之后被注册
一旦 @prepare()函数成功调用之后,驱动所属的子系统和内核剩余的部分也被假定不会调用
probe()方法.
如果 @prepare()检测到他无法处理的状况(例如子设备的注册正在进行中),它会返回-EAGAIN,
以便PM CORE可以再次执行他(例如,新的子设备注册完成之后)使之从竟态中恢复出来。
这个方法会在各种suspend 转换中被执行,他会后跟@suspend(), @freeze()或者@poweroff()。
PM core会在为任何设备调用 @suspend之前,执行子系统级的 @prepare.
在 @prepare()执行的时候设备通常可以被认为是可操作的或者说是会响应运行时的resume请求的.
然而在此时:
1.对于用户空间的可用性,设备驱动不能假设任何东西;
2.在 @prepare()中请求firmware是无效的;
3.在 @prepare()中以GFP_KERNEL模式开辟大量内存也是无效的。
为了解决这些限制,驱动可以注册suspend()和hibernation()通知函数,这些函数会在任务
被冻结之前执行,注册和注销通知函数的接口函数为:
int register_pm_notifier(struct notifier_block *nb);
int unregister_pm_notifier(struct notifier_block *nb);
#define pm_notifier(fn, pri) { \
static struct notifier_block fn##_nb = \
{ .notifier_call = fn, .priority = pri }; \
register_pm_notifier(&fn##_nb); \
}
//@complete: Undo the changes made by @prepare(). This method is executed for
// all kinds of resume transitions, following one of the resume callbacks:
// @resume(), @thaw(), @restore(). Also called if the state transition
// fails before the driver's suspend callback: @suspend(), @freeze() or
// @poweroff(), can be executed (e.g. if the suspend callback fails for one
// of the other devices that the PM core has unsuccessfully attempted to
// suspend earlier).
// The PM core executes subsystem-level @complete() after it has executed
// the appropriate resume callbacks for all devices.
@complete:撤销 @prepare()函数所做在更改,
这个方法会在各种resume transaction中被执行,
会跟在这些resume函数之一的后面:@resume(), @thaw(), @restore();
如果状态转换在driver的suspend回调(@suspend(), @freeze() 或 @poweroff())
可以被执行前失败,该方法也会被调用.
(例如:如果suspend回调因为PM core在此之前因未能成功suspend另一个设备而失败)
PM core在为所有设备执行合适的resume之后,执行子系统级的@complete
//@suspend: Executed before putting the system into a sleep state in which the
// contents of main memory are preserved. The exact action to perform
// depends on the device's subsystem (PM domain, device type, class or bus
// type), but generally the device must be quiescent after subsystem-level
// @suspend() has returned, so that it doesn't do any I/O or DMA.
// Subsystem-level @suspend() is executed for all devices after invoking
// subsystem-level @prepare() for all of them.
@suspend: 在将系统置为sleep状态之前执行,在sleep状态下,主存的内容会被保存.
要执行的确切动作取决于设备所属的子系统(PM domain, 设备类型, class 或者 总线类型);
但是在子系统级别的 @suspend返回后设备通常必须被quiescent,所以他不做任何I/O或DMA;
在为每个设备调用子系统级别的@prepare()之后,子系统级别的@suspend会为所有设备调用;
// @suspend_late: Continue operations started by @suspend(). For a number of
// devices @suspend_late() may point to the same callback routine as the
// runtime suspend callback.
@suspend_late: @suspend()的后继操作.
对于一些设备@suspend_late()可以指向和suspend相同的回调函数。
// @resume: Executed after waking the system up from a sleep state in which the
// contents of main memory were preserved. The exact action to perform
// depends on the device's subsystem, but generally the driver is expected
// to start working again, responding to hardware events and software
// requests (the device itself may be left in a low-power state, waiting
// for a runtime resume to occur). The state of the device at the time its
// driver's @resume() callback is run depends on the platform and subsystem
// the device belongs to. On most platforms, there are no restrictions on
// availability of resources like clocks during @resume().
// Subsystem-level @resume() is executed for all devices after invoking
// subsystem-level @resume_noirq() for all of them.
@resume:在系统从sleep状态唤醒之后执行,在sleep状态下,主存的内容会被保存.
要执行的确切的动作取决于设备所属的子系统,但是通常是希望驱动再次开始工作,以响应硬件事件
和软件请求(设备本身可以保持低电状态,等待runtime resume的发生).
设备driver的 @resume()运行的时候,设备的状态取决于他所属的platform和子系统
// @resume_early: Prepare to execute @resume(). For a number of devices
// @resume_early() may point to the same callback routine as the runtime
// resume callback.
@resume_early:为@resume()的执行做准备.
多数设备的@resume_early()会指向和runtime resume相同的回调例程
// @freeze: Hibernation-specific, executed before creating a hibernation image.
// Analogous to @suspend(), but it should not enable the device to signal
// wakeup events or change its power state. The majority of subsystems
// (with the notable exception of the PCI bus type) expect the driver-level
// @freeze() to save the device settings in memory to be used by @restore()
// during the subsequent resume from hibernation.
// Subsystem-level @freeze() is executed for all devices after invoking
// subsystem-level @prepare() for all of them.
@freeze: Hibernation专属的,在创建hibernation image之前执行.
和@suspend()的相似,但是他不应该在收到信号唤醒事件的时候使能设备或者改变设备
的电源状态。
大部分子系统(主要是除了PCI总线类型)希望driver级的@freeze()在内存中保存设备
的设置,以便在后续从hibernation状态唤醒的时候由@restore()使用.
在为所有设备调用子系统级别的@prepare()之后,为所有设备执行子系统级别的@freeze()
// @freeze_late: Continue operations started by @freeze(). Analogous to
// @suspend_late(), but it should not enable the device to signal wakeup
// events or change its power state.
@freeze_late:在@freeze()之后继续执行。
和@suspend_late()相似,但是他不应该在收到唤醒事件信号后使能设备或者改变其电源状态。
// @thaw: Hibernation-specific, executed after creating a hibernation image OR
// if the creation of an image has failed. Also executed after a failing
// attempt to restore the contents of main memory from such an image.
// Undo the changes made by the preceding @freeze(), so the device can be
// operated in the same way as immediately before the call to @freeze().
// Subsystem-level @thaw() is executed for all devices after invoking
// subsystem-level @thaw_noirq() for all of them. It also may be executed
// directly after @freeze() in case of a transition error.
@thaw: Hibernation专属,在创建了一个hibernation image或者image的创建失败后执行。
也会在试图恢复一个这样的image的主存内容失败后执行。
撤销前面@freeze()所做的修改,因此设备可以被以和@freeze()相同的方式操作
子系统级别的@thaw是在为所有设备调用@thaw_noirq()之后为所有设备执行的.他还可以直接
在@freeze()之后直接执行以免(状态)转换出错.
// @thaw_early: Prepare to execute @thaw(). Undo the changes made by the
// preceding @freeze_late().
@thaw_early: 为执行@thaw()做准备,撤销前面@freeze_late()所做的变更
// @poweroff: Hibernation-specific, executed after saving a hibernation image.
// Analogous to @suspend(), but it need not save the device's settings in
// memory.
// Subsystem-level @poweroff() is executed for all devices after invoking
// subsystem-level @prepare() for all of them.
@power_off:Hibernation专属,在保存了hibernation image之后执行。
和@suspend()类似,但是他不必在内存中保存设备的设置。
子系统级别的@poweroff()是在为所有设备执行了@prepare()之后执行
// @poweroff_late: Continue operations started by @poweroff(). Analogous to
// @suspend_late(), but it need not save the device's settings in memory.
@poweroff_late:在@poweroff之后执行,和suspend_late()相似,
但是他不必在内存中保存设备的设置.
// @restore: Hibernation-specific, executed after restoring the contents of main
// memory from a hibernation image, analogous to @resume().
@restore: hibernation专属,和@resume()相似
在从hibernation image中恢复了主存内容之后执行,
// @restore_early: Prepare to execute @restore(), analogous to @resume_early().
@restore_early: 为执行@restore()做准备,是对resume_early()的模拟
// @suspend_noirq: Complete the actions started by @suspend(). Carry out any
// additional operations required for suspending the device that might be
// racing with its driver's interrupt handler, which is guaranteed not to
// run while @suspend_noirq() is being executed.
// It generally is expected that the device will be in a low-power state
// (appropriate for the target system sleep state) after subsystem-level
// @suspend_noirq() has returned successfully. If the device can generate
// system wakeup signals and is enabled to wake up the system, it should be
// configured to do so at that time. However, depending on the platform
// and device's subsystem, @suspend() or @suspend_late() may be allowed to
// put the device into the low-power state and configure it to generate
// wakeup signals, in which case it generally is not necessary to define
// @suspend_noirq().
@suspend_noriq: 完成@suspend()所发起的动作.
实现任何必须的附加的操作来suspend那些可能与其驱动的中断处理例程竞争的设备,
在 @suspend_noriq()执行的时候,设备驱动的中断处理例程将被保证不会运行。
通常是希望在系统级的 @suspend_noirq()被调用后,设备将会处于低电状态
(适于目标系统的睡眠状态),如果设备能够产生系统唤醒信号并且被使能可以唤醒系统,
他应该被配置为在那时(系统级的@suspend_noirq()被调用后)唤醒系统,然而,
这取决于平台和设备所属的子系统。
@suspend()或者 @suspend_late()可以被允许将设备置于低电状态或者配置设备
产生唤醒信号,在这种情况下通常不必定义 @suspend_noirq()。
// @resume_noirq: Prepare for the execution of @resume() by carrying out any
// operations required for resuming the device that might be racing with
// its driver's interrupt handler, which is guaranteed not to run while
// @resume_noirq() is being executed.
@resume_noirq: 通过执行resuming设备所需的可能和驱动的中断处理程序竞争的操作为@resume()
的执行做准备.
该函数执行的时候设备的中断处理程序保证不被执行。
// @freeze_noirq: Complete the actions started by @freeze(). Carry out any
// additional operations required for freezing the device that might be
// racing with its driver's interrupt handler, which is guaranteed not to
// run while @freeze_noirq() is being executed.
// The power state of the device should not be changed by either @freeze(),
// or @freeze_late(), or @freeze_noirq() and it should not be configured to
// signal system wakeup by any of these callbacks.
@freeze_noirq():完成由@freeze()发起的动作,执行冻结设备需要的并且可能会和设备的中断处理程序
竞争的任何附加的操作。
此函数执行的时候设备的中断处理被保证不会执行。
设备的电源状态不应该被@freeze()、@freeze_late()或者@freeze_noirq()改变,这些回调不应该
被配置用信号唤醒系统。
// @thaw_noirq: Prepare for the execution of @thaw() by carrying out any
// operations required for thawing the device that might be racing with its
// driver's interrupt handler, which is guaranteed not to run while
// @thaw_noirq() is being executed.
@thaw_noirq: 通过执行thawing设备所需的并且可能会与设备驱动中断处理形成竞争的任何操作
为执行@thaw()做准备。
此函数执行的时候设备的中断处理被保证不会执行。
// @poweroff_noirq: Complete the actions started by @poweroff(). Analogous to
// @suspend_noirq(), but it need not save the device's settings in memory.
@poweroff_noirq: 完成@poweroff()所发起的动作。
和 @suspend_noirq()类似,@poweroff_noirq()不需要把设备的状态保存在内存中。
// @restore_noirq: Prepare for the execution of @restore() by carrying out any
// operations required for thawing the device that might be racing with its
// driver's interrupt handler, which is guaranteed not to run while
// @restore_noirq() is being executed. Analogous to @resume_noirq().
@restore_noirq:通过执行thawing the device所需的并且可能会和设备的中断处理程序竞争的操作
为 @restore()的执行做准备。
设备的中断处理程序在@restore_noirq()运行期间被保证不会执行;
和 @resume_irq()相似。
// All of the above callbacks, except for @complete(), return error codes.
// However, the error codes returned by the resume operations, @resume(),
// @thaw(), @restore(), @resume_noirq(), @thaw_noirq(), and @restore_noirq(), do
// not cause the PM core to abort the resume transition during which they are
// returned. The error codes returned in those cases are only printed by the PM
// core to the system logs for debugging purposes. Still, it is recommended
// that drivers only return error codes from their resume methods in case of an
// unrecoverable failure (i.e. when the device being handled refuses to resume
// and becomes unusable) to allow us to modify the PM core in the future, so
// that it can avoid attempting to handle devices that failed to resume and
// their children.
上面所有的回调,除了@complete(),都返回错误码。然而,resume操作(@resume(),@thaw(),
@restore(), @resume_noriq(), @thaw_noriq()和 @restore_noirq())返回的错误码并不会
引起PM core在此期间放弃resume状态转换。尽管如此,还是推荐在出现不可恢复的错误的情况下,
驱动在方法中只返回错误码(例如:当前设备拒绝resume而变得不可用的时候)以此来允许我们将来修改
PM core,以便他可以避免尝试处理无法唤醒的设备或者子设备。
// It is allowed to unregister devices while the above callbacks are being
// executed. However, a callback routine must NOT try to unregister the device
// it was called for, although it may unregister children of that device (for
// example, if it detects that a child was unplugged while the system was
// asleep).
在上面的回调执行的时候注销设备是允许的,然而,一个回调例程一定不能试图注销他所操作的那个设备
尽管他可能会注销该设备的子设备(例如,如果他检测到在系统睡眠时一个子设备被拔出)
// Refer to Documentation/power/devices.txt for more information about the role
// of the above callbacks in the system suspend process.
参考Documentation/power/devices.txt来获取更多关于上述回调在系统suspend的过程中所扮演
的角色
// There also are callbacks related to runtime power management of devices.
// Again, these callbacks are executed by the PM core only for subsystems
// (PM domains, device types, classes and bus types) and the subsystem-level
// callbacks are supposed to invoke the driver callbacks. Moreover, the exact
// actions to be performed by a device driver's callbacks generally depend on
// the platform and subsystem the device belongs to.
还有运行时电源管理相关的的回调函数。这些回调还是由PM core来执行的,只针对子系统(PM domain
设备类型,classes和总线类型),子系统级别的回调被假定会调用设备驱动的回调。除此而外,设备驱动
执行的确切动作通常取决于设备所属的平台和子系统。
// @runtime_suspend: Prepare the device for a condition in which it won't be
// able to communicate with the CPU(s) and RAM due to power management.
// This need not mean that the device should be put into a low-power state.
// For example, if the device is behind a link which is about to be turned
// off, the device may remain at full power. If the device does go to low
// power and is capable of generating runtime wakeup events, remote wakeup
// (i.e., a hardware mechanism allowing the device to request a change of
// its power state via an interrupt) should be enabled for it.
@runtime_suspend: 为因电源管理而不能够和CPU和RAM通信的情况而准备好设备,这并不意味着设备
应该被置于低电状态。
例如,如果设备is behine a 将要被关闭的link, 设备应该保持full power.
如果设备进入低电并且能够产生运行时的唤醒事件,应该为它使能远程唤醒
(例如,一个硬件机制允许设备去请求通过一个中断去改变其电源状态)
// @runtime_resume: Put the device into the fully active state in response to a
// wakeup event generated by hardware or at the request of software. If
// necessary, put the device into the full-power state and restore its
// registers, so that it is fully operational.
@runtime_resume: 将设备置于full-active状态, 作为对硬件产生的唤醒事件或者软件请求的响应,
如果必要的话,把设备置于full-power状态并且恢复他的寄存器,所以这(将设备置于full-active
状态还是full-power状态)完全是可选的
// @runtime_idle: Device appears to be inactive and it might be put into a
// low-power state if all of the necessary conditions are satisfied. Check
// these conditions and handle the device as appropriate, possibly queueing
// a suspend request for it. The return value is ignored by the PM core.
@runtime_idle: 设备表现为inactive, 并且如果所有的必要条件都被满足的话,设备可能被置为低电状态.
检测这些条件,并且酌情处理那些可能排队了对其提出的挂起请求的设备。返回值会被PM core忽略。
// Refer to Documentation/power/runtime_pm.txt for more information about the
// role of the above callbacks in device runtime power management.
参考Documentation/power/runtime_pm.txt来获取更多上述回调在设备运行时电源管理中所扮演的角色的信息
@prepare() -->
@suspend() --> @suspend_late() --> @suspend_noriq() -->
@freeze() --> @freeze_late() --> @freeze_noirq -->
@poweroff_late() --> @poweroff() --> @poweroff_noirq() ...
...
@restore() <-- @restore_early() <-- @restore_noirq() ...
@thaw() <-- @thaw_early() <-- @thaw_noirq() <--
@resume() <-- @resume_early() <-- @resume_noirq() <--
@complete() <--
dev_pm_ops结构
最新推荐文章于 2023-07-06 00:56:04 发布