Re: Using irq-crossbar.c

From: Sebastian Frias
Date: Mon Jun 13 2016 - 10:57:22 EST


Hi Lennart,

Thanks for your input, please find my comments below.

On 06/13/2016 04:04 PM, Lennart Sorensen wrote:
> On Sat, Jun 11, 2016 at 05:37:51PM +0200, Mason wrote:
>> Only the name of the file was provided, not the path. I was not aware
>> that you already knew where to find it. I made no claim whatsoever on
>> the implementation. In fact, I agree with everything Lennart wrote.
>
> The way the TI irq crossbar works is:
>
> You have say 200 interrupt sources in the system. You have some
> coprocessor (say PRU0) that you want to handle UART7, so you tell the
> crossbar: Please map the IRQ from UART7 (which might be input 146 on the
> crossbar) to IRQ 10 on the PRU0 processor. Now whenever the interrupt
> from UART7 fires, PRU0 will see it as IRQ10. There are no interrupt
> registers to check in the crossbar, it is purely virtual wires for
> routing interrupts. It just happens to be an enourmouse and very very
> flexible set of wires.
>

Ok, thanks for the information.

> If on the other hand you have 128 inputs and 24 outputs and you want
> all 128 inputs to work, and you have 24 128bit registers in the device
> to tell you which of the inputs fired to cause a given output to fire,
> then you in fact have an interrupt controller, not a crossbar.

Actually we have 128 inputs and 24 outputs, the 24 outputs go straight to the GIC.
The HW block is a many-to-many router.
There are 128 32bit registers which specify, for each of the corresponding 128 inputs, to which of the 24 outputs it would be routed to.

There are 4 32bit registers that can show the RAW status of the 128 inputs, but they do not latch on the inputs.
That's why our understanding is that on Linux terms it is not an interrupt controller, but just a many-to-many mux, the only real interrupt-controller (where one can set if the line is active high or low for example) is the GIC.

> This would
> be much more similar to how the original x86 design has an i8259 connected
> with 8 inputs and 1 output to an input on a second i8259 (the output of
> the secondary chip connects to IRQ2 on the primary). You actually need
> an irq controller driver to go read the registers to determine which
> external interrupt fired and to assign a virtual IRQ number so that
> drivers can register for a given externel pin. Cascaded interrupt
> controllers like this is perfectly common on lots of systems.

Thanks for the background on the i8259 and the cascaded interrupts.
However, our understanding is that it would only be required if more than 24 devices request IRQ lines, in which case, some of them would have to share a single GIC IRQ line, right?
Shall we worry about that now?

>
> Now of course you could cheat and simply declare that all the inputs
> that are mixed to a single output are in fact sharing a single interrupt
> (fine if they are level triggered, could be problematic if edge triggered,
> depending on how it works exactly). Of course then when an interrupt
> happens, every driver that handles some device on a given shared interrupt
> will have the handler called in turn until everyone has had a change
> to handle the interrupt, at which point everyone should have stopped
> triggering it and it will clear itself, unless of course another event
> happened on one of the devices in which case another loop through everyone
> happens to handle the new events. The loop will continue until the
> interrupt clears, as long as some of the handlers return that they in fact
> did do some work to handle the interrupt event. If no one claims to have
> done something and the interrupt stays, you get the kernel killing the
> interrupt with a message about "Interrupt foo happened and nobody cared".

This is interesting.
We have one interrupt controller already upstream, drivers/irqchip/irq-tango.c, and our understanding is that it dispatches one IRQ at the time, see tangox_dispatch_irqs() function, is that what you are discussing?

Best regards,

Sebastian