摘要:
此篇在上篇博文基礎上,增加對待機後,怎麼增加喚醒源的分析
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。