您好、欢迎来到现金彩票网!
当前位置:2019手机棋牌游戏平台 > 系统中断 >

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

发布时间:2019-06-20 02:20 来源:未知 编辑:admin

  主要解决这样一个问题:在系统休眠过程中,如何suspend设备中断(IRQ)?在从休眠中唤醒的过程中,如何resume设备IRQ?

  之所以这么做,其思路是这样的:在各个设备驱动完成了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会被重新打开,具体代码如下(删除了部分无关代码):

  当然,有些中断需要在整个系统的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。

  有些中断可以将系统从睡眠状态中唤醒,我们称之“可以唤醒系统的中断”,当然,“可以唤醒系统的中断”需要配置才能启动唤醒系统这样的功能。这样的中断一般在工作状态的时候就是作为普通I/O interrupt出现,只要在准备使能唤醒系统功能的时候,才会发起一些特别的配置和设定。

  这样的配置和设定有可能是和硬件系统(例如SOC)上的信号处理逻辑相关的,我们可以考虑下面的HW block图:

  外设的中断信号被送到“通用的中断信号处理模块”和“特定中断信号接收模块”。正常工作的时候,我们会turn on“通用的中断信号处理模块”的处理逻辑,而turn off“特定中断信号接收模块” 的处理逻辑。但是,在系统进入睡眠状态的时候,有可能“通用的中断信号处理模块”已经off了,这时候,我们需要启动“特定中断信号接收模块”来接收中断信号,从而让系统suspend-resume模块(它往往是suspend状态时候唯一能够工作的HW block了)可以正常的被该中断信号唤醒。一旦唤醒,我们最好是turn off“特定中断信号接收模块”,让外设的中断处理回到正常的工作模式,同时,也避免了系统suspend-resume模块收到不必要的干扰。

  IRQ子系统提供了两个接口函数来完成这个功能:enable_irq_wake()函数用来打开该外设中断线通往系统电源管理模块(也就是上面的suspend-resume模块)之路,另外一个接口是disable_irq_wake(),用来关闭该外设中断线通往系统电源管理模块路径上的各种HW block。

  Freeze和suspend的前面的操作基本是一样的:首先冻结系统中的进程,然后是suspend系统中的形形色色的device,不一样的地方在noirq suspend完成之后,freeze不会disable那些non-BSP的处理器和syscore suspend阶段,而是调用freeze_enter函数,把所有的处理器推送到idle状态。这时候,任何的enable的中断都可以将系统唤醒。而这也就意味着那些标记IRQF_NO_SUSPEND(其IRQ没有在suspend_device_irqs过程中被mask掉)是有能力将处理器从idle状态中唤醒(不过,需要注意的是:这种信号并不会触发一个系统唤醒信号),而普通中断由于其IRQ被disable了,因此无法唤醒idle状态中的处理器。

  那些能够唤醒系统的wakeup interrupt呢?由于其中断没有被mask掉,因此也可以将系统从suspend-to-idle状态中唤醒。整个过程和将系统从suspend状态中唤醒一样,唯一不同的是:将系统从freeze状态唤醒走的中断处理路径,而将系统从suspend状态唤醒走的唤醒处理路径,需要电源管理HW BLOCK中特别的中断处理逻辑的参与。

  针对一个设备,在申请中断的时候使用IRQF_NO_SUSPEND flag,又同时调用enable_irq_wake设定唤醒源是不合理的,主要原因如下:

  不过,在非常特殊的场合下,一个IRQ可以被设定为wakeup source,同时也设定IRQF_NO_SUSPEND 标志。为了代码逻辑正确,该设备的驱动代码需要满足一些特别的需求。

  每日头条、业界资讯、热点资讯、八卦爆料,全天跟踪微博播报。各种爆料、内幕、花边、资讯一网打尽。百万互联网粉丝互动参与,TechWeb官方微博期待您的关注。

http://keithpaine.com/xitongzhongduan/237.html
锟斤拷锟斤拷锟斤拷QQ微锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷微锟斤拷
关于我们|联系我们|版权声明|网站地图|
Copyright © 2002-2019 现金彩票 版权所有