|
void handle_edge_irq(unsigned int irq, struct irq_desc *desc)
{
raw_spin_lock(&desc->lock);
/*因為接收到中斷,所以清除下面兩個標誌*/
desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING);
/*IRQ是否被禁止,或者正在處理中,或者沒有掛接中斷處理函數*/
if (unlikely(irqd_irq_disabled(&desc->irq_data) ||
irqd_irq_inprogress(&desc->irq_data) || !desc->action)) {
if (!irq_check_poll(desc)) {
desc->istate |= IRQS_PENDING; /*設定irq處於掛起狀態*/
mask_ack_irq(desc); /*向硬體發ACK,屏蔽中斷*/
goto out_unlock;
}
}
kstat_incr_irqs_this_cpu(irq, desc); /*process/interrupts中對應irq計算加1*/
/*cpu對此IRQ的回應,表示準備接收此IRQ的下一個中斷*/
desc->irq_data.chip->irq_ack(&desc->irq_data);
do {
if (unlikely(!desc->action)) { /*沒有掛接中斷處理函數*/
mask_irq(desc); /*屏蔽IRQ*/
goto out_unlock;
}
/*IRQ處於中斷掛起狀態*/
if (unlikely(desc->istate & IRQS_PENDING)) {
if (!irqd_irq_disabled(&desc->irq_data) &&
irqd_irq_masked(&desc->irq_data))
unmask_irq(desc);
}
/*處理中斷*/
handle_irq_event(desc);
} while ((desc->istate & IRQS_PENDING) && /*有掛起的中斷需要處理*/
!irqd_irq_disabled(&desc->irq_data)); /*irq沒有禁止*/ |