摘要:
此篇在上篇博文基础上,增加对待机后,怎么增加唤醒源的分析
android待机过程 与 irq的开关过程
对于android开发者而言,可能会有疑问为什么我们的手机或者平板,音量按键,屏幕不会亮,而电源按键,屏幕会亮?又或者如何才能让音量按键也有点亮屏的效果(当然纯粹是以开发者角度,与实用性无关)
irq在android待机过程中的总体管理是:
1. 全部irq被disable
2. 部分irq被enable
3. 待机等待irq唤醒
之所以能够这么统一地管理所有的irq,而不用知道是什么应用注册的irq,是通过irq的属性,而这个属性是每个模块在申请注册自己模块中断时候需要考虑清楚的。
我们尝试一下,在待机的时候,是否可以按自己想法,使能部分的irq,比如音量按键。
1. 全部irq被disable
- arch_suspend_disable_irqs();
2. 部分irq被enable
- list_for_each_entry_reverse(cls, &system_kset->list, kset.kobj.entry) {
- pr_debug("Suspending type '%s':\n",
- kobject_name(&cls->kset.kobj));
- list_for_each_entry(sysdev, &cls->kset.list, kobj.entry) {
- pr_debug(" %s\n", kobject_name(&sysdev->kobj));
- /* Call auxillary drivers first */
- list_for_each_entry(drv, &cls->drivers, entry) {
- if (drv->suspend) {//在driver的suspend回调里面,打开要使能的irq,让irq有wakeup功能
- ret = drv->suspend(sysdev, state);
- if (ret)
- goto aux_driver;
- }
- WARN_ONCE(!irqs_disabled(),
- "Interrupts enabled after %pF\n",
- drv->suspend);
- }
- /* Now call the generic one */
- if (cls->suspend) {
- ret = cls->suspend(sysdev, state);
- if (ret)
- goto cls_driver;
- WARN_ONCE(!irqs_disabled(),
- "Interrupts enabled after %pF\n",
- cls->suspend);
- }
- }
- }
管理irq,我们只需要知道irq的id是多少就可以,在CPU设计,会有GIC模块,每个irq都能有唯一的id。
在linux中,enable_irq_wake和disable_irq_wake两个函数,只需要传入irq的id,就可以开关这个irq的wake功能。
比如
- int irq_wake_id[IRQ_WAKE_MAX];
- void pm_irqwake_enable(void)
- {
- enable_irq_wake(irq_wake_id[IRQ_WAKE_TS]);
- enable_irq_wake(irq_wake_id[IRQ_WAKE_GS]);
- enable_irq_wake(irq_wake_id[IRQ_WAKE_KEY_MENU]);
- return;
- }
- void pm_irqwake_disable(void)
- {
- disable_irq_wake(irq_wake_id[IRQ_WAKE_GS]);
- disable_irq_wake(irq_wake_id[IRQ_WAKE_TS]);
- disable_irq_wake(irq_wake_id[IRQ_WAKE_KEY_MENU]);
- return;
- }
这些irq的id,是可以cat proc/interrupts得到的,当然更好的方法是用函数去获取,我是偷懒直接看完id后,再define。