Linux Power Management!!! in due to follow specific use cases to Discuss
Source Framework::
API Layer :: used to provide User space, which used to shutdown, restart, hibernate, suspend using sysfs .
PM Core :: Major modifications as on kernel ref: source code framework.
PM driver :: Again 2 Layers Architecture dependent and Specific Driver Framework.
Main stream linux kernel shutdown and restart system calls.
Ahhh!!! After shutdown, sooner or later will boot , so restart shutdown is a special process.
/*
* Reboot system call: for obvious reasons only root may call it,
* and even root needs to set up some magic numbers in the registers
* so that some mistake won't make this reboot the whole machine.
* You can also set the meaning of the ctrl-alt-del-key here.
*
* reboot doesn't sync: do that yourself before calling this.
*/
SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd,
void __user *, arg)
Source Framework::
- kernel/power/ *
- drivers/power/
- drivers/base/power/*
- drivers/cpuidle/*
- drivers/cpufreq/* <<<<<<------1st 2.6.11="" 2006="" addition="" in="" li="" nbsp="" place=""> ------1st>
- drivers/devfreq/*
- include/linux/power_supply.h
- include/linux/cpuidle.h
- include/linux/cpufreq.h
- include/linux/cpu_pm.h
- include/linux/device.h
- include/linux/pm.h
- include/linux/pm domain.h
- include/linux/pm runtime.h
- include/linux/pm wakeup.h
- include/linux/suspend.h
- Documentation/power/*.txt
#define container_of(ptr, type, member) (type *)((char *)ptr - (char *)&((type *)0)->member)
最后将程序改为
1 #include
2 #include
3 #include
4
5 #define container_of(ptr, type, member) (type *)((char *)ptr - (char *)&((type *)0)->member)
6
7 typedef struct {
8 int a;
9 int b;
10 int c;
11 }hehe;
12
13 int main(int argc, char *argv[])
14 {
15 hehe hoho;
16 hehe *haha;
17 hehe *hihi;
18 int *ptr;
19
20 hoho.a = 1;
21 hoho.b = 2;
22 hoho.c = 3;
23
24 hihi = &hoho;
25
26 ptr = &hoho.b;
27
28 printf("ptr = %d, hihi = 0xx\n", *ptr, hihi);
29
30 haha = container_of(ptr, hehe, b);
31 printf("a = %d, b = %d, c = %d \n", haha->a, haha->b, haha->c);
32 }
33
编译后运行:
$ ./2
ptr = 2, hihi = 0xbfe14b5c
a = 1, b = 2, c = 3
Major 3 layers ::最后将程序改为
1 #include
2 #include
3 #include
4
5 #define container_of(ptr, type, member) (type *)((char *)ptr - (char *)&((type *)0)->member)
6
7 typedef struct {
8
9
10
11 }hehe;
12
13 int main(int argc, char *argv[])
14 {
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 }
33
编译后运行:
$ ./2
ptr = 2, hihi = 0xbfe14b5c
a = 1, b = 2, c = 3
API Layer :: used to provide User space, which used to shutdown, restart, hibernate, suspend using sysfs .
PM Core :: Major modifications as on kernel ref: source code framework.
PM driver :: Again 2 Layers Architecture dependent and Specific Driver Framework.
Main stream linux kernel shutdown and restart system calls.
Ahhh!!! After shutdown, sooner or later will boot , so restart shutdown is a special process.
* Reboot system call: for obvious reasons only root may call it,
* and even root needs to set up some magic numbers in the registers
* so that some mistake won't make this reboot the whole machine.
* You can also set the meaning of the ctrl-alt-del-key here.
*
* reboot doesn't sync: do that yourself before calling this.
*/
SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd,
void __user *, arg)
| /** | |
| * 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). | |
| * | |
| * 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. | |
| * | |
| * @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(). If the transition is a suspend to memory or standby (that | |
| * is, not related to hibernation), the return value of @prepare() may be | |
| * used to indicate to the PM core to leave the device in runtime suspend | |
| * if applicable. Namely, if @prepare() returns a positive number, the PM | |
| * core will understand that as a declaration that the device appears to be | |
| * runtime-suspended and it may be left in that state during the entire | |
| * transition and during the subsequent resume if all of its descendants | |
| * are left in runtime suspend too. If that happens, @complete() will be | |
| * executed directly after @prepare() and it must ensure the proper | |
| * functioning of the device after the system resume. | |
| * 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.] | |
| * | |
| * @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. If the corresponding | |
| * @prepare() at the beginning of the suspend transition returned a | |
| * positive number and the device was left in runtime suspend (without | |
| * executing any suspend and resume callbacks for it), @complete() will be | |
| * the only callback executed for the device during resume. In that case, | |
| * @complete() must be prepared to do whatever is necessary to ensure the | |
| * proper functioning of the device after the system resume. To this end, | |
| * @complete() can check the power.direct_complete flag of the device to | |
| * learn whether (unset) or not (set) the previous suspend and resume | |
| * callbacks have been executed for it. | |
| * | |
| * @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_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. | |
| * | |
| * @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_early: Prepare to execute @resume(). For a number of devices | |
| * @resume_early() may point to the same callback routine as the runtime | |
| * resume callback. | |
| * | |
| * @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_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. | |
| * | |
| * @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_early: Prepare to execute @thaw(). Undo the changes made by the | |
| * preceding @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. | |
| * | |
| * @poweroff_late: Continue operations started by @poweroff(). Analogous to | |
| * @suspend_late(), but it need not save the device's settings in memory. | |
| * | |
| * @restore: Hibernation-specific, executed after restoring the contents of main | |
| * memory from a hibernation image, analogous to @resume(). | |
| * | |
| * @restore_early: Prepare to execute @restore(), analogous to @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(). | |
| * | |
| * @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. | |
| * | |
| * @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. | |
| * | |
| * @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. | |
| * | |
| * @poweroff_noirq: Complete the actions started by @poweroff(). Analogous to | |
| * @suspend_noirq(), but it need not save the device's settings in memory. | |
| * | |
| * @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(). | |
| * | |
| * 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. | |
| * | |
| * 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. | |
| * | |
| * 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. | |
| * | |
| * @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_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_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 return 0 if it's appropriate to let the PM | |
| * core queue a suspend request for the device. | |
| * | |
| * Refer to Documentation/power/runtime_pm.txt for more information about the | |
| * role of the above callbacks in device runtime power management. | |
| * | |
| */ | |
| 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); | |
| }; |


No comments:
Post a Comment