Re: Shared edge triggered interrupts

Richard B. Johnson (root@chaos.analogic.com)
Fri, 7 Aug 1998 13:24:58 -0400 (EDT)


On Fri, 7 Aug 1998, Peter T. Breuer wrote:

> "A month of sundays ago Linus Torvalds wrote:"
> >
> > The device driver for device X is still happily handling the interrupt,
> > and at time C it finishes with device X, and returns. We have now handled
> > all shared interrupts, and the kernel returns from the interrupt handler
> > to normal handling.
> >
> > However, the interrupt line is still active, but the CPU has never gotten
> > the interrupt because the edge never happened. So we'll never again see
> > any interrupts from Y or X, because there won't be any more edges.
>
> Seems a flawed argument to me.
>
[SNIPPED]
>
> I.e., would somebody mind drawing a diagram? I need to know where the RC
> flipflops are, and where the JK flipflops are, in order to comment sensibly.
> My impression is that "it depends".
>

I will pretend that we have only one interrupt controller.

The CPU interrupt line (there are only two, one is maskable and the
other is unmaskable) will be called CPU_INT.

CPU_INT = IRQ0_latch | IRQ1_latch | IRQ2_latch ... etc.
IRQ0_latch = IRQ0_input & ~IRQ0_mask
IRQ1_latch = IRQ1_input & ~IRQ1_mask
... etc ...

IRQ0_input = shared_IRQ_line0 | shared_IRQ_line1 ... etc.
IRQ1_input = shared_IRQ_lineN | shared_IRQ_lineX ... etc.

The latch can be programmed so its output remains TRUE even after its
input becomes FALSE. This is called edge triggering. When programmed in
this manner, the latch is reset, even if the input remains high, by
sending an EOI (End of Interrupt) command to the controller. There are two
kinds, specific and non-specific. This allows the controller to capture
short duration events.

The latch can be programmed so its output remains TRUE until a EOI
command is sent to the controller, but then will remain TRUE if the
input still remains TRUE. Otherwise, it will become FALSE. This
is called level triggering.

When you share interrupts, the input to the controller is the logical
OR of every shared interrupt so you need to program the controller
for levels, rather than edges, and then you have to make sure that
each ISR properly and completely handles the demands of its respective
hardware device so that each device sets its interrupt request to FALSE.

A case in point: The 8250 (and clones) UART can be programmed to
assert an interrupt request when the TX buffer is empty. This is
necessary so you can send data without having to poll. If the
interrupt controller is programmed for "levels", and the TX buffer
is empty, what happens if you don't have any more data to send?

The interrupt request will remain TRUE because you can't satisfy
the UART's request for more data. This will cause the controller
to interrupt "forever". What needs to be done, where there are
no more data available, is to turn off the UART's "interrupt
on TX buffer empty" programming until there are more data available.
This will set the interrupt request to FALSE.

Since the IRQN_mask, used to enable interrupts for specific levels,
is before the latch, it is possible to make new "edges" so a
IRQN_input can be detected, even if the controller is programmed
for "edges". However, usage in the manner is undocumented so
you get whatever you get.

Cheers,
Dick Johnson
***** FILE SYSTEM MODIFIED *****
Penguin : Linux version 2.1.113 on an i586 machine (66.15 BogoMips).
Warning : It's hard to remain at the trailing edge of technology.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.altern.org/andrebalsa/doc/lkml-faq.html