Using irq-crossbar.c

Sebastian Frias
2016-06-10T15:37:37Z

Hi,

We are trying to write a driver for an interrupt controller (actually more of a crossbar) for an ARM-based SoC.
This IRQ crossbar has 128 inputs and 24 outputs, the outputs are connected directly to the GIC.
The idea is that the GIC handles everything, and just request a mapping from an IRQ number (0...127, from a device's DT entry) into one of its 24 input lines.

By looking at current code (4.7-rc1) there seems to be a driver (drivers/irqchip/irq-crossbar.c) that provides similar functionality.
The driver uses hierarchical irq domains (since commit 783d31863fb8 "irqchip: crossbar: Convert dra7 crossbar to stacked domains") which we believe we don't need because the only controller is the GIC.
However the API used previously, register_routable_domain_ops(), was removed with commit a5561c3e845c "irqchip: gic: Get rid of routable domain".

Trying to use the driver with hierarchical domains (after modifications for our SoC), results on the kernel being blocked at some point:

[ 0.041524] ThumbEE CPU extension supported.
[ 0.041589] Registering SWP/SWPB emulation handler
[ 0.052022] Freeing unused kernel memory: 12364K (c029b000 - c0eae000)
[ 0.074084] random: dbus-uuidgen urandom read with 0 bits of entropy available

We've put logs on the different domain_ops calls (alloc, free, translate) but they are not called, even if the DT is supposed to tell devices to take interrupts from this controller (*).

Do you have suggestions on what APIs should be used, further reading/examples and/or pointers on how debug this (logs to enable, things to look for, etc.)?

Thanks in advance.
Best regards,

Sebastian

(*):
here's the diff on our DT:

--- tango4-common.dtsi 2016-06-10 16:23:08.244246017 +0200
+++ tangox_irqv2-common.dtsi 2016-06-10 16:24:01.212588737 +0200
@@ -47,7 +47,7 @@

soc {
compatible = "simple-bus";
- interrupt-parent = <&irq0>;
+ interrupt-parent = <&irq_mux>;
#address-cells = <1>;
#size-cells = <1>;
ranges;
@@ -75,7 +75,7 @@
uart: serial@10700 {
compatible = "ralink,rt2880-uart";
reg = <0x10700 0x30>;
- interrupts = <1 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
clock-frequency = <7372800>;
reg-shift = <2>;
};
@@ -83,10 +83,11 @@
eth0: ethernet@26000 {
compatible = "sigma,smp8734-ethernet";
reg = <0x26000 0x800>;
- interrupts = <38 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clkgen 1>;
};

+#if 0
intc: interrupt-controller@6e000 {
compatible = "sigma,smp8642-intc";
reg = <0x6e000 0x400>;
@@ -117,5 +118,16 @@
interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
};
};
+#else
+ irq_mux: irq_mux@6f800 {
+ compatible = "sigma,smp-irq-mux";
+ reg = <0x6f800 0x400>;
+ interrupt-controller;
+ interrupt-parent = <&gic>;
+ irqs-reserved = <2 3 4 125 126 127>;
+ };
+
+#endif
+
};
};