linux kernel 工程师
全部博文(99)
分类: LINUX
2014-02-08 16:04:24
文中提到 __irq_set_handler作为中断注册的第一个层次,通过这个函数为desc->handle_irq 安排一个处理函数。
通常安排的处理函数有handle_edge_irq,handle_level_irq等
假如安排的处理函数是 handle_level_irq,我们看一下处理流程
/**
* handle_level_irq - Level type irq handler
* @irq: the interrupt number
* @desc: the interrupt description structure for this irq
*
* Level type interrupts are active as long as the hardware line has
* the active level. This may require to mask the interrupt and unmask
* it after the associated handler has acknowledged the device, so the
* interrupt line is back to inactive.
*/
void
handle_level_irq(unsigned int irq, struct irq_desc *desc)
{
raw_spin_lock(&desc->lock);
mask_ack_irq(desc); /* 屏蔽掉当前中断 */
if (unlikely(irqd_irq_inprogress(&desc->irq_data))) /* 发现同一个中断isr程序正在执行,退出 */
if (!irq_check_poll(desc))
goto out_unlock;
desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING);
kstat_incr_irqs_this_cpu(irq, desc);
/*
* If its disabled or no action available
* keep it masked and get out of here
*/
if (unlikely(!desc->action || irqd_irq_disabled(&desc->irq_data)))
goto out_unlock;
handle_irq_event(desc); /* 这里调用 handle_irq_event,handle_irq_event->handle_irq_event_percpu-> action->handler */
cond_unmask_irq(desc);
out_unlock:
raw_spin_unlock(&desc->lock);
}