驱动程序可以通过下面的函数注册并激活一个中断处理程序,以便处理中断:
- int request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *), unsigned long irgflags, const char *devname, void *dev_id)
第一个参数irq表示要分配的中断号。
第二个参数handler是一个指针,指向处理这个中断的实际中断处理程序。只要操作系统一接到中断,该函数就被调用。
第三个参数irqflags可以为0,也可能是下列一个或多个标志的位掩码:
- SA_INTERRUPT: 此标志表明给定的中断处理程序是一个快速中断处理程序。现在,加不加此标志的区别只剩下一条了:在本地处理器上,快速中断处理程序在禁止所有中断的情况下运行。这使得快速中断处理程序能够不受其他中断干扰,得以迅速执行。而默认情况下(没有这个标志),除了正运行得中断处理程序对应的那条中断线被屏蔽外,其他所有中断都是激活的。除了时钟中断外,绝大多数中断都不使用该标志。
- SA_SAMPLE_RANDOM: 此标志表明这个设备产生的中断对内核熵池有贡献。内核熵池负责提供从各种随即事件导出的真正的随机数。如果指定了改标志,那么来自设备的中断间隔就会作为熵填充到熵池。有其他很多硬件产生中断的速率是不可预知的,所有都能称为一种较好的熵源。
- SA_SHIRQ: 此标志表明可以在多个中断处理程序之间共享中断线。在同一个给定线上注册的每个处理程序必须指定这个标志;否则,在每条线上只能有一个处理程序。
第四个参数devname是与中断相关的设备的ASCII文本表示法。
第五个参数dev_id主要用于共享中短线。当一个中断处理程序需要释放时,dev_id将提供唯一的标志信息(cookie),以便从共享中断线的诸多中断处理程序中删除指定的哪一个。如果无需共享中短线,那么将该参数赋予空值(NULL)就可以了。实践中往往会通过它传递驱动程序的设备结构:这个指针是唯一的,而且有可能在中断处理程序内及设备模式中被用到。
request_irq()成功执行回返回0。如果返回非0值,就表示有错误发生,在这种情况下,指定的中断处理程序不会被注册。最常见的错误时-EBUSY,它表示给定的中断线已经在使用。
注意,request_irq()函数可能会睡眠,因此,不能在中断上下文或其他不允许阻塞的代码中调用该函数。
释放中断处理程序
卸载驱动程序时,需要注销相应的中断处理程序,并释放中断线。可以调用void free_irq(unsigned int irq,void *dev_id)来释放中断线。
如果指定的中断线不是共享的,那么,该函数删除处理程序的同时将禁用这条中断线。如果中断线是共享的,则仅删除dev_id所对应的处理程序,而这条中断本身只有在删除了最后一个处理程序时才会被禁用。
必须从进程上下文中调用free_irq()。