First, Runtime pm introduction
1. Background
(1) Display requirements
(2) The demand of dynamic power optimization for the whole system
(3) Upstream
2. Solution
(1) Introduction of Debounce
(2) Use a unified workqueue to manage tasks
(3) Close the device that does not need to work in real time
(4) When the device is a parent, all the child does not work, the device is closed
(5) Introduction of Pm_rutime
3. Performance indicators
(1) Fast switch screen scene, light screen speed increase
(2) Dynamic power consumption, more stable, wake up without light screen scene, lower power consumption
(3) Help to reduce the dynamic power consumption of the system
Second, Runtime PM framework
1. Runtime pm Hierarchy
2. Runtime PM Status
3. Runtime pm Control Process
Each device or subsystem will register 3 callback with the runtime PM core.
In the struct dev_pm_ops struct, these three callback are defined:
struct Dev_pm_ops {
...
Int (*runtime_suspend) (struct device *dev);
Int (*runtime_resume) (struct device *dev);
Int (*runtime_idle) (struct device *dev);
. suspend
. resume
};
Note: After the introduction of runtime, the suspend interface needs to be placed in the same data structure as the runtime interface;
4. Rpm_status (include\linux\pm.h)
Enum Rpm_status {
rpm_active = 0, /* indicates that Runtime_resume () was executed successfully */
rpm_resuming, /* indicates that runtime_resume () is being executed */
rpm_suspended, /* indicates that runtime_suspend () was executed successfully */
rpm_suspending, /* indicates that runtime_suspend () is being executed */
};
5. Rpm_request (include\linux\pm.h)
Enum Rpm_request {
Rpm_req_none = 0,rpm_req_idle,/* Execute Runtime_idle () */
Rpm_req_suspend, /* Execute runtime_suspend () */
Rpm_req_autosuspend, /* Execute runtime_suspend after autosuspend_delay delay () */
Rpm_req_resume, /* Execute Runtime_resume () */
};
The type of the request (setting request_pending is valid).
6. Idle Reference API
Pm_runtime_put_noidle:only put
Pm_runtime_idle
Pm_request_idle:async
Pm_runtime_put:put + Async
Pm_runtime_put_sync
7. Suspend Reference API
Pm_schedule_suspend
Pm_runtime_suspend:
Pm_runtime_put_sync_suspend:put
Pm_runtime_autosuspend:auto
Pm_request_autosuspend:async + Auto
Pm_runtime_put_autosuspend:put + async + Auto
Pm_runtime_put_sync_autosuspend:put + Auto
8. Resume Reference API
Pm_runtime_get_noresume
Pm_runtime_resume
Pm_request_resume:async
Pm_runtime_get:get + Async
Pm_runtime_get_sync:get
9. Device Runtime Suspend process
Trigger:
Pm_schedule _suspend
pm_runtime_suspend:
pm_runtime_put_sync_suspend:put
Pm_runtime_autosuspend:auto
Pm_request_autosuspend:async + auto
Pm_runtime_put_autosuspend:put + async + auto
Pm_runtime_put_sync_autosuspend:put + auto
Suspend conditions:
usage_cnt= 0;
disable_depth = 0;
Runtime_status = rpm_active
Device Runtime PM Idle Process
Idle trigger:
Pm_runtime_put_noidle:only put
Pm_runtime_idle
Pm_request_idle:async
Pm_runtime_put:put + Async
Pm_runtime_put_sync
Conditions for idle:
Usage_cnt= 0;
disable_depth = 0;
Runtime_status = rpm_active
Device Runtime PM Resume Process
Trigger:
Pm_runtime_get_noresume
Pm_runtime_resume
Pm_request_resume:async
Pm_runtime_get:get + Async
Pm_runtime_get_sync:get
Conditions:
disable_depth = 0
Runtime_status! = rpm_active
III. Runtime PM and device model
1. Device Runtime PM Initialization
(1) The device model completes the initialization of Pm_runtime;
(2) The change of pm_runtime state needs to be realized after device_register;
(3) device model, when calling the DRV probe, remove, shutdown and other interfaces,
Can ensure that the pm_runtime in disable state, or other agreed state;
void Pm_runtime_init (struct device *dev)
{
Dev->power.runtime_status = rpm_suspended;
Dev->power.idle_notification = false;
dev->power.disable_depth = 1;
Atomic_set (&dev->power.usage_count, 0);
Dev->power.runtime_error = 0;
Atomic_set (&dev->power.child_count, 0);
Pm_suspend_ignore_children (Dev, false);
Dev->power.runtime_auto = true;
Dev->power.request_pending = false;
Dev->power.request = Rpm_req_none;
Dev->power.deferred_resume = false;
Dev->power.accounting_timestamp = jiffies;
Init_work (&dev->power.work, pm_runtime_work);
dev->power.timer_expires = 0;
Setup_timer (&dev->power.suspend_timer, PM_SUSPEND_TIMER_FN, (unsigned long) dev);
Init_waitqueue_head (&dev->power.wait_queue);
}
Platform_device_register (&platform_disp_device);
Pm_runtime_set_active (&platform_disp_device.dev);
Pm_runtime_get_noresume (&platform_disp_device.dev);
Pm_runtime_enable (&platform_disp_device.dev);
Pm_runtime_set_autosuspend_delay (&platform_disp_device.dev, 5000);
Pm_runtime_use_autosuspend (&platform_disp_device.dev);
Platform_driver_register (&disp_driver);
2. Device Runtime PM Remove Process
3. Device Runtime PM shutdown process
Iv. Runtime pm and Power Management
1. System Sleep Flow
2. System Sleep Flow:resume
3. System Sleep Flow:suspend
Five, Runtime PM case Analysis
Linux Runtime PM Introduction