If no interrupt handler claims to have dealt with a level-triggered
GPIO interrupt, check the GPIO interrupt status register after clearing it down to see if the interrupt source has disappeared. If it does, assume it was a spurious event. Otherwise, panic.
This commit is contained in:
parent
80649e0513
commit
ecc5fec473
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ixp425_intr.c,v 1.4 2003/10/08 14:55:04 scw Exp $ */
|
||||
/* $NetBSD: ixp425_intr.c,v 1.5 2003/10/08 19:31:17 scw Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003
|
||||
|
@ -68,7 +68,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: ixp425_intr.c,v 1.4 2003/10/08 14:55:04 scw Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: ixp425_intr.c,v 1.5 2003/10/08 19:31:17 scw Exp $");
|
||||
|
||||
#ifndef EVBARM_SPL_NOINLINE
|
||||
#define EVBARM_SPL_NOINLINE
|
||||
|
@ -439,8 +439,6 @@ ixp425_intr_establish(int irq, int ipl, int (*func)(void *), void *arg)
|
|||
/* All IXP425 interrupts are level-triggered. */
|
||||
iq->iq_ist = IST_LEVEL; /* XXX */
|
||||
|
||||
IXPREG(IXP425_GPIO_VBASE + IXP425_GPIO_GPISR) = ixp425_irq2gpio_bit(irq);
|
||||
|
||||
oldirqstate = disable_interrupts(I32_bit);
|
||||
|
||||
TAILQ_INSERT_TAIL(&iq->iq_list, ih, ih_list);
|
||||
|
@ -522,19 +520,29 @@ ixp425_intr_dispatch(struct clockframe *frame)
|
|||
}
|
||||
restore_interrupts(oldirqstate);
|
||||
|
||||
#if 0 /* XXX: There's a spurious interrupt coming from somewhere... */
|
||||
if (handled == 0 && iq->iq_ist == IST_LEVEL) {
|
||||
panic("ixp425_intr_dispatch: unhandled level-triggered"
|
||||
" interrupt: irq %d", irq);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Clear down level triggered GPIO interrupts now */
|
||||
if ((ibit & IXP425_INT_GPIOMASK) && iq->iq_ist == IST_LEVEL) {
|
||||
IXPREG(IXP425_GPIO_VBASE + IXP425_GPIO_GPISR) =
|
||||
ixp425_irq2gpio_bit(irq);
|
||||
}
|
||||
|
||||
if (handled == 0 && iq->iq_ist == IST_LEVEL) {
|
||||
/*
|
||||
* Let's see if the interrupt really did clear down.
|
||||
* We sometimes see spurious (GPIO) interrupts from
|
||||
* some PCIbus cards on certain boards.
|
||||
*/
|
||||
if ((ibit & IXP425_INT_GPIOMASK) == 0 ||
|
||||
IXPREG(IXP425_GPIO_VBASE + IXP425_GPIO_GPISR) &
|
||||
ixp425_irq2gpio_bit(irq)) {
|
||||
/*
|
||||
* Nope, still asserted. We're toast.
|
||||
*/
|
||||
panic("ixp425_intr_dispatch: unhandled "
|
||||
"level-triggered interrupt: irq %d", irq);
|
||||
}
|
||||
}
|
||||
|
||||
current_spl_level = pcpl;
|
||||
|
||||
/* Re-enable this interrupt now that's it's cleared. */
|
||||
|
|
Loading…
Reference in New Issue