作家
登录

Linux系统休眠(System Suspend)和设备中断处理

作者: 来源: 2017-07-17 13:18:26 阅读 我要评论

【技巧沙龙】AI开辟者拭魅战营-7分钟打造1个定制技能。7月22号,我们等你一路!


一、设备IRQ的suspend和resume

四、Interrupts and Suspend-to-Idle

1、如不雅IRQ没有共享,应用IRQF_NO_SUSPEND flag解释你想要在全部体系的suspend-resume过程中(包含suspend_device_irqs之后的阶段)保持中断打开以便正常的调用其interrupt handler。而调用enable_irq_wake函数则解释你想要将该设备的irq旌旗灯号设定为中断源,是以并不期望调用其interrupt handler。而这两个需求明显是互斥的。

重要解决如许一个问题:在体系休眠过程中,若何suspend设备中断(IRQ)?在大年夜休眠中唤醒的过程中,若何resume设备IRQ?

一般而言,在体系suspend过程的后期,各个设备的IRQ (interrupt request line)会被disable掉落。具体的时光点是在各个设备的late suspend阶段之后。代码如下(删除了部分无关代码):

  1. static int suspend_enter(suspend_state_t state, bool *wakeup) 
  2.  
  3. {…… 
  4.  
  5. error = dpm_suspend_late(PMSG_SUSPEND);-----late suspend阶段 
  6.  
  7. error = platform_suspend_prepare_late(state); 
  8.  
  9. 下面的代码中会disable各个设备的irq 
  10.  
  11. error = dpm_suspend_noirq(PMSG_SUSPEND);----进入noirq的阶段 
  12.  
  13. error = platform_suspend_prepare_noirq(state); 
  14.  
  15. …… 
  16.  
  17.  

之所以这么做,其思路是如许的:在各个设备驱动完成了late suspend之后,按理嗣魅这些已经被suspend的设备不该该再触发中断了。如不雅还有一些设备没有被精确的suspend,那么我们最好的策略是mask该设备的irq,大年夜而阻拦中断的递交。此外,在以前的代码中(指interrupt handler),我们对设备共享IRQ的情况处理的不是很好,存在如许的问题:在共享IRQ的设备们完成suspend之后,如不雅有中断触发,这时刻设备驱动的interrupt handler并没有预备好。在有些场景下,interrupt handler会拜访已经suspend设备的IO地址空间,大年夜而导致弗成预知的issue。这些issue很难debug,是以,我们惹人了suspend_device_irqs()以及设备noirq阶段的callback函数。

体系resume过程中,在各个设备的early resume过程之前,各个设备的IRQ会被从新打开,具体代码如下(删除了部分无关代码):

  1. static int suspend_enter(suspend_state_t state, bool *wakeup) 
  2.  
  3. {…… 
  4.  
  5. platform_resume_noirq(state);----起首履行noirq阶段的resume 
  6.  
  7. dpm_resume_noirq(PMSG_RESUME);------在这里会恢复irq,然落后入early resume阶段 
  8.  
  9. platform_resume_early(state); 
  10.  
  11. dpm_resume_early(PMSG_RESUME); 
  12.  
  13. ……}  

在dpm_resume_noirq函数中,会调用各个设备驱动的noirq callback,在此之后,调用resume_device_irqs函数,完成各个设备irq的enable。

二、关于IRQF_NO_SUSPEND Flag

当然,有些中断须要在全部体系的suspend-resume过程中(包含在noirq阶段,包含将nonboot CPU推送到offline状况以及体系resume后,将其从新设置为online的阶段)保持可以或许触发的状况。一个简单的例子就是timer中断,此外IPI以及一些特别目标设备中断也须要如斯。

在中断申请的时刻,IRQF_NO_SUSPEND flag可以用来告诉IRQ subsystem,这个中断就是上一段文字中描述的那种中断:须要在体系的suspend-resume过程中保持enable状况。有了这个flag,suspend_device_irqs并不会disable该IRQ,大年夜而让该中断在随后的suspend和resume过程中,保持中断开启。当然,这并不克不及包管该中断可以将体系唤醒。如不雅想要达到唤醒的目标,请调用enable_irq_wake。

须要留意的是:IRQF_NO_SUSPEND flag影响应用该IRQ的所有外设(一个IRQ可以被多个外设共享,不过ARM中不会这么竽暌姑)。如不雅一个IRQ被多个外设共享,并且各个外设都注册了对应的interrupt handler,如不雅其一在申请中断的时刻应用了IRQF_NO_SUSPEND flag,那么在体系suspend的时刻(指suspend_device_irqs之后,按理说各个IRQ已经被disable了),所有该IRQ上的各个设备的interrupt handler都可以被正常的被触发履行,即就是有些设备在调用request_irq(或者其他中断注册函数)的时刻没有设定IRQF_NO_SUSPEND flag。正因为如斯,我们应当尽可能的避免同时应用IRQF_NO_SUSPEND 和IRQF_SHARED这两个flag。


  推荐阅读

  Windows 10系统internet explorer无法显示该网页怎么办?

【技巧沙龙】AI开辟者拭魅战营-7分钟打造1个定制技能。7月22号,我们等你一路! 在日常平凡工作之余,我们有时会应用ie浏览器来看视频或者浏览消息,可是有不罕用户反竽暌钩说打开ie然落>>>详细阅读


本文标题:Linux系统休眠(System Suspend)和设备中断处理

地址:http://www.17bianji.com/lsqh/36241.html

关键词: 探索发现

乐购科技部分新闻及文章转载自互联网,供读者交流和学习,若有涉及作者版权等问题请及时与我们联系,以便更正、删除或按规定办理。感谢所有提供资讯的网站,欢迎各类媒体与乐购科技进行文章共享合作。

网友点评
自媒体专栏

评论

热度

精彩导读
栏目ID=71的表不存在(操作类型=0)