博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
linux2.6.32内核Suspend流程
阅读量:2456 次
发布时间:2019-05-10

本文共 2749 字,大约阅读时间需要 9 分钟。

 

Suspend流程

参考linux2.6.32

Suspend锁流程

Suspend&resume流程

具体看main.c(kernel/power);上层通过属性节点写命令,最终会调到此文件中的state_store函数。

state_store()

{

   request_suspend_state();

}

request_suspend_state()@ kernel/power/ earlysuspend.c

{

  //early_suspend_work-> early_suspend,suspend处理

  queue_work(suspend_work_queue, &early_suspend_work);

  //early_suspend_work-> late_resume,resume处理,early suspend的模块resume

  queue_work(suspend_work_queue, &late_resume_work);

}

static void early_suspend(struct work_struct *work) @

{

        //处理earlysuspend,即一级休眠

list_for_each_entry(pos, &early_suspend_handlers, link) {

        if (pos->suspend != NULL)

               pos->suspend(pos);

       }

        // 系统suspend

wake_unlock(&main_wake_lock);

}

void wake_unlock(struct wake_lock *lock)@wakelock.c

{

        // suspend_work-> suspend()

        queue_work(suspend_work_queue, &suspend_work);

}

suspend()@wakelock.c

{

        //判断系统suspend有没有被锁,如果被锁,则中断二级休眠处理

       if (has_wake_lock(WAKE_LOCK_SUSPEND)) {

               return;

        }

        // suspend系统

        pm_suspend();

}

pm_suspend()@kernel/power/suspend.c

{

enter_state();

}

 

 

int enter_state(suspend_state_t state)

{

error = suspend_devices_and_enter(state);

}

suspend_devices_and_enter()

{

error = dpm_suspend_start(PMSG_SUSPEND);//devices suspend

{

        error = dpm_suspend(state);

}

 suspend_enter();// 系统相关suspend

}

static int suspend_enter(suspend_state_t state)

{

//disable all irq

error = dpm_suspend_noirq(PMSG_SUSPEND);

// system dev suspend

error = sysdev_suspend(PMSG_SUSPEND);

}

 

注意:    evdev.c中的evdev_event()->evdev_pass_event ()函数会调用wake_lock_timeout()。功能还不知道

 

设备处理

int device_add(struct device *dev) ()@drivers/base/core.c

{

device_pm_add(dev);@drivers/base/power/main.c

 

 

}

中断处理

原理

系统通过enable_irq_wake()标记中断在系统suspend时不disable,没有标记的irq在系统suspend时会被disable。

static inline int enable_irq_wake(unsigned int irq)

{

       return set_irq_wake(irq, 1);

}

 

int set_irq_wake(unsigned int irq, unsigned int on)

{

       if (on) {

              desc->status |= IRQ_WAKEUP;// 系统suspend是该中断不会被disable

       }

}

实现过程

系统suspend时,先通过dpm_suspend_noirq()disable所有的中断,然后再sysdev_suspend()调用intc的sysdev的suspend函数,恢复desc->status |= IRQ_WAKEUP标记的中断。

/*

*@kernel/power/suspend.c

*/

static int suspend_enter(suspend_state_t state)

{

dpm_suspend_noirq();// 关掉所有的中断

{

       suspend_device_irqs();

}

/*

*在sys_device的suspend回调函数中唤醒系统suspend时需要保持有效的中断

*rk的架构参考arch/arm/mach-rk2818/gpio.c的

*struct sysdev_class rk2818_gpio_sysclass.suspend= rk2818_gpio_suspend();但是该架构

*的实现函数rk2818_gpio_suspend()实现的不太标准。标准实现见下面的intc_suspend()

*/

sysdev_suspend();

dpm_resume_noirq();//恢复所有被disable的中断

}

 

 

其他参考模式

/*

*drivers/sh/intc.c

* intc_sysdev_class. suspend = intc_suspend;@ drivers/sh/intc.c

*/

intc_suspend()

{

       switch (state.event) {

              case PM_EVENT_SUSPEND:

        //将通过enable_irq_wake()函数设置的irq还原为enable状态

        for_each_irq_desc(irq, desc) {

               if ((desc->status & IRQ_WAKEUP) && (desc->chip == &d->chip))

                      intc_enable(irq);

               }

        break;

       }

}

转载地址:http://fhnhb.baihongyu.com/

你可能感兴趣的文章
sysadmin默认密码_sysadmin的Ansible指南:如何简化任务
查看>>
linux开源游戏_适用于Linux的5个开源策略和模拟游戏
查看>>
开源语法解释器_抓住机会解释开源
查看>>
sonic pi_前5名:Linux,Sonic Pi,LibreOffice等
查看>>
owncloud_本周热门文章5:ownCloud创始人专访,Raspberry Pi上的Docker等
查看>>
前5名:来自Docker CEO的一句话,来自Scratch的Linux等
查看>>
开源意义_有用的陌生人和开源的意义
查看>>
最佳 开源 人脸识别算法_2014年最佳开源教程
查看>>
foss测试_2014年FOSS十大法律发展
查看>>
本周最热门的5篇文章:Raspberry Pi A +,Ansible和Jen的Linux历程
查看>>
owncloud_一周前五篇文章:Linux理念,ownCloud集成等
查看>>
最佳 开源 人脸识别算法_本周最佳5篇文章:今年最佳开源,以及更多
查看>>
firefox 开源_一周最热门的5篇文章:移动版Firefox OS和年度开源奇迹
查看>>
18年开源前端框架排名_2014年排名前20位的开源故事
查看>>
十大开源项目_2014年十大开源访谈
查看>>
展望2019年_感谢您创纪录的一年(并展望2015年)
查看>>
go开源项目整理-新手篇_一周的前5篇文章:您正在从事什么开源项目?
查看>>
您不懂JavaScript,但您应该
查看>>
医疗项目 开源_免费和开源医疗保健成功的背后是什么?
查看>>
开源教学系统_通过开源进行教学和口语学习
查看>>