Development Plan Proposal for Unifying Interrupt and PCI APIs

Pavel Pisa ppisa4lists at pikron.com
Sun Oct 24 10:58:18 UTC 2004


On Sunday 24 October 2004 05:48, gregory.menke at gsfc.nasa.gov wrote:
> One reasonable and simple approach is to keep a linked list of handlers
> for each vector.  When the interrupt shows up, the handlers are called
> in order.  Each handler performs a quick check of its hardware.  If
> its asserting, the interrupt is serviced and the handler chain
> iteration continues.  If a handler finds its hardware is not
> asserting, it returns right away, and the chain iteration continues.

I have my two cents tips and observation there.

It is required to add driver context and may be IRQ/bus source context
into rtems_irq_connect_data. There should be added next/prev field
as well. Than there is no problem to implement sharing by calling 
all of the handlers on the list. This is simplest and if drivers
developers keeps principle defer as much as possible to the driver
worker thread, that it would work well for all level sensitive
sources.

There should be provided generic set of bus/interrupt controller
set of enable/disable methods

static void pci_isr_on(const rtems_irq_connect_data *unused);
static void pci_isr_off(const rtems_irq_connect_data *unused);
static int pci_isr_is_on(const rtems_irq_connect_data *irq);

For i.MX/MX1, thay can be implemented basic methods next way

/* Enables i.MX AITC interrupts. */
static void
imx_aitc_isr_on(const rtems_irq_connect_data *isr_data)
{
        /* Enable interrupts */
        MC9328MXL_AITC_INTENNUM = isr_data->name;

        return;
}

/* Disables i.MX AITC interrupts */
static void
imx_aitc_isr_off(const rtems_irq_connect_data *isr_data)
{
        /* disable all various TX/RX interrupts */
        MC9328MXL_AITC_INTDISNUM = isr_data->name;

        return;
}

/* Tests to see if i.MX AITC interrupts are enabled, and returns non-0 if so.
 * If interrupt is not enabled, returns 0.
 */
static int
imx_aitc_isr_is_on(const rtems_irq_connect_data *isr_data)
{
        if(isr_data->name<32)
                return MC9328MXL_AITC_INTENABLEL & (1 << 
((isr_data->name)&0x1f));
        else
                return MC9328MXL_AITC_INTENABLEH & (1 << ((isr_data->name - 
32)&0x1f));
}

As for PCI, there could be bus/card context, which enables to implement
IRQ enable/disable (pci_isr_on/pci_isr_off) on per card basis.
There should be some higher level IRQ state manipulation functions.

There is other problem for edge triggered interrupts.
If you go through the chain, call isrA, there is no IRQ, then call isrB,
but irqA is activated, before isrB negates request, than IRQ line
to interrupt controller stalls in the activated state => no more IRQ
is received. Only correct solution is to call all members of chain
again and again until one full round is not returning no interrupt
serviced state.

Best wishes

                Pavel Pisa
        e-mail: pisa at cmp.felk.cvut.cz
        www:    http://cmp.felk.cvut.cz/~pisa
        work:   http://www.pikron.com



More information about the users mailing list