foss-for-synopsys-dwc-arc-processors / linux

Helpful resources for users & developers of Linux kernel for ARC
22 stars 13 forks source link

[Question] How to register IRQ handler to the IDU-intc on Linux? #52

Closed wimowa closed 3 years ago

wimowa commented 3 years ago

Dear all,

Our environment has 4 Hs48 cores, and per core have 32 IDU interrupts. I review linux/arch/arc/boot/dts/haps_hs_idu.dts in order to get more understanding about IDU.

    core_intc: interrupt-controller {
        compatible = "snps,archs-intc";
        interrupt-controller;
        #interrupt-cells = <1>;
    };

    idu_intc: idu-interrupt-controller {
        compatible = "snps,archs-idu-intc";
        interrupt-controller;
        interrupt-parent = <&core_intc>;
        #interrupt-cells = <1>;
    };

    uart0: serial@f0000000 {
        compatible = "ns16550a";
        reg = <0xf0000000 0x2000>;
        interrupt-parent = <&idu_intc>;
        interrupts = <0>;
        clock-frequency = <50000000>;
        baud = <115200>;
        reg-shift = <2>;
        reg-io-width = <4>;
        no-loopback-test = <1>;
    };

Does this means Uart interrupt will connect to IDU common interrupt#0 ? and then propagate to 4 HS48 cores?

So when I implement the Uart Interrupt Handler in Uart driver, do I still call request_irq (~) to register Uart_Interrupt_Handler with IRQ number = 0 ?

Please help me to figure out how to register an ISR to IDU-inct on Linux.

If there is any sample code for me to reference, that will be so so so nice.... Thank you so much.

Best Regards, Sophie

evgeniy-paltsev commented 3 years ago

Hi!

Does this means Uart interrupt will connect to IDU common interrupt#0 ?

Correct.

and then propagate to 4 HS48 cores?

Correct. I should note there that we don't send interrupt to all cores simultaneously but we send it to one CPU core which is chosen with round-robin algorithm.

The hardware itself allows to configure IRQ scheduling to cores: which core(s) to deliver to and algorithm of core(s) selection, however in case of ARC linux we don't support such configuration (in build or run time) and use round-robin algorithm as described above.

So when I implement the Uart Interrupt Handler in Uart driver, do I still call request_irq (~) to register Uart_Interrupt_Handler with IRQ number = 0 ?

You can check the interrupt setup code the ns16550a driver itself and use it as a reference. From the driver side we don't require any arc-specific handling no mater the IDU used or not.

Interrupt line number get: https://elixir.bootlin.com/linux/latest/source/drivers/tty/serial/8250/8250_of.c#L129 Interrupt request: https://elixir.bootlin.com/linux/latest/source/drivers/tty/serial/8250/8250_core.c#L212

Note that we don't use hw irq line number in driver explicitly. The 0 in the of_irq_get parameter

irq = of_irq_get(np, 0);

has nothing to deal with

interrupts = <0>;

in the device tree node.

Index 0 in the of_irq_get parameter means that we are getting first of the interrupts described in the corresponding device tree node. In the uart0: serial@f0000000 we specify only one interrupt, so the indeх is 0.

PS: there is an article with some details about interrupts in Linux kernel. https://www.kernel.org/doc/html/latest/core-api/irq/irq-domain.html