[Linux kernel]系统sleep

//以下是进入sleep的关键入口
lpm_cpuidle_enter(,fromidle)或 lpm_suspend_enter(,fromidle)
 ->lpm_enter_low_power()
	->lpm_cpu_prepare(system_state, cpu_index, from_idle);
	->lpm_system_prepare(system_state, idx, from_idle);
		->msm_rpm_enter_sleep() 
			->smd_mask_receive_interrupt() //屏蔽RPM发给AP的中断	
		->msm_mpm_enter_sleep() //进入sleep前配置MPM
	->msm_cpu_pm_enter_sleep(cpu_level->mode, from_idle);
		->execute[mode](from_idle); //调用msm_pm_power_collapse()等
	->lpm_system_unprepare(system_state, cpu_index, from_idle);
		->msm_rpm_exit_sleep();  //不屏蔽RPM发给AP的中断
		->msm_mpm_exit_sleep(from_idle); //退出SLEEP时
	->lpm_cpu_unprepare(system_state, cpu_index, from_idle); 

1)lpm_suspend_enter()被调用的过程

被定义在 lpm_suspend_ops 里:
static const struct platform_suspend_ops lpm_suspend_ops = 
{
	enter = lpm_suspend_enter,
	valid = suspend_valid_only_mem,
	prepare_late = lpm_suspend_prepare,
	wake = lpm_suspend_wake
}

 suspend_set_ops(&lpm_suspend_ops) //Set the global suspend method table:suspend_ops
 
 //貌似以下2种情况是由app主动写文件节点而设置睡眠的
 autosleep_store()->..->try_to_suspend()  //配置了CONFIG_PM_AUTOSLEEP
 或state_store  
     ->pm_suspend()
       ->enter_state() //Do common work needed to enter system sleep state
		 ->suspend_devices_and_enter()
		   ->suspend_enter()
			 ->suspend_ops->prepare_late();
			 ->disable_nonboot_cpus();
			 ->arch_suspend_disable_irqs();
			 ->syscore_suspend() //Execute all the registered system core suspend 
			 //callbacks in syscore_ops_list,like GPIO,timer, sched_clock, GIC, VIC, cupfreq 
			 
			if not Fail
			{
				if not pm_wakeup_pending()
				  ->suspend_ops->enter(state);//lpm_suspend_enter(,fromidle=false) 开始进入进入low power
				syscore_resume()
				
			 }
			 ->arch_suspend_enable_irqs();
			 ->enable_nonboot_cpus();
			 ->suspend_ops->wake();
 
 
 2) lpm_cpuidle_enter()被调用的过程
 
 //从以下可以看出,这是因CPU没有任务运行,所以主动进入sleep.
 start_kernel()
 ->rest_init()
	->cpu_idle()
	{
	   while (1) 
	   {
			while (!need_resched()) 
			{
			
				if (!need_resched()) 
				{
					cpuidle_idle_call() //通过cpuidle_get_driver获取cpuidle_curr_driver变量
					->cpuidle_enter_state()
						->cpuidle_enter_ops()  //被赋予:cpuidle_enter()
						  ->target_state->enter()  //被赋予:lpm_cpuidle_enter(,fromidle=true).  
						  //在lpm_cpuidle_init()里,msm_cpuidle_driver 通过cpuidle_register()函数被注册到cpuidle_curr_driver变量
						  
				}
			}
	   }
	}
 

你可能感兴趣的:(Linux,linux,kernel)