再谈Request_irq和setup_irq

来源:互联网 发布:个体户年报有淘宝网店 编辑:程序博客网 时间:2024/06/05 04:30

上一篇文章描述了Request_irq和setup_irq的区别,这里我们来看看,在设备驱动中该怎么使用request_irq和setup_irq。

通过看request_irq和setup_irq的实现我们可以知道, request_irq的action是通过kmalloc分配得到的,而 free_irq内部调用了__free_irq,__free_irq实际上是将对应的irqaction从action chain(是该中断的action列表,存放在链表中)中去掉并返回此irqaction的指针,然后用kfree去free掉它。这说明,request_irq申请的中断应该使用free_irq去free掉。

但对于setup_irq,第二个参数irqaction很有可能不是kmalloc得到,因此在使用setup_irq设置一个irqaction后,通常不能用free_irq去free它,否则会出现访问NULL pointer的oops。与setup_irq对应的应该是remove_irq(内部也调用了__free_irq,但是没有去free它的返回值)。


再来看看,free_irq的第二个参数是dev_id,该参数用于判断要free掉的到底是该中断  action chain中的哪个  irqaction(通过遍历,逐个比较),如果遍历到chain末尾还找不到匹配的irqaction(使得action->dev_id == dev_id)那么就会报Trying to free already-free IRQ的错。

上述结论可以通过查看kernel/irq/manage.c中的具体实现验证。


另外,disable_irq / enable_irq用于除能和使能某个中断,但对于共享中断要特别注意,一次disable_irq 作用是使得整个中断线上的中断action都被disable掉(实际上是将中断向量irq_desc的status成员置位IRQ_DISABLED,这将影响该中断向量的整个action chain)