diff -urN 2.3.47pre2/arch/alpha/kernel/alpha_ksyms.c pc164/arch/alpha/kernel/alpha_ksyms.c --- 2.3.47pre2/arch/alpha/kernel/alpha_ksyms.c Thu Feb 17 20:20:29 2000 +++ pc164/arch/alpha/kernel/alpha_ksyms.c Fri Feb 18 22:38:02 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 pc164/arch/alpha/kernel/irq.c --- 2.3.47pre2/arch/alpha/kernel/irq.c Thu Feb 17 20:20:29 2000 +++ pc164/arch/alpha/kernel/irq.c Fri Feb 18 22:38:02 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_cabriolet.c pc164/arch/alpha/kernel/sys_cabriolet.c --- 2.3.47pre2/arch/alpha/kernel/sys_cabriolet.c Wed Dec 8 00:05:25 1999 +++ pc164/arch/alpha/kernel/sys_cabriolet.c Fri Feb 18 22:35:55 2000 @@ -16,6 +16,8 @@ #include #include #include +#include +#include #include #include @@ -31,42 +33,99 @@ #include #include "proto.h" -#include #include "pci_impl.h" #include "machvec_impl.h" +static void enable_cabriolet_irq(unsigned int irq); +static void disable_cabriolet_irq(unsigned int irq); + +static void enable_cabriolet_srm_irq(unsigned int irq); +static void disable_cabriolet_srm_irq(unsigned int irq); + +#define end_cabriolet_irq enable_cabriolet_irq +#define shutdown_cabriolet_irq disable_cabriolet_irq +#define mask_and_ack_cabriolet_irq disable_cabriolet_irq + +#define end_cabriolet_srm_irq enable_cabriolet_srm_irq +#define shutdown_cabriolet_srm_irq disable_cabriolet_srm_irq +#define mask_and_ack_cabriolet_srm_irq disable_cabriolet_srm_irq + +static unsigned int +startup_cabriolet_irq(unsigned int irq) +{ + enable_cabriolet_irq(irq); + return 0; /* never anything pending */ +} + +static unsigned int +startup_cabriolet_srm_irq(unsigned int irq) +{ + enable_cabriolet_srm_irq(irq); + return 0; /* never anything pending */ +} + +static struct hw_interrupt_type cabriolet_irq_type = { + "CABRIOLET", + startup_cabriolet_irq, + shutdown_cabriolet_irq, + enable_cabriolet_irq, + disable_cabriolet_irq, + mask_and_ack_cabriolet_irq, + end_cabriolet_irq, +}; + +static struct hw_interrupt_type cabriolet_srm_irq_type = { + "CABRIOLET-SRM", + startup_cabriolet_srm_irq, + shutdown_cabriolet_srm_irq, + enable_cabriolet_srm_irq, + disable_cabriolet_srm_irq, + mask_and_ack_cabriolet_srm_irq, + end_cabriolet_srm_irq, +}; + +static unsigned long cached_irq_mask = ~0UL; + +static inline void +cabriolet_flush_irq_mask(unsigned long mask) +{ + outl(mask >> 16, 0x804); +} + +static void +enable_cabriolet_irq(unsigned int irq) +{ + cached_irq_mask &= ~(1UL << irq); + cabriolet_flush_irq_mask(cached_irq_mask); +} + static void -cabriolet_update_irq_hw(unsigned long irq, unsigned long mask, int unmask_p) +disable_cabriolet_irq(unsigned int irq) { - if (irq >= 16) - outl(alpha_irq_mask >> 16, 0x804); - else if (irq >= 8) - outb(mask >> 8, 0xA1); - else - outb(mask, 0x21); + cached_irq_mask |= 1UL << irq; + cabriolet_flush_irq_mask(cached_irq_mask); } + /* Under SRM console, we must use the CSERVE PALcode routine to manage the interrupt mask for us. Otherwise, the kernel/HW get out of sync with what the PALcode thinks it needs to deliver/ignore. */ static void -cabriolet_srm_update_irq_hw(unsigned long irq, unsigned long mask, int unmaskp) +enable_cabriolet_srm_irq(unsigned int irq) { - if (irq >= 16) { - if (unmaskp) - cserve_ena(irq - 16); - else - cserve_dis(irq - 16); - } - else if (irq >= 8) - outb(mask >> 8, 0xA1); - else - outb(mask, 0x21); + cserve_ena(irq - 16); +} + +static void +disable_cabriolet_srm_irq(unsigned int irq) +{ + cserve_dis(irq - 16); } + static void cabriolet_device_interrupt(unsigned long v, struct pt_regs *r) { @@ -86,26 +145,47 @@ if (i == 4) { isa_device_interrupt(v, r); } else { - handle_irq(16 + i, 16 + i, r); + handle_irq(16 + i, r); } } } -static void +static void __init +init_TSUNAMI_irqs(struct hw_interrupt_type * ops) +{ + int i; + + for (i = 0; i < NR_IRQS; i++) { + if (i == RTC_IRQ) + continue; + if (i < 16) + continue; + if (i >= 35) + break; + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].handler = ops; + } +} + +static void __init cabriolet_init_irq(void) { + static struct irqaction cascade = { no_action, 0, 0, "sio-cascade", NULL, NULL}; + STANDARD_INIT_IRQ_PROLOG; + init_ISA_irqs(); + init_RTC_irq(); if (alpha_using_srm) { - alpha_mv.update_irq_hw = cabriolet_srm_update_irq_hw; alpha_mv.device_interrupt = srm_device_interrupt; + init_TSUNAMI_irqs(&cabriolet_srm_irq_type); } else { - outl(alpha_irq_mask >> 16, 0x804); + init_TSUNAMI_irqs(&cabriolet_irq_type); + cabriolet_flush_irq_mask(~0UL); } - enable_irq(16 + 4); /* enable SIO cascade */ - enable_irq(2); /* enable cascade */ + setup_irq(16 + 4, &cascade); /* enable SIO cascade */ } @@ -260,9 +340,6 @@ min_mem_address: APECS_AND_LCA_DEFAULT_MEM_BASE, nr_irqs: 35, - irq_probe_mask: _PROBE_MASK(35), - update_irq_hw: cabriolet_update_irq_hw, - ack_irq: common_ack_irq, device_interrupt: cabriolet_device_interrupt, init_arch: apecs_init_arch, @@ -289,9 +366,6 @@ min_mem_address: CIA_DEFAULT_MEM_BASE, nr_irqs: 35, - irq_probe_mask: _PROBE_MASK(35), - update_irq_hw: cabriolet_update_irq_hw, - ack_irq: common_ack_irq, device_interrupt: cabriolet_device_interrupt, init_arch: cia_init_arch, @@ -317,9 +391,6 @@ min_mem_address: APECS_AND_LCA_DEFAULT_MEM_BASE, nr_irqs: 35, - irq_probe_mask: _PROBE_MASK(35), - update_irq_hw: cabriolet_update_irq_hw, - ack_irq: common_ack_irq, device_interrupt: cabriolet_device_interrupt, init_arch: lca_init_arch, @@ -345,9 +416,6 @@ min_mem_address: DEFAULT_MEM_BASE, nr_irqs: 35, - irq_probe_mask: _PROBE_MASK(35), - update_irq_hw: cabriolet_update_irq_hw, - ack_irq: common_ack_irq, device_interrupt: cabriolet_device_interrupt, init_arch: pyxis_init_arch, @@ -373,9 +441,6 @@ min_mem_address: CIA_DEFAULT_MEM_BASE, nr_irqs: 35, - irq_probe_mask: _PROBE_MASK(35), - update_irq_hw: cabriolet_update_irq_hw, - ack_irq: common_ack_irq, device_interrupt: cabriolet_device_interrupt, init_arch: cia_init_arch, diff -urN 2.3.47pre2/arch/alpha/kernel/sys_dp264.c pc164/arch/alpha/kernel/sys_dp264.c --- 2.3.47pre2/arch/alpha/kernel/sys_dp264.c Thu Feb 17 20:20:29 2000 +++ pc164/arch/alpha/kernel/sys_dp264.c Fri Feb 18 22:38:02 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); } diff -urN 2.3.47pre2/arch/alpha/kernel/sys_sx164.c pc164/arch/alpha/kernel/sys_sx164.c --- 2.3.47pre2/arch/alpha/kernel/sys_sx164.c Thu Feb 17 20:20:29 2000 +++ pc164/arch/alpha/kernel/sys_sx164.c Fri Feb 18 22:24:13 2000 @@ -143,6 +143,8 @@ static void sx164_init_irq(void) { + static struct irqaction timer = { no_action, 0, 0, "sx164-timer", NULL, NULL}; + static struct irqaction cascade = { no_action, 0, 0, "sx164-isa-cascade", NULL, NULL}; struct hw_interrupt_type *ops; long i; @@ -171,8 +173,8 @@ irq_desc[i].handler = ops; } - ops->startup(16 + 6); /* enable timer */ - ops->startup(16 + 7); /* enable ISA PIC cascade */ + setup_irq(16 + 6, &timer); /* enable timer */ + setup_irq(16 + 7, &cascade); /* enable ISA PIC cascade */ } /*