gpio_to_irq
使用提供的gpio_to_irq是最佳的选择,设备树配置起来也比较方便,都不需要将中断父结点设置为gpio0。
key {
compatible = "zynq,led";
status = "okay";
key-gpio = <&gpio0 12 GPIO_ACTIVE_LOW>;
//interrupt-parent = <&gpio0>; //使用gpio_to_irq不需要设置
//interrupts = <12 2>; /* FALLING RISING */ //使用gpio_to_irq不需要设置
};
驱动程序申请一下映射后的终端号key_test.irq(int):
key_test.irq = gpio_to_irq(key_test.key_gpio);
使用key_test.irq就可以request中断啦~
但是可以看出,现在的父结点是gpio,中断号是12,也就是现在key使用的编号(MIO12),而不是GPIO的中断号52。
irq_of_parse_and_map
irq_of_parse_and_map是一般性的方法,如果偏要使用也可以。使用irq_of_parse_and_map获取中断号。先要将设备树设置为:
key {
compatible = "zynq,led";
status = "okay";
key-gpio = <&gpio0 12 GPIO_ACTIVE_LOW>;
//interrupt-parent = <&intc>; //依附intc会报错
interrupt-parent = <&gpio0>;
interrupts = <12 2>; /* FALLING RISING */
};
因为中断父结点是gpio0,从上面那张图可知需要将中断号设置成12,即自己所使用的MIO编号,的而不是gpio自己的中断号52。
C程序中:
key_test.irq = irq_of_parse_and_map(key_test.nd,0);
之后照旧request就行啦。
ret = request_irq(key_test.irq,
key_handler,
IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
"KEY",
NULL);
为啥interrupts有两个元素?因为gpio0节点规定了它的子节点的interrupts属性的元素数目为2。分别是<终端号 触发方式>。(如果是3个的话就是第一个是中断域:<中断域 中断号 触収方式>)
注意,不可以想当然的把中断父结点直接设置为<&intc>,直接设置中断号为52-32=20会报错: