linux kernel 工程师
全部博文(99)
分类: LINUX
2014-02-08 15:02:09
__irq_set_handler作为中断注册的第一个层次,通过这个函数为desc->handle_irq 安排一个处理函数。
通常安排的处理函数有handle_edge_irq,handle_level_irq等
void
__irq_set_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
const char *name)
{
unsigned long flags;
struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, 0);
if (!desc)
return;
if (!handle) {
handle = handle_bad_irq;
} else {
if (WARN_ON(desc->irq_data.chip == &no_irq_chip))
goto out;
}
/* Uninstall? */ /* 如果要uninstall,在参数里传递handle为 handle_bad_irq */
if (handle == handle_bad_irq) {
if (desc->irq_data.chip != &no_irq_chip)
mask_ack_irq(desc);
irq_state_set_disabled(desc);
desc->depth = 1;
}
desc->handle_irq = handle; /* 安装desc->handle_irq */
desc->name = name;
if (handle != handle_bad_irq && is_chained) {
/* 如果传递参数is_chained为true,设置desc->status_use_accessors |= _IRQ_NOREQUEST;
is_chained 在 设备驱动程序的内核机制中 解释为中断共享,应当是不正确的。有人翻译为中断级联,不知可否?
在request_irq里面会判断 (!irq_settings_can_request(desc) ) 来确定是否可以通过request_irq来安装desc->action->handler.
如果这里设置了_IRQ_NOREQUEST,则不能通过request_irq来安装desc->action->handler
*/
irq_settings_set_noprobe(desc);
irq_settings_set_norequest(desc);
irq_settings_set_nothread(desc);
irq_startup(desc, true);
}
out:
irq_put_desc_busunlock(desc, flags);
}