在前面的文章提到的设备树文件没有涉及到中断本文章会对设备树中的中断简单的介绍,
在以前的mach-s3c24xx.c中手动注册了很多平台设备,这些平台设备中指定了很多设备资源,比如i2c控制器提前指定了中断号和内存等资源,这些中断号可以从某个头文件指定。
内核不断演变,虚拟中断号和硬件中断号不再绑定,这也就意味着不能在平台资源里事先确定所使用的中断资源,就需要用设备树描述这些中断资源,也就是事先不能确定好virq(虚拟中断号),这时我们就必须用设置树描述中断,
解压linux内核
tar xzf linux-4.19-rc3.tar.gz
打上补丁:
cd linux-4.19-rc3 patch -p1 < ../linux-4.19-rc3_device_tree_for_irq_jz2440.patch
在内核目录下执行:
export PATH=PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/work/tools/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabi/bin cp config_ok .config make uImage // 生成 arch/arm/boot/uImage make dtbs // 生成 arch/arm/boot/dts/jz2440_irq.dtb
内核中断(设备树中没有描述中断资源):
/ # cat proc/interrupts
CPU0
29: 6753 s3c 13 Edge samsung_time_irq
42: 0 s3c 26 Edge ohci_hcd:usb1
43: 0 s3c 27 Edge s3c2440-i2c.0
74: 69 s3c-level 0 Edge s3c2440-uart
75: 284 s3c-level 1 Edge s3c2440-uart
83: 1 s3c-level 9 Edge ts_pen
84: 8688 s3c-level 10 Edge adc
87: 0 s3c-level 13 Edge s3c2410-wdt
samsung_time_irq对应中断号是29,在irqs.h中对应的宏是 #define IRQ_TIMER3 S3C2410_IRQ(13),
使用老内核中断号都是固定的,如下所示:
#define IRQ_TICK S3C2410_IRQ(8) /* 24 */
#define IRQ_WDT S3C2410_IRQ(9) /* WDT/AC97 for s3c2443 */
#define IRQ_TIMER0 S3C2410_IRQ(10)
#define IRQ_TIMER1 S3C2410_IRQ(11)
#define IRQ_TIMER2 S3C2410_IRQ(12)
#define IRQ_TIMER3 S3C2410_IRQ(13) /* 29 */
使用新内核启动:
nfs 30000000 192.168.1.109:/work/share_nfs/uImage; nfs 32000000 192.168.1.109:/work/share_nfs/jz2440_irq.dtb; bootm 30000000 - 32000000
/ # cat proc/interrupts
CPU0
8: 0 s3c 8 Edge s3c2410-rtc tick
13: 7317 s3c 13 Edge samsung_time_irq
30: 0 s3c 30 Edge s3c2410-rtc alarm
32: 52 s3c-level 32 Level 50000000.serial
33: 168 s3c-level 33 Level 50000000.serial
59: 0 s3c-level 59 Edge 53000000.watchdog
我们发现samsung_time_irq的中virq(虚拟中断号)从之前的29变成现在的13,以前在老版本的linux内核中根据硬件制定它的虚拟中断号,现在我们不能指定virq(虚拟断号)只能在设备树中描述会用到什么中断号。
现在我们不能事先根据硬件确定virq(虚拟中断号),我们只能在设备树里面描述硬件会用到哪个hwirq(硬件中断号),
我们怎么表明一个中断呢? 我可以用hwirq(硬件中断号)提示:在不同的中断控制器里面相同的硬件中断号值对应的硬件中断是不一样的
1、指定是哪一个中断控制器(属于哪一个中断控制器);
2、指定在该中断控制器里面的哪一个hwirq(硬件中断号);
举个例子:
有个网卡:当网卡有数据时会产生一个中断,接到gpio控制器里面,怎么描述这个网卡的中断信息呢?
1、指定网卡的中断控制器是谁(interrupt-parent= )
2、指定使用中断控制器里面的哪个中断(interrupts=)
ethernet@20000000 {
compatible = "davicom,dm9000";
reg = <0x20000000 0x2 0x20000004 0x2>;
interrupt-parent = <&gpf>;
interrupts = <7 IRQ_TYPE_EDGE_RISING>;
local-mac-address = [00 00 de ad be ef];
davicom,no-eeprom;
};
interrupt-parent = <&gpf>:interrupt-parent指向一个中断控制器gpf
interrupts = <7 IRQ_TYPE_EDGE_RISING>:表明使用中断控制器gpf里面的7号中断(hwirq硬件中断号),IRQ_TYPE_EDGE_RISING表明是中断触发方式。
对于gpio中断可以指定中断触发方式,对于其他中断可能就不需要指定中断触发方式所以interrupts用多个u32表示是由interrupt-parent(它所属于的中断控制器)所决定的。interrupts = <hwirq type>的具体含义由中断控制器来解释,用多个u32表示由中断控制器决定。
问题:中断控制器怎么决定用多个u32表示<hwirq type>
答:中断控制器在设备树里面也有一个节点,它可以表明它是一个中断控制器,它有一项属性:
1、interrupt-controller属性(它是个没有值得属性)表明自己是一个中断控制器;
2、#interrupt-cells = <n>:表示下一级设备用n个u32数据描述这个中断;