在很多驅動文件中可以發現,在request_thread_irq調用以後,probe函數裏並沒有顯示的調用enable_irq。對於我們來說,要確認的一點的是,沒有enable_irq的話,中斷函數是不會被調用的。細細看下代碼,只有request_thread_irq即在申請中斷的時候,中斷核心是不是會幫忙做了這件事呢?
從 request_thread_irq追到__setup_irq函數。在函數裏可以看到下面的代碼:
if(irq_setting_can_autoenable(desc))
irq_startup(desc, true);
else
desc->depth = 1;
1.irq_setting_can_autoenable
這個函數作爲判斷條件,追進去可以看到邏輯非常簡單
static inline bool irq_setting_can_autoenable(struct irq_desc *desc)
{
return !(desc->status_use_accessors & _IRQ_NOAUTOEN);
}
如果我們手動設置了IRQ_NOAUTOEN,那麼這裏的返回值爲false。如果沒設置,返回true。
2.irq_startup(desc, true)
這個代碼往下的具體實現我在代碼沒有實際找到,邏輯是如果chip有提供irq_startup回調那麼調用它,否則會調用irq_enable。
irq_enable也是如此,調用chip提供的irq_enable回調。
3.我們常用的接口enable_irq實際是對__enable_irq的封裝,內部邏輯如下:
desc會有一個count值叫做desc->depth,理論上調用一次disable_irq,這個值會加1,相反調用enable_irq會減1。
對於enable_irq來說,這裏有兩種特殊情況:
一個是depth爲0的情況下調用enable_irq,會通過WARN輸出警報,這個狀態下不應該有enable_irq被調用。
一個是depth爲1的情況下調用enable_irq,這個狀態下本來應該處於disable狀態,需要實際的打開這個中斷。這裏調用的也是irq_enable這個函數。
驗證一個問題:
1.request_thread_irq如果幫我們打開了中斷,我們在probe裏再次enable_irq會產生什麼效果?
實驗發現在probe里加了enable_irq會導致WARN的輸出,證明了確實是由request_thread_irq幫忙打開了中斷