[Linux] suspend代碼閱讀記錄

Base Linux RC5.0

echo mem > /sys/power/state

Suspend                     Resume
    |                           |

    call notifiers              Turn On Power
    |                           |
    freeze tasks                System core online
    |                           |
    devices suspend             Nonboot cpu online
        |                       |
        .prepare                Devices Resume
        |                               |
        .suspend                        .resume_noirq
        |                               |
        .suspend_late                   .resume_early
        |                               |
        .suspend_noir                   .resume
    |                                   |
    nonboot cpu offline                 .comnplete
    |                           |
    system core offline         thaw tasks
    |                           |
    turn off power              call notifiers
    
autosleep_store      /*節點調用的入口函數*/

    decode_state    /*解析對用state,     pm_state的初始化在pm_state_init(pm init完成)*/
    pm_autosleep_set_state
        __pm_stay_awake(autosleep_ws);
        __pm_relax(autosleep_ws);
        pm_wakep_autosleep_enabled
        pm_suspend  (state < PM_SUSPEND_MAX)  /*Externally visible function for suspending the system*/
            enter_state /*Do common work needed to enter system sleep state*/
state_store
    pm_autosleep_lock
    pm_autosleep_state() > PM_SUSPEND_ON /*如果進入到suspend流程,返還出去*/
    decode_state     /*解析對用state,     pm_state的初始化在pm_state_init(pm init完成)*/
    if (state < PM_SUSPEND_MAX) {
		if (state == PM_SUSPEND_MEM)
			state = mem_sleep_current;      /*mem_sleep_store 函數初始化 mem sleep current的值*/
        error = pm_suspend(state);          /*Externally visible function for suspending the system*/
                enter_state()               /*Do common work needed to enter system sleep state*/
                   if (state == PM_SUSPEND_TO_IDLE)
	                   s2idle_begin();         /*s2idle_state = S2IDLE_STATE_NONE*/
	               pm_suspend_clear_flags       /*設置pm_suspend_global_flags = 0*/
	               suspend_prepare()            /*Prepare for entering system sleep state*/
	                    pm_prepare_console()        /*切換 控制檯打印口*/
	                    __pm_notifier_call_chain()       /*運行suspend的notifylist*/
	                    suspend_freeze_processes()
	                            freeze_processes        /*凍結用戶進程, 失敗則thaw_processes解凍進程*/
	                            freeze_kernel_threads   /*凍結內核進程嗎,失敗則thaw_processes解凍進*/    
                        dpm_save_failed_step()          /*what to do????*/
                        error go out:
                        __pm_notifier_call_chain        /*notify PM_POST_SUSPEND*/
                        pm_restore_console              /*恢復控制檯*/
                suspend_test()                          /*調試使用的api*/
                suspend_devices_and_enter()             /*設備驅動休眠與進系統休眠*/
                        sleep_state_supported()         /*判斷是否支持*/
                        platform_suspend_begin()
                                s2idle_ops->begin()
                                suspend_ops->begin(state)   /*suspend_set_ops(&psci_suspend_ops); psci 沒有begin這個api,所以return*/
                        suspend_console()     /*Suspending console(s) (use no_console_suspend to debug)*/
                        suspend_test_start()    /** what to do???/
                        dpm_suspend_start()
                                dpm_prepare()
                                        wait_for_device_probe()     /*清理workqueue, 等待wq完成,同步域中的所有異步函數*/
                                        device_block_probing()      /*sync with probes to avoid races*/
                                        device_prepare()            /*調用devices pm ops.prepare*/
                                dpm_suspend()
                                        devfreq_suspend()
                                        cpufreq_suspend()
                                        device_suspend()
                                        /*dpm_prepared_list),轉移到dpm_suspended_list*/
                                        async_synchronize_full()
                        suspend_enter()
                                platform_suspend_prepare()          /*suspend_ops->prepare*/
                                dpm_suspend_late()                  /*與dpm suspend 差別, 父節點的devices suspend, suspend late suspend設備*/
                                platform_suspend_prepare_late()         /*s2idle_ops->prepare()*/
                                s2idle_loop /*state = id or test level RETURN*/
                                dpm_suspend_noirq()         /*要disable irq的設備suspend,noirq,是通過禁止所有的中斷線的形式,而不是通過關全局中斷的方式*/
                                platform_suspend_prepare_noirq()
                                /*suspend_ops->prepare_late(), suspend_ops的prepare_late回調, 通知平臺代碼,以便讓其在最後關頭,再做一些處理, 失敗的話,需要跳至Platform_wake處, 
                                如果是suspend to freeze,執行相應的操作,包括凍結進程、suspended devices(參數爲PM_SUSPEND_FREEZE)、cpu進入idle
                                如果有任何事件使CPU從idle狀態退出,跳至Platform_wake處,執行wake操作*/
                                disable_nonboot_cpus()              /*offline 非boot cpu, 調用cpudown的接口*/
                                arch_suspend_disable_irqs()         /*local_irq_disable*/
                                syscore_suspend()
                                        pm_wakeup_pending  /*檢查wakeup狀態, return error*/ /*用pm_wakeup_pending檢查一下,這段時間內,是否有喚醒事件發生,如果有就要終止suspend*/
                                        ops->suspend    /*syscore_ops_list 上的suspend調用,exp: cpufreq_stop_governor*/
                                pm_wakeup_pending       /*再次檢查wakeup狀態*/
                                suspend_ops->enter(state)   /*調用到psci接口中*/
                                out path:
                                syscore_resume
                                arch_suspend_enable_irqs
                                enable_nonboot_cpus
                                platform_resume_noirq
                                dpm_resume_noirq
                                platform_resume_early
                                dpm_resume_early
                                platform_resume_finish
                        
   } else if (state == PM_SUSPEND_MAX) {
		error = hibernate();
	} else {
		error = -EINVAL;
	}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章