diff options
Diffstat (limited to 'arch/alpha/kernel/sys_sable.c')
-rw-r--r-- | arch/alpha/kernel/sys_sable.c | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/arch/alpha/kernel/sys_sable.c b/arch/alpha/kernel/sys_sable.c index e2a69b5c7..b27d757b2 100644 --- a/arch/alpha/kernel/sys_sable.c +++ b/arch/alpha/kernel/sys_sable.c @@ -30,6 +30,7 @@ #include "pci_impl.h" #include "machvec_impl.h" +spinlock_t sable_irq_lock = SPIN_LOCK_UNLOCKED; /* * For SABLE, which is really baroque, we manage 40 IRQ's, but the @@ -137,8 +138,10 @@ sable_enable_irq(unsigned int irq) unsigned long bit, mask; bit = sable_irq_swizzle.irq_to_mask[irq]; + spin_lock(&sable_irq_lock); mask = sable_irq_swizzle.shadow_mask &= ~(1UL << bit); sable_update_irq_hw(bit, mask); + spin_unlock(&sable_irq_lock); } static void @@ -147,8 +150,10 @@ sable_disable_irq(unsigned int irq) unsigned long bit, mask; bit = sable_irq_swizzle.irq_to_mask[irq]; + spin_lock(&sable_irq_lock); mask = sable_irq_swizzle.shadow_mask |= 1UL << bit; sable_update_irq_hw(bit, mask); + spin_unlock(&sable_irq_lock); } static unsigned int @@ -159,14 +164,23 @@ sable_startup_irq(unsigned int irq) } static void +sable_end_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + sable_enable_irq(irq); +} + +static void sable_mask_and_ack_irq(unsigned int irq) { unsigned long bit, mask; bit = sable_irq_swizzle.irq_to_mask[irq]; + spin_lock(&sable_irq_lock); mask = sable_irq_swizzle.shadow_mask |= 1UL << bit; sable_update_irq_hw(bit, mask); sable_ack_irq_hw(bit); + spin_unlock(&sable_irq_lock); } static struct hw_interrupt_type sable_irq_type = { @@ -176,7 +190,7 @@ static struct hw_interrupt_type sable_irq_type = { enable: sable_enable_irq, disable: sable_disable_irq, ack: sable_mask_and_ack_irq, - end: sable_enable_irq, + end: sable_end_irq, }; static void @@ -204,11 +218,10 @@ sable_init_irq(void) outb(0x44, 0x535); /* enable cascades in master */ for (i = 0; i < 40; ++i) { - irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; irq_desc[i].handler = &sable_irq_type; } - init_rtc_irq(); common_init_isa_dma(); } |