PALcode will ack the interrupt in the normal interrupt return path, but 2.4 re-enables interrupts before that. This means we re-enable interrupts without the hardware being acked, which results in nasty interrupt storms. Fixed thus. r~ --- linux/arch/alpha/kernel/sys_rawhide.c.orig Sun May 27 15:51:03 2001 +++ linux/arch/alpha/kernel/sys_rawhide.c Sun May 27 15:57:42 2001 @@ -59,10 +59,11 @@ rawhide_enable_irq(unsigned int irq) irq -= 16; hose = irq / 24; irq -= hose * 24; + mask = 1 << irq; spin_lock(&rawhide_irq_lock); - mask = cached_irq_masks[hose] |= 1 << irq; - mask |= hose_irq_masks[hose]; + mask |= cached_irq_masks[hose]; + cached_irq_masks[hose] = mask; rawhide_update_irq_hw(hose, mask); spin_unlock(&rawhide_irq_lock); } @@ -75,14 +76,37 @@ rawhide_disable_irq(unsigned int irq) irq -= 16; hose = irq / 24; irq -= hose * 24; + mask = ~(1 << irq) | hose_irq_masks[hose]; spin_lock(&rawhide_irq_lock); - mask = cached_irq_masks[hose] &= ~(1 << irq); - mask |= hose_irq_masks[hose]; + mask &= cached_irq_masks[hose]; + cached_irq_masks[hose] = mask; rawhide_update_irq_hw(hose, mask); spin_unlock(&rawhide_irq_lock); } +static void +rawhide_mask_and_ack_irq(unsigned int irq) +{ + unsigned int mask, mask1, hose; + + irq -= 16; + hose = irq / 24; + irq -= hose * 24; + mask1 = 1 << irq; + mask = ~mask1 | hose_irq_masks[hose]; + + spin_lock(&rawhide_irq_lock); + + mask &= cached_irq_masks[hose]; + cached_irq_masks[hose] = mask; + rawhide_update_irq_hw(hose, mask); + + /* Clear the interrupt. */ + *(vuip)MCPCIA_INT_REQ(MCPCIA_HOSE2MID(hose)) = mask1; + + spin_unlock(&rawhide_irq_lock); +} static unsigned int rawhide_startup_irq(unsigned int irq) @@ -104,7 +128,7 @@ static struct hw_interrupt_type rawhide_ shutdown: rawhide_disable_irq, enable: rawhide_enable_irq, disable: rawhide_disable_irq, - ack: rawhide_disable_irq, + ack: rawhide_mask_and_ack_irq, end: rawhide_end_irq, }; @@ -145,8 +169,12 @@ rawhide_init_irq(void) mcpcia_init_hoses(); for (hose = hose_head; hose; hose = hose->next) { - int h = hose->index; - rawhide_update_irq_hw(h, hose_irq_masks[h]); + unsigned int h = hose->index; + unsigned int mask = hose_irq_masks[h]; + + cached_irq_masks[h] = mask; + *(vuip)MCPCIA_INT_MASK0(MCPCIA_HOSE2MID(h)) = mask; + *(vuip)MCPCIA_INT_MASK1(MCPCIA_HOSE2MID(h)) = 0; } for (i = 16; i < 128; ++i) { - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/