Re: Using irq-crossbar.c

From: Lennart Sorensen
Date: Mon Jun 13 2016 - 10:04:13 EST


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.

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. 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.

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".

> I'm not sure I follow. All platform interrupts flow into the platform
> controller. Maybe other platforms have more complex setups, with
> several cascaded controllers?

I get the impression yours is not as simple as you thought either.

--
len Sorensen