diff options
-rw-r--r-- | sys/alpha/isa/isa.c | 30 |
1 files changed, 21 insertions, 9 deletions
diff --git a/sys/alpha/isa/isa.c b/sys/alpha/isa/isa.c index d6ddebc..ec1de88 100644 --- a/sys/alpha/isa/isa.c +++ b/sys/alpha/isa/isa.c @@ -389,17 +389,29 @@ isa_teardown_intr(device_t dev, device_t child, struct resource *irq, void *cookie) { struct isa_intr *ii = cookie; + struct intrhand *ih, *handler = (struct intrhand *)ii->ih; + struct ithd *ithread = handler->ih_ithread; + int num_handlers = 0; + + mtx_lock(&ithread->it_lock); + TAILQ_FOREACH(ih, &ithread->it_handlers, ih_next) + num_handlers++; + mtx_unlock(&ithread->it_lock); + + /* only disable the interrupt in hardware if there are no + other handlers sharing it */ + + if (num_handlers == 1) { + mtx_lock_spin(&icu_lock); + isa_intr_disable(irq->r_start); + mtx_unlock_spin(&icu_lock); + if (platform.isa_teardown_intr) { + platform.isa_teardown_intr(dev, child, irq, + cookie); + return 0; + } - mtx_lock_spin(&icu_lock); - isa_intr_disable(irq->r_start); - mtx_unlock_spin(&icu_lock); - - if (platform.isa_teardown_intr) { - platform.isa_teardown_intr(dev, child, irq, cookie); - return 0; } - alpha_teardown_intr(ii->ih); - return 0; } |