前言
Linux Device Tree中定义了很多和中断相关的属性,这些属性之间的关系错综复杂。为剖析这些关系,特地查阅文档后输出本文。本文基于ARM平台,主要说明如下几个属性:
interrupt-controller
interrupt-parent
interrupt-cells
interrupts
interrupt domain和interrupt specifier
interrupt-map
其中第5点属于中断相关文章中经常会提到的概念,并不是Device Tree中定义的属性。但理解它们也非常有必要,所以在这里一并解释下。
中断控制器的硬件结构(基于Exynos4412 ARMv7)
查看Exynos4412芯片手册中断相关章节可以确认Exynos4412有两个中断控制器,一个是常见的GIC(PL390),另外一个是Interrupt Combiner。具体连接关系如下所示:
可以看到这里的PL390后面又级联了一个名叫Interrupt Combiner的中断控制器。所以这颗SOC有两个interrupt controller,分别是GIC和Interrupt Combiner。下面分别看下这两个控制器的硬件细节。
GIC
先看下GIC的硬件细节,如下图所示:
可以看到GIC的外设中断(除去SGI)类型有两类:
SPI,共享外设中断(由GIC内部的distributor来分发到相关CPU),中断号:32~1019
PPI,私有外设中断(指定CPU接收),中断号:16~31
外设中断号的分配规则如下:
32~1019给SPI
16~31给PPI
所有外设中断都支持四种触发方式:
上升沿触发
下降沿触发
高电平触发
低电平触发
所以总结,exynos4412的GIC中断控制器(interrupt controller)通过中断类型、中断号、中断触发方式这三个要素可以描述一个唯一指定的中断。这种能够描述出系统中唯一中断的要素组合称为interrupt specifier
所以DTS中接在GIC的device node的interrupts属性也是用这三个要素来描述一个具体的中断。
格式如:interrupts =
Interrrupt Types
Interrrupt Number
Trigger Type
0 = SPI
1 = PPI
32
… …
1019
1 = low to high
2 = high to low
4 = high level
8 = low level
Interrupt Combiner
除了GIC这个controller外Exynos4412还有一个Combiner的interrupt controller。Combiner的硬件细节如下所示:
可以看到,连接到combiner控制器上的多个中断源会共享一个中断号,且这些中断都属于SPI类型。所以描述一个combiner的中断应该要包含两个要素。
interrupts =
DTS对中断的描述
DTS中采用中断树来描述中断的连接信息以及级联情况等。但中断树和设备树的结构不一样,中断树是一个"倒树"。设备树都是从root到leaf的顺序来描述的,比如DTS都有一个root node,cpus、mem等都是它的子节点,而cpus或者mem节点下又分cpu@0、cpu@1等子节点。但中断树不一样,中断产生设备中会嵌入一个interrupt-parent属性,这个interrupt-parent会被赋值一个phandle变量,通过phandle指明这个设备中断物理上的连接关系。但并不是所有的中断产生设备节点都会显式定义interrupt-parent属性。如果一个中断产生设备没有定义interrupt-parent,那他的interrupt-parent就是设备树中的parent。所以根据前面的描述,中断树的连接关系是先找中断产生设备device node,然后找到这个node连接的interrupt-parent,所以和DTS的device node组织结构相比是倒过来的。
中断子树也可称之为中断域(interrupt domain)。同一个中断域下,设备的interrupt属性具有相同的格式和释义。中断树由多个中断域组成。
每个中断产生设备都采用一个interrupt属性来描述该设备的中断源信息,也称之为中断描述符。中断描述符的格式和含义是由interrupt domain决定。interrupt domian的根节点会有一个interrupt-cells属性来决定域内中断描述符占用的数目。比如像Open PIC中断控制器的中断描述符就需要中断号和中断触发类型两个<32>来描述
中断域是定义中断描述符的上下文(context)。一个中断域的根可以是interrupt-controller也可以是一个interrupt nexus。
1.interrupt-controller: 它是一个物理设备,需要驱动支持来处理连接到它的中断。
2.interrupt nexus(interrupt-map): 实现从一个interrupt domain转化到另一个interrupt domain。通过定义interrupt-map属性来实现。例如PCIE的中断需要映射到系统的IRQ。
3.interrupt-cells: 一个中断描述符所需的数目
4.interrupt-parent: 为了让中断树能反映实际上的物理连接层次关系,定义了interrupt-parent属性。比如一颗SoC,有外部中断通过GPIO子系统然后连接到GIC上;也有SoC集成的UART,I2C等控制器上的中断直连到GIC上。外部中断的interrupt-parent可以设为GPIO,而UART的interrupt-parent则可设置为interrupt-controller(GIC)
DTS中断实例解析
以exynos4412-tiny4412.dts为例解析DTS中关于中断相关属性的用法。
因为exynos4412-tiny4412.dts使用了include其它dts,所以总共涉及的dts文件如下:
exynos4412-tiny4412.dts
exynos4412.dtsi
exynos4x12.dtsi
exynos4.dtsi
exynos4x12-pinctrl.dtsi
[1]:《Open Firmware. Recommended Practice: Interrupt Mapping. Version 0.9. Unapproved DRAFT.》
[2]: 《Devicetree Specification Release v0.2-21-g15cd53d》