Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reading Device tree node with Interrupt property

I have following snippets the from two different Device tree source.

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>;
            };

I would want to know What does interrupts = <1 4>; interrupts = <42 2>; stand for?

Where do we get <1 4> , <42 2> values from?

like image 268
Amit Singh Tomar Avatar asked Dec 25 '22 02:12

Amit Singh Tomar


1 Answers

You need a little more context to determine what those interrupts properties represent. Taking something similar to your first example, let's look at arch/powerpc/boot/dts/bamboo.dts, which has the following:

        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>;
        };

The interrupts property describes a connection from this device to the interrupt controller. Assuming that the controller has multiple inputs (ie, the interrupt lines), we need to find out which one of the lines that this device will interact with.

Different controllers may have different methods of demultiplexing their IRQs, hence the variation in property types. In this case, let's take a look at the interrupt controller. We see that the serial@ef600400 node has the following property:

            interrupt-parent = <&UIC0>;

The &UIC0 syntax tells us that there's a UIC0 label elsewhere in the device tree. That's our interrupt controller. If we find that label, we see:

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>;
};

Firstly, we see that #interrupt-cells is 2 - this means that each interrupt descriptor occupies two cells. Since the serial device's interrupt property has two cells (0x1 and 0x4), this tells us that there's one interrupt line being described.

The compatible property tells us that this is an IBM UIC interrupt controller. If we take a look at the driver for this controller, we see:

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

That xlate function is what's used to map the interrupt sources' interrupts properties to a hardware IRQ number (and possibly its IRQ type). The irq_domain_xlate_twocell function is pretty straightforward:

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;
}

So (and as Peter L mentioned in his comment), in this case the two cells <0x1 0x4> represent the interrupt line 1, and a level-high (0x4 == IRQ_TYPE_LEVEL_HIGH) interrupt type.

Your second example is a little more complex: it uses an mpic interrupt controller, which has its own xlate function. Have a look at mpic_host_xlate in arch/powerpc/sysdev/mpic.c for the internal details.

like image 181
Jeremy Kerr Avatar answered Jan 03 '23 06:01

Jeremy Kerr