request_irq
函数介绍
函数原型
最好用devm_request_irq代替
request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, const char *name, void *dev)
//对应free_irq (此函数必须要调用)
参数
irq: 要申请的硬件中断号。
对于不支持设备树的内核:在内核si项目里搜“irqs.h",找对应平台,即可得到。
对于支持设备树的内核:不能直接写中断号,要通过设备树映射中断号,见:request_irq注意事项
handler: 向系统注册的中断处理函数,是回调函数,中断发生时,系统调用这函数,dev_id参数传递给它。
本函数最后要return IRQ_HANDLED;
irqflags:中断处理的属性, //以下老版本意思是linux2.6.24之前
IRQF_DISABLED (老版本中的SA_INTERRUPT)表示中断处理程序是快速处理程序,
快速处理程序被调用时禁止所有中断。慢速处理程序不禁止
IRQF_SHARED (老版本中的SA_SHIRQ)多个设备共享中断,
IRQF_SAMPLE_RANDOM(老版本中的SA_SAMPLE_RANDOM),对系统获取随机数有好处。
...
name: 中断名称,通常是设备驱动程序的名称.
在/proc/interrupts 里可以看到。cat /proc/interrupts
dev: 作为中断服务函数(handler)的第二个参数。若中断服务函数用不到更多参数,则设置为NULL。
若此项不是NULL,free_irq的第二个参数也要写上对应的值。
返回值
0: 成功
-EINVAL:表示中断号无效或处理函数指针为NULL
-EBUSY:表示中断已经被占用且不能共享
注意事项
在设备树存在以后,不能直接把中断号作为第1个参数,得从设备树获取,获取时核心层函数做了映射将中断号数组中对应的索引作为此函数的参数。
示例:
i2c0的中断号是89
设备树中:
interrupt-parent = <&intc>;
interrupt = <0 57 1>; //共享中断,57+32=89, 触发方式:上升沿。设备树中共享中断要减32,私有中断要减16
驱动代码
static int i2c_probe(struct platform_device *pdev)
{
struct device_node *node;
int irq;
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
dev_err(&pdev->dev, "failed to get IRQ number\n");
return irq;
}
if(request_irq(irq, i2c0_int_irq_handler, IRQF_SHARED, "i2c0-test" , &(dev->dev)))
{
printk(KERN_DEBUG "requst irq failled \n");
}
return 0;
}