什么是linux irq域,为什么需要它们?
什么是irq域,我阅读了内核文档()它们说: 注册为唯一irqchips的中断控制器的数量 显示上升趋势:例如,不同类型的子驱动程序 例如GPIO控制器避免重新实现相同的回调 通过对中断进行建模,将机制作为IRQ核心系统 处理器作为irqchips,即实际上是级联中断控制器什么是linux irq域,为什么需要它们?,linux,linux-kernel,linux-device-driver,embedded-linux,interrupt,max732x.c,Linux,Linux Kernel,Linux Device Driver,Embedded Linux,Interrupt,Max732x.c,什么是irq域,我阅读了内核文档()它们说: 注册为唯一irqchips的中断控制器的数量 显示上升趋势:例如,不同类型的子驱动程序 例如GPIO控制器避免重新实现相同的回调 通过对中断进行建模,将机制作为IRQ核心系统 处理器作为irqchips,即实际上是级联中断控制器 如何将GPIO控制器称为中断控制器?我在include/linux/irqdomain.h中找到了一条评论: 中断控制器“域”数据结构。这可以定义为 irq域控制器。也就是说,它处理 给定中断域的硬件和虚拟中断号 我认为它所
如何将GPIO控制器称为中断控制器?我在include/linux/irqdomain.h中找到了一条评论: 中断控制器“域”数据结构。这可以定义为 irq域控制器。也就是说,它处理 给定中断域的硬件和虚拟中断号 我认为它所指的实际结构是irq_域 什么是linux irq域,为什么需要它们 它在的第一段中有很好的记录,所以我假设你已经知道了。如果没有--请询问关于该文档的哪些内容不清楚。下面的文本解释了如何使用IRQ域API及其工作原理 如何将GPIO控制器称为中断控制器 让我以驱动程序作为参考()来回答这个问题。它是一个GPIO驱动程序,它的作用也类似于中断控制器,所以它应该是IRQ域API如何工作的一个很好的例子 身体水平 为了完全理解进一步的解释,让我们首先了解MAX732x力学。应用电路来自(简化为我们的示例): 当P0-P7引脚上的电压电平发生变化时,MAX7325将在INT引脚上产生中断。驱动器(在SoC上运行)可以通过I2C(SCL/SDA引脚)读取P0-P7引脚的状态,并为每个P0-P7引脚生成单独的中断。这就是为什么这个驱动程序充当中断控制器的原因 考虑下一个配置: “某些设备”改变P4引脚的电平,诱使MAX7325产生中断。来自MAX7325的中断连接到GPIO4 IP核(SoC内部),它使用该GPIO4模块的第29行通知CPU中断。所以我们可以说MAX7325是级联到GPIO4控制器的。GPIO4还充当中断控制器,并级联到GIC中断控制器 设备树 让我们在设备树中声明上述配置。我们可以使用中的绑定作为参考:
expander: max7325@6d {
compatible = "maxim,max7325";
reg = <0x6d>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
interrupt-parent = <&gpio4>;
interrupts = <29 IRQ_TYPE_EDGE_FALLING>;
};
中断传播
现在我们可以这样做(在“某些设备”驱动程序中):
devm\u请求\u线程化\u irq(core->dev,core->gpio\u irq,NULL,
一些设备isr,IRQF触发上升,IRQF一次性,
设备名称(核心->设备),核心);
当MAX7325的P4引脚上的电平从低到高(上升沿)时,每次都会调用一些设备isr()。它是如何工作的?从左到右,如果您查看上图:
- “某些设备”更改MAX7325的P4上的电平
- MAX7325更改其INT引脚的电平
- GPIO4模块被配置为捕捉这样的变化,所以它生成GIC的中断
- GIC通知CPU
- CPU现在处于GIC中断处理程序中的中断上下文中。它从中调用
,然后调用handle\u domain\u irq()
。有关详细信息,请参阅。现在我们在SoC的GPIO控制器IRQ处理器中generic\u handle\u irq()
- SoC的GPIO驱动程序还调用
来运行为每个特定管脚设置的处理程序。例如,请参见在中是如何完成的。现在我们使用的是MAX7325 IRQ处理程序generic\u handle\u irq()
- MAX7325 IRQ处理程序()调用
,以便连接到MAX7325的设备的所有IRQ处理程序(在我们的例子中为“某些设备”IRQ处理程序)都将在handle\u-nested\u-IRQ()
线程中调用max732x\u-IRQ\u处理程序()
- 最后,调用“某个设备”驱动程序的IRQ处理程序
max732x\u irq\u handler()
中):
handle_nested_irq(irq_find_映射(chip->gpio_chip.irqdomain,level));
irq\u find\u mapping()
将按硬件irq编号查找linux irq编号(使用irq domainmapping函数)。然后将调用handle\u nested\u irq()
函数,该函数将运行“某个设备”驱动程序的irq处理程序
GPIOLIB_IRQCHIP
由于许多GPIO驱动程序以相同的方式使用IRQ域,因此决定将该代码提取到GPIOLIB框架,更具体地说,提取到GPIOLIB_IRQCHIP。从文档/gpio/driver.txt
:
帮助处理GPIO irqchips和
关联的irqdomain和资源分配回调,gpiolib
可通过选择GPIOLIB\u IRQCHIP
Kconfig启用的一些帮助程序
符号:
:将irqchip添加到gpiochip。它会过去的 芯片的gpiochip\u irqchip\u add()
用于所有IRQ回调,因此回调 需要将struct gpio_chip*
嵌入其状态容器并获取指针 使用gpio_芯片
连接到容器。 (请参见container\u of()
)文档/driver model/design patterns.txt
:为gpiochip\u set\u chained\u irqchip()
来自父IRQ,并将gpio_芯片
作为处理程序传递 数据。(注意处理程序数据,因为irqchistruct gpio_芯片*
some_device: some_device@1c { reg = <0x1c>; interrupt-parent = <&expander>; interrupts = <4 IRQ_TYPE_EDGE_RISING>; };