diff -urN 2.3.47pre2/arch/alpha/kernel/alpha_ksyms.c p/arch/alpha/kernel/alpha_ksyms.c --- 2.3.47pre2/arch/alpha/kernel/alpha_ksyms.c Thu Feb 17 20:20:29 2000 +++ p/arch/alpha/kernel/alpha_ksyms.c Fri Feb 18 04:00:54 2000 @@ -51,6 +51,7 @@ EXPORT_SYMBOL(enable_irq); EXPORT_SYMBOL(disable_irq); EXPORT_SYMBOL(disable_irq_nosync); +EXPORT_SYMBOL(probe_irq_mask); EXPORT_SYMBOL(screen_info); EXPORT_SYMBOL(perf_irq); diff -urN 2.3.47pre2/arch/alpha/kernel/irq.c p/arch/alpha/kernel/irq.c --- 2.3.47pre2/arch/alpha/kernel/irq.c Thu Feb 17 20:20:29 2000 +++ p/arch/alpha/kernel/irq.c Fri Feb 18 15:47:39 2000 @@ -831,15 +831,17 @@ unsigned long probe_irq_on(void) { - unsigned int i; + int i; unsigned long delay; + unsigned long val; /* Something may have generated an irq long ago and we want to flush such a longstanding irq before considering it as spurious. */ spin_lock_irq(&irq_controller_lock); - for (i = NR_IRQS-1; i > 0; i--) + for (i = NR_IRQS-1; i >= 0; i--) if (!irq_desc[i].action) - irq_desc[i].handler->startup(i); + if(irq_desc[i].handler->startup(i)) + irq_desc[i].status |= IRQ_PENDING; spin_unlock_irq(&irq_controller_lock); /* Wait for longstanding interrupts to trigger. */ @@ -850,7 +852,7 @@ if a longstanding irq happened in the previous stage, it may have masked itself) first, enable any unassigned irqs. */ spin_lock_irq(&irq_controller_lock); - for (i = NR_IRQS-1; i > 0; i--) { + for (i = NR_IRQS-1; i >= 0; i--) { if (!irq_desc[i].action) { irq_desc[i].status |= IRQ_AUTODETECT | IRQ_WAITING; if(irq_desc[i].handler->startup(i)) @@ -868,6 +870,7 @@ /* * Now filter out any obviously spurious interrupts */ + val = 0; spin_lock_irq(&irq_controller_lock); for (i=0; ishutdown(i); + continue; } + + if (i < 64) + val |= 1 << i; } spin_unlock_irq(&irq_controller_lock); - return 0x12345678; + return val; +} + +/* + * Return a mask of triggered interrupts (this + * can handle only legacy ISA interrupts). + */ +unsigned int probe_irq_mask(unsigned long val) +{ + int i; + unsigned int mask; + + mask = 0; + spin_lock_irq(&irq_controller_lock); + for (i = 0; i < 16; i++) { + unsigned int status = irq_desc[i].status; + + if (!(status & IRQ_AUTODETECT)) + continue; + + if (!(status & IRQ_WAITING)) + mask |= 1 << i; + + irq_desc[i].status = status & ~IRQ_AUTODETECT; + irq_desc[i].handler->shutdown(i); + } + spin_unlock_irq(&irq_controller_lock); + + return mask & val; } /* @@ -893,12 +928,9 @@ */ int -probe_irq_off(unsigned long unused) +probe_irq_off(unsigned long val) { int i, irq_found, nr_irqs; - - if (unused != 0x12345678) - printk("Bad IRQ probe from %lx\n", (&unused)[-1]); nr_irqs = 0; irq_found = 0; diff -urN 2.3.47pre2/arch/alpha/kernel/sys_dp264.c p/arch/alpha/kernel/sys_dp264.c --- 2.3.47pre2/arch/alpha/kernel/sys_dp264.c Thu Feb 17 20:20:29 2000 +++ p/arch/alpha/kernel/sys_dp264.c Fri Feb 18 15:55:57 2000 @@ -85,7 +85,7 @@ end_clipper_irq }; -static unsigned long cached_irq_mask = ~0UL; +static unsigned long cached_irq_mask; #define TSUNAMI_SET_IRQ_MASK(cpu, value) \ do { \ @@ -141,25 +141,24 @@ unsigned long value; #ifdef CONFIG_SMP - value = ~mask; - do_flush_smp_irq_mask(value); + do_flush_smp_irq_mask(mask); #endif - value = ~mask | (1UL << 55) | 0xffff; /* isa irqs always enabled */ + value = mask | (1UL << 55) | 0xffff; /* isa irqs always enabled */ do_flush_irq_mask(value); } static void enable_tsunami_irq(unsigned int irq) { - cached_irq_mask &= ~(1UL << irq); + cached_irq_mask |= 1UL << irq; dp264_flush_irq_mask(cached_irq_mask); } static void disable_tsunami_irq(unsigned int irq) { - cached_irq_mask |= 1UL << irq; + cached_irq_mask &= ~(1UL << irq); dp264_flush_irq_mask(cached_irq_mask); } @@ -168,26 +167,26 @@ { unsigned long value; + value = mask >> 16; #ifdef CONFIG_SMP - value = ~mask >> 16; do_flush_smp_irq_mask(value); #endif - value = (~mask >> 16) | (1UL << 55); /* master ISA enable */ + value = value | (1UL << 55); /* master ISA enable */ do_flush_irq_mask(value); } static void enable_clipper_irq(unsigned int irq) { - cached_irq_mask &= ~(1UL << irq); + cached_irq_mask |= 1UL << irq; clipper_flush_irq_mask(cached_irq_mask); } static void disable_clipper_irq(unsigned int irq) { - cached_irq_mask |= 1UL << irq; + cached_irq_mask &= ~(1UL << irq); clipper_flush_irq_mask(cached_irq_mask); } @@ -278,6 +277,9 @@ continue; if (i < 16) continue; + /* only irqs between 16 and 47 are tsunami irqs */ + if (i >= 48) + break; irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; irq_desc[i].handler = ops; } @@ -298,7 +300,7 @@ init_RTC_irq(); init_TSUNAMI_irqs(&tsunami_irq_type); - dp264_flush_irq_mask(~0UL); + dp264_flush_irq_mask(0UL); } static void __init @@ -316,7 +318,7 @@ init_RTC_irq(); init_TSUNAMI_irqs(&clipper_irq_type); - clipper_flush_irq_mask(~0UL); + clipper_flush_irq_mask(0UL); }