1 设备树里中断节点的语法
参考文档:
内核 Documentation\devicetree\bindings\interrupt-controller\interrupts.txt
设备树里的中断控制器
中断的硬件框图如下:
在硬件上,“中断控制器”只有 GIC 这一个,但是我们在软件上也可以把上图中的“ GPIO”称为“中断控制器”。很多芯片有多个 GPIO 模块,比如 GPIO1、GPIO2 等等。所以软件上的“中断控制器”就有很多个: GIC、 GPIO1、 GPIO2 等等。
GPIO1 连接到 GIC, GPIO2 连接到 GIC,所以 GPIO1 的父亲是 GIC, GPIO2的父亲是 GIC。
假设 GPIO1 有 32 个中断源,但是它把其中的 16 个汇聚起来向 GIC 发出一个中断,把另外 16 个汇聚起来向 GIC 发出另一个中断。这就意味着 GPIO1 会用到 GIC 的两个中断,会涉及 GIC 里的 2 个 hwirq。
这些层级关系、中断号(hwirq),都会在设备树中有所体现。
在设备树中,中断控制器节点中必须有一个属性: interrupt-controller,表明它是“中断控制器”。
还必须有一个属性: #interrupt-cells,表明引用这个中断控制器的话需要多少个 cell。
#interrupt-cells 的值一般有如下取值:
⚫ #interrupt-cells=<1>
别的节点要使用这个中断控制器时,只需要一个 cell 来表明使用“哪一个中断”。
⚫ #interrupt-cells=<2>
别的节点要使用这个中断控制器时,需要一个 cell 来表明使用“哪一个中断”;还需要另一个 cell 来描述中断,一般是表明触发类型:
示例如下:
如 果 中 断 控 制 器 有 级 联 关 系 , 下 级 的 中 断 控 制 器 还 需 要 表 明 它 的“ interrupt-parent ” 是 谁 , 用 了 interrupt-parent ” 中 的 哪 一 个“ interrupts”,请看下一小节。
设备树里使用中断
一个外设,它的中断信号接到哪个“中断控制器”的哪个“中断引脚”,这个中断的触发方式是怎样的?
这 3 个问题,在设备树里使用中断时,都要有所体现。
⚫ interrupt-parent=<&XXXX>
你要用哪一个中断控制器里的中断?
⚫ interrupts
你要用哪一个中断?
Interrupts 里要用几个 cell,由 interrupt-parent 对应的中断控制器决定。在中断控制器里有“ #interrupt-cells”属性,它指明了要用几个 cell来描述中断。比如:
⚫ 新写法: interrupts-extended
一个“ interrupts-extended”属性就可以既指定“ interrupt-parent”,也指定“ interrupts”,比如:
interrupts-extended = <&intc1 5 1>, <&intc2 1 0>;
2 设备树里中断节点的示例
以 100ASK_IMX6ULL 开发板为例,在 arch/arm/boot/dts 目录下可以看到2 个文件: imx6ull.dtsi、 100ask_imx6ull-14x14.dts,把里面有关中断的部分内容抽取出来。
从设备树反推 IMX6ULL 的中断体系,如下,比之前的框图多了一个“ GPC INTC”:
GPC INTC 的 英 文 是 : General Power Controller, Interrupt Controller。它提供中断屏蔽、中断状态查询功能,实际上这些功能在 GIC 里也实现了,个人觉得有点多余。除此之外,它还提供唤醒功能,这才是保留它的原因。
3 在代码中获得中断
之 前 我 们 提 到 过 , 设 备 树 中 的 节 点 有 些 能 被 转 换 为 内 核 里 的platform_device,有些不能,回顾如下:
- 根节点下含有 compatile 属性的子节点,会转换为 platform_device
- 含有特定 compatile 属性的节点的子节点,会转换为 platform_device
如果一个节点的 compatile 属性,它的值是这 4 者之一: "simplebus","simple-mfd","isa","arm,amba-bus",
那么它的子结点(需含 compatile 属性)也可以转换为 platform_device。
- 总线 I2C、 SPI 节点下的子节点: 不转换为 platform_device
某个总线下到子节点, 应该交给对应的总线驱动程序来处理, 它们不应该被转换为 platform_device
对于 platform_device
一个节点能被转换为 platform_device,如果它的设备树里指定了中断属性,那么可以从 platform_device 中获得“中断资源”,函数如下,可以使用下列函数获得 IORESOURCE_IRQ 资源,即中断号:
对于 I2C 设备、 SPI 设备
对于 I2C 设备节点, I2C 总线驱动在处理设备树里的 I2C 子节点时,也会处理其中的中断信息。一个 I2C 设备会被转换为一个 i2c_client 结构体,中断号会保存在 i2c_client 的 irq 成员里,代码如下(drivers/i2c/i2c-core.c):
对于 SPI 设备节点, SPI 总线驱动在处理设备树里的 SPI 子节点时,也会处理其中的中断信息。一个 SPI 设备会被转换为一个 spi_device 结构体,中断号会保存在 spi_device 的 irq 成员里,代码如下(drivers/spi/spi.c):
调用 of_irq_get 获得中断号
如果你的设备节点既不能转换为 platform_device,它也不是 I2C 设备,不是 SPI 设备,那么在驱动程序中可以自行调用 of_irq_get 函数去解析设备树,得到中断号。
对于 GPIO
参考: drivers/input/keyboard/gpio_keys.c
可以使用 gpio_to_irq 或 gpiod_to_irq 获得中断号。举例,假设在设备树中有如下节点:
标签:中断,代码,device,GIC,interrupt,树中,节点,设备 From: https://www.cnblogs.com/liusiluandzhangkun/p/18450254