什么是 irq 域,我阅读了内核文档( https://www.kernel.org/doc/Documentation/IRQ-domain.txt ),他们说:
The number of interrupt controllers registered as unique irqchips show a rising tendency: for example subdrivers of different kinds such as GPIO controllers avoid reimplementing identical callback mechanisms as the IRQ core system by modeling their interrupt handlers as irqchips, i.e. in effect cascading interrupt controllers.
GPIO Controller 如何称为中断 Controller ?
最佳答案
What are linux irq domains, why are they needed?
它在 Documentation/IRQ-domain.txt 的第一段中得到了完美的记录。 ,所以我假设你已经知道了。如果不是 - 请询问该文档有哪些不清楚的地方。下面的文本解释了如何使用 IRQ 域 API 及其工作原理。
How GPIO controller can be called as interrupt controller?
让我用 max732x.c 回答这个问题驱动程序作为引用( driver code )。它是一个 GPIO 驱动程序,它也充当中断 Controller ,因此它应该是 IRQ 域 API 如何工作的一个很好的例子。
body 水平
为了完全理解进一步的解释,让我们先看看 MAX732x 的机制。应用电路来自datasheet (为我们的示例简化):
当 P0-P7 引脚上的电压电平发生变化时,MAX7325 将在 INT 引脚上产生中断。驱动程序(在 SoC 上运行)可以通过 I2C(SCL/SDA 引脚)读取 P0-P7 引脚的状态,并为每个 P0-P7 引脚生成单独的中断。这就是为什么这个驱动程序充当 中断 Controller .
考虑下一个配置:
“某些设备”改变 P4 引脚上的电平,诱使 MAX7325 产生中断。来自 MAX7325 的中断连接到 GPIO4 IP 核(在 SoC 内部),它使用该 GPIO4 模块的第 29 行来通知 CPU 中断。所以我们可以说MAX7325是级联 到 GPIO4 Controller 。 GPIO4 也作为中断 Controller ,它级联到 GIC 中断 Controller 。
设备树
让我们在设备树中声明上述配置。我们可以使用来自 Documentation/devicetree/bindings/gpio/gpio-max732x.txt 的绑定(bind)作为引用:
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>;
};
属性的含义如下:
interrupt-controller
属性定义设备产生中断;进一步需要将此节点用作 interrupt-parent
在“某些设备”节点中。 #interrupt-cells
定义 interrupts
的格式属性(property);在我们的例子中是 2
: 1 个单元格用于行号,1 个单元格用于中断类型 interrupt-parent
和 interrupts
属性描述中断线连接假设我们有 MAX7325 的驱动程序和“某些设备”的驱动程序。当然,两者都在 CPU 中运行。在“Some device”驱动程序中,当“Some device”改变 MAX7325 的 P4 引脚电平时,我们希望请求事件中断。让我们首先在设备树中声明:
some_device: some_device@1c {
reg = <0x1c>;
interrupt-parent = <&expander>;
interrupts = <4 IRQ_TYPE_EDGE_RISING>;
};
中断传播
现在我们可以做这样的事情(在“某些设备”驱动程序中):
devm_request_threaded_irq(core->dev, core->gpio_irq, NULL,
some_device_isr, IRQF_TRIGGER_RISING | IRQF_ONESHOT,
dev_name(core->dev), core);
和
some_device_isr()
每次当 MAX7325 的 P4 引脚上的电平从低到高(上升沿)时都会被调用。这个怎么运作?从左到右,如果你看上图:所有这些操作都发生在硬件级别。让我们看看在软件层面发生了什么。它实际上是倒退的(从图片上的右到左):
handle_domain_irq()
,反过来调用 generic_handle_irq()
.见 Documentation/gpio/driver.txt详情。现在我们在 SoC 的 GPIO Controller IRQ 处理程序中。 generic_handle_irq()
运行处理程序,这是为每个特定引脚设置的。参见例如它是如何在 omap_gpio_irq_handler() 中完成的.现在我们在 MAX7325 IRQ 处理程序中。 handle_nested_irq()
,以便所有连接到 MAX7325 的设备的 IRQ 处理程序(“某些设备”IRQ 处理程序,在我们的例子中)将在 max732x_irq_handler()
中被调用。线程 IRQ 域 API
GIC 驱动程序、GPIO 驱动程序和 MAX7325 驱动程序——它们都使用 IRQ 域 API 将这些驱动程序表示为中断 Controller 。让我们来看看它是如何在 MAX732x 驱动程序中完成的。它是在 this 中添加的犯罪。只需阅读 IRQ 域文档并查看此提交,就很容易弄清楚它是如何工作的。该提交中最有趣的部分是这一行(在
max732x_irq_handler()
中):handle_nested_irq(irq_find_mapping(chip->gpio_chip.irqdomain, level));
irq_find_mapping()
将通过硬件 IRQ 号找到 linux IRQ 号(使用 IRQ 域 映射 函数)。然后handle_nested_irq()
将调用函数,该函数将运行“某些设备”驱动程序的 IRQ 处理程序。GPIOLIB_IRQCHIP
由于许多 GPIO 驱动程序都以相同的方式使用 IRQ 域,因此决定将该代码提取到 GPIOLIB 框架,更具体地说是 GPIOLIB_IRQCHIP。来自
Documentation/gpio/driver.txt
:To help out in handling the set-up and management of GPIO irqchips and the associated irqdomain and resource allocation callbacks, the gpiolib has some helpers that can be enabled by selecting the
GPIOLIB_IRQCHIP
Kconfig symbol:
gpiochip_irqchip_add()
: adds an irqchip to a gpiochip. It will pass thestruct gpio_chip*
for the chip to all IRQ callbacks, so the callbacks need to embed thegpio_chip
in its state container and obtain a pointer to the container usingcontainer_of()
. (SeeDocumentation/driver-model/design-patterns.txt
)
gpiochip_set_chained_irqchip()
: sets up a chained irq handler for agpio_chip
from a parent IRQ and passes thestruct gpio_chip*
as handler data. (Notice handler data, since the irqchip data is likely used by the parent irqchip!) This is for the chained type of chip. This is also used to set up a nested irqchip ifNULL
is passed as handler.
This commit 将 IRQ 域 API 转换为 MAX732x 驱动程序中的 GPIOLIB_IRQCHIP API。
下一个问题
进一步的讨论在这里:
关于linux - 什么是 linux irq 域,为什么需要它们?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34371352/