Linux内核 -- irq_of_parse_and_map 接口使用详解

irq_of_parse_and_map 接口详解

irq_of_parse_and_map 是 Linux 内核中用于处理设备树(Device Tree)中的中断映射的一个常用接口。它主要用于将设备树中定义的中断资源解析并映射到一个 IRQ 号,以便内核能够识别和管理这些中断。

函数原型

unsigned int irq_of_parse_and_map(struct device_node *dev, int index);

参数详解

  • dev: 这是一个指向设备节点(struct device_node)的指针,代表了设备树中的一个节点。这个节点通常包含了中断控制器相关的信息。
  • index: 这是一个整数,表示在设备树中需要解析的中断号的索引。由于一个设备可能有多个中断,所以使用索引来选择具体的中断。

返回值

  • 成功时,返回一个有效的 IRQ 号。
  • 失败时,返回 0,表示中断映射失败。

工作原理

  1. 解析设备树: irq_of_parse_and_map 函数首先会根据传入的设备节点和索引,查找设备树中相应的中断控制器信息。
  2. 中断映射: 找到中断信息后,函数会调用中断控制器的相关回调函数,将设备树中的中断描述符映射成内核能够处理的 IRQ 号。
  3. 返回 IRQ 号: 映射成功后,函数返回对应的 IRQ 号。这个 IRQ 号可以用于后续的中断处理,比如 request_irq 等。

典型用法

通常在设备驱动程序中使用 irq_of_parse_and_map 函数来解析和映射设备树中的中断信息,例如:

struct device_node *np = of_find_node_by_name(NULL, "my-device");
unsigned int irq = irq_of_parse_and_map(np, 0);
if (!irq) {
    pr_err("Failed to map IRQ for my-device
");
    return -ENODEV;
}

ret = request_irq(irq, my_irq_handler, 0, "my-device-irq", dev);
if (ret) {
    pr_err("Failed to request IRQ %u for my-device
", irq);
    return ret;
}

设备树中的中断描述

设备树使用一种叫做 “Flattened Device Tree” (FDT) 的结构来表示硬件资源。每个硬件设备在设备树中都有一个节点,这个节点可以包含多个属性来描述设备的特性。其中,中断资源通常通过 interruptsinterrupt-parent 属性来描述。

设备树节点示例

假设我们有一个设备树节点描述如下:

my_device: my_device@1000 {
    compatible = "mycompany,my-device";
    reg = <0x1000 0x100>;
    interrupts = <3 1>; /* 中断号3,触发类型1(例如:高电平触发) */
    interrupt-parent = <&intc>; /* 指向中断控制器 */
};

这里的设备树节点描述了一个名为 my_device 的设备,它在 0x1000 地址处有寄存器区域,并且有一个中断资源。interrupts 属性定义了中断号和触发类型,而 interrupt-parent 属性指定了中断控制器(intc)的引用。

irq_of_parse_and_map 如何与设备树关联

在驱动程序中,通常需要从设备树中读取这个中断信息,并将其映射为内核中的 IRQ 号。使用 irq_of_parse_and_map 就可以做到这一点。

驱动程序中的代码示例

struct device_node *np;
unsigned int irq;

/* 找到设备节点 */
np = of_find_node_by_name(NULL, "my_device");
if (!np) {
    pr_err("Failed to find device node for my_device
");
    return -ENODEV;
}

/* 解析并映射设备树中的中断 */
irq = irq_of_parse_and_map(np, 0);
if (!irq) {
    pr_err("Failed to map IRQ for my_device
");
    return -ENODEV;
}

/* 请求中断 */
ret = request_irq(irq, my_irq_handler, 0, "my_device_irq", dev);
if (ret) {
    pr_err("Failed to request IRQ %u for my_device
", irq);
    return ret;
}

设备树与 irq_of_parse_and_map 的关联

  • 中断描述: 设备树节点中的 interrupts 属性描述了中断号和触发方式,而 interrupt-parent 指定了中断控制器。
  • 中断解析: irq_of_parse_and_map 使用这些信息解析出设备的中断号,并与系统内的中断资源相对应。
  • 设备树的灵活性: 通过设备树,硬件资源和配置从内核代码中解耦出来,使得内核更加通用,并且可以通过设备树轻松适配不同的硬件平台。

总结

irq_of_parse_and_map 是驱动程序中与设备树中断描述紧密相关的重要接口。它通过解析设备树中定义的中断信息,将硬件中断资源映射到内核可识别的 IRQ 号,为设备的正常工作提供了关键支持。在设备驱动开发中,理解设备树的中断定义及其与 irq_of_parse_and_map 的关联,对于正确处理硬件中断至关重要。

of_find_node_by_name 中设备节点名称的使用

在设备树中使用 of_find_node_by_name 函数时,传递给该函数的名字应该是 : 前面的部分,即设备树节点名称,而不是 : 后面的部分。

示例

假设我们有以下设备树节点:

my_device: my_device@1000 {
    compatible = "mycompany,my-device";
    reg = <0x1000 0x100>;
    interrupts = <3 1>;
    interrupt-parent = <&intc>;
};

在这个示例中,my_device: 是设备节点的标签,my_device@1000 是设备节点的名称。在调用 of_find_node_by_name 时,应该传递节点的名称 my_device@1000,而不是标签 my_device

代码示例

struct device_node *np;

/* 查找设备树中的节点,使用节点名称 */
np = of_find_node_by_name(NULL, "my_device@1000");
if (!np) {
    pr_err("Failed to find device node for my_device@1000
");
    return -ENODEV;
}

总结

  • : 前的部分: 这是设备树节点的标签,用于在设备树中唯一标识这个节点,通常用于引用。
  • : 后的部分: 这是设备树节点的名称,of_find_node_by_name 应该使用这个名称来查找节点。

在使用 of_find_node_by_name 时,填入的应该是设备树中 : 后面的部分,即节点名称,如 my_device@1000

上一篇:UE5: Content browser工具编写02
下一篇:SQL案例分析:计算延迟法定退休年龄