linux-kernel之读取具有中断属性的设备树节点

lautakyan007 阅读:13 2024-08-06 10:45:09 评论:0

我有以下来自两个不同设备树源的片段。

UART1: serial@ef600400 { 
              device_type = "serial"; 
              compatible = "ns16550"; 
              reg = <0xef600400 8>; 
              virtual-reg = <0xef600400>; 
              clock-frequency = <0x00a8c000>; 
              current-speed = <0>; 
              interrupt-parent = <&UIC0>; 
              interrupts = <1 4>; 
                    }; 
 
 
serial0: serial@4500 { 
                    cell-index = <0>; 
                    device_type = "serial"; 
                    compatible = "ns16550"; 
                    reg = <0x4500 0x100>; 
                    clock-frequency = <0>; 
                    interrupts = <42 2>; 
                    interrupt-parent = <&mpic>; 
            }; 

我想知道什么是中断 = <1 4>;中断 = <42 2>;代表?

我们从哪里得到 <1 4> , <42 2> 值?

请您参考如下方法:

您需要更多的上下文来确定那些 interrupts属性代表。以类似于您的第一个示例的内容为例,让我们看看 arch/powerpc/boot/dts/bamboo.dts , 具有以下内容:

        UART1: serial@ef600400 { 
            device_type = "serial"; 
            compatible = "ns16550"; 
            reg = <0xef600400 0x00000008>; 
            virtual-reg = <0xef600400>; 
            clock-frequency = <0>; 
            current-speed = <0>; 
            interrupt-parent = <&UIC0>; 
            interrupts = <0x1 0x4>; 
        }; 
interrupts属性描述了从该设备到中断 Controller 的连接。假设 Controller 有多个输入(即中断线),我们需要找出该设备将与哪一条线进行交互。

不同的 Controller 可能有不同的方法来解复用它们的 IRQ,因此属性类型会有所不同。在这种情况下,让我们来看看中断 Controller 。我们看到 serial@ef600400节点具有以下属性:
            interrupt-parent = <&UIC0>; 
&UIC0语法告诉我们在设备树的其他地方有一个 UIC0 标签。那是我们的中断 Controller 。如果我们找到那个标签,我们会看到:
UIC0: interrupt-controller0 { 
    compatible = "ibm,uic-440ep","ibm,uic"; 
    interrupt-controller; 
    cell-index = <0>; 
    dcr-reg = <0x0c0 0x009>; 
    #address-cells = <0>; 
    #size-cells = <0>; 
    #interrupt-cells = <2>; 
}; 

首先,我们看到 #interrupt-cells是 2 - 这意味着每个中断描述符占用两个单元格。由于串口设备的 interrupt属性有两个单元格(0x1 和 0x4),这告诉我们有一条中断线被描述。
compatible属性告诉我们这是一个 IBM UIC 中断 Controller 。如果我们查看此 Controller 的驱动程序,我们会看到:

static struct irq_domain_ops uic_host_ops = { 
    .map    = uic_host_map, 
    .xlate  = irq_domain_xlate_twocell, 
}; 

该 xlate 函数用于映射中断源的 interrupts属性到硬件 IRQ 号(可能还有它的 IRQ 类型)。 irq_domain_xlate_twocell函数非常简单:

int irq_domain_xlate_twocell(struct irq_domain *d, struct device_node *ctrlr, 
            const u32 *intspec, unsigned int intsize, 
            irq_hw_number_t *out_hwirq, unsigned int *out_type) 
{ 
    if (WARN_ON(intsize < 2)) 
        return -EINVAL; 
    *out_hwirq = intspec[0]; 
    *out_type = intspec[1] & IRQ_TYPE_SENSE_MASK; 
    return 0; 
} 

所以(正如 Peter L 在他的评论中提到的),在这种情况下,两个单元格 <0x1 0x4>代表中断线1,和一个高电平(0x4 == IRQ_TYPE_LEVEL_HIGH)中断类型。

你的第二个例子有点复杂:它使用了一个 mpic 中断 Controller ,它有自己的 xlate功能。看看 mpic_host_xlatearch/powerpc/sysdev/mpic.c对于内部细节。


标签:linux
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

关注我们

一个IT知识分享的公众号