patch-2.3.47 linux/arch/alpha/kernel/sys_alcor.c
Next file: linux/arch/alpha/kernel/sys_cabriolet.c
Previous file: linux/arch/alpha/kernel/smp.c
Back to the patch index
Back to the overall index
- Lines: 183
- Date:
Sun Feb 20 08:13:56 2000
- Orig file:
v2.3.46/linux/arch/alpha/kernel/sys_alcor.c
- Orig date:
Tue Dec 7 09:32:39 1999
diff -u --recursive --new-file v2.3.46/linux/arch/alpha/kernel/sys_alcor.c linux/arch/alpha/kernel/sys_alcor.c
@@ -27,50 +27,71 @@
#include <asm/core_cia.h>
#include "proto.h"
-#include <asm/hw_irq.h>
+#include "irq_impl.h"
#include "pci_impl.h"
#include "machvec_impl.h"
-static void
-alcor_update_irq_hw(unsigned long irq, unsigned long mask, int unmask_p)
+/* Note mask bit is true for ENABLED irqs. */
+static unsigned long cached_irq_mask;
+
+static inline void
+alcor_update_irq_hw(unsigned long mask)
{
- if (irq >= 16) {
- /* On Alcor, at least, lines 20..30 are not connected and can
- generate spurrious interrupts if we turn them on while IRQ
- probing. So explicitly mask them out. */
- mask |= 0x7ff000000000UL;
+ *(vuip)GRU_INT_MASK = mask;
+ mb();
+}
- /* Note inverted sense of mask bits: */
- *(vuip)GRU_INT_MASK = ~(mask >> 16);
- mb();
- }
- else if (irq >= 8)
- outb(mask >> 8, 0xA1); /* ISA PIC2 */
- else
- outb(mask, 0x21); /* ISA PIC1 */
+static inline void
+alcor_enable_irq(unsigned int irq)
+{
+ alcor_update_irq_hw(cached_irq_mask |= 1UL << (irq - 16));
+}
+
+static inline void
+alcor_disable_irq(unsigned int irq)
+{
+ alcor_update_irq_hw(cached_irq_mask &= ~(1UL << (irq - 16)));
}
static void
-alcor_ack_irq(unsigned long irq)
+alcor_mask_and_ack_irq(unsigned int irq)
{
- if (irq < 16) {
- /* Ack the interrupt making it the lowest priority */
- /* First the slave .. */
- if (irq > 7) {
- outb(0xE0 | (irq - 8), 0xa0);
- irq = 2;
- }
- /* .. then the master */
- outb(0xE0 | irq, 0x20);
+ alcor_disable_irq(irq);
- /* On ALCOR/XLT, need to dismiss interrupt via GRU. */
- *(vuip)GRU_INT_CLEAR = 0x80000000; mb();
- *(vuip)GRU_INT_CLEAR = 0x00000000; mb();
- }
+ /* On ALCOR/XLT, need to dismiss interrupt via GRU. */
+ *(vuip)GRU_INT_CLEAR = 1 << (irq - 16); mb();
+ *(vuip)GRU_INT_CLEAR = 0; mb();
+}
+
+static unsigned int
+alcor_startup_irq(unsigned int irq)
+{
+ alcor_enable_irq(irq);
+ return 0;
}
static void
+alcor_isa_mask_and_ack_irq(unsigned int irq)
+{
+ i8259a_mask_and_ack_irq(irq);
+
+ /* On ALCOR/XLT, need to dismiss interrupt via GRU. */
+ *(vuip)GRU_INT_CLEAR = 0x80000000; mb();
+ *(vuip)GRU_INT_CLEAR = 0; mb();
+}
+
+static struct hw_interrupt_type alcor_irq_type = {
+ typename: "ALCOR",
+ startup: alcor_startup_irq,
+ shutdown: alcor_disable_irq,
+ enable: alcor_enable_irq,
+ disable: alcor_disable_irq,
+ ack: alcor_mask_and_ack_irq,
+ end: alcor_enable_irq,
+};
+
+static void
alcor_device_interrupt(unsigned long vector, struct pt_regs *regs)
{
unsigned long pld;
@@ -89,26 +110,40 @@
if (i == 31) {
isa_device_interrupt(vector, regs);
} else {
- handle_irq(16 + i, 16 + i, regs);
+ handle_irq(16 + i, regs);
}
}
}
-static void
+static void __init
alcor_init_irq(void)
{
- STANDARD_INIT_IRQ_PROLOG;
+ long i;
if (alpha_using_srm)
alpha_mv.device_interrupt = srm_device_interrupt;
- *(vuip)GRU_INT_MASK = ~(alpha_irq_mask >> 16); mb(); /* invert */
- *(vuip)GRU_INT_EDGE = 0U; mb(); /* all are level */
+ *(vuip)GRU_INT_MASK = 0; mb(); /* all disabled */
+ *(vuip)GRU_INT_EDGE = 0; mb(); /* all are level */
*(vuip)GRU_INT_HILO = 0x80000000U; mb(); /* ISA only HI */
- *(vuip)GRU_INT_CLEAR = 0UL; mb(); /* all clear */
+ *(vuip)GRU_INT_CLEAR = 0; mb(); /* all clear */
+
+ for (i = 16; i < 48; ++i) {
+ /* On Alcor, at least, lines 20..30 are not connected
+ and can generate spurrious interrupts if we turn them
+ on while IRQ probing. */
+ if (i >= 16+20 && i <= 16+30)
+ continue;
+ irq_desc[i].status = IRQ_DISABLED;
+ irq_desc[i].handler = &alcor_irq_type;
+ }
+ i8259a_irq_type.ack = alcor_isa_mask_and_ack_irq;
+
+ init_i8259a_irqs();
+ init_rtc_irq();
+ common_init_isa_dma();
- enable_irq(16 + 31); /* enable (E)ISA PIC cascade */
- enable_irq(2); /* enable cascade */
+ setup_irq(16+31, &isa_cascade_irqaction);
}
@@ -203,14 +238,11 @@
min_mem_address: CIA_DEFAULT_MEM_BASE,
nr_irqs: 48,
- irq_probe_mask: ALCOR_PROBE_MASK,
- update_irq_hw: alcor_update_irq_hw,
- ack_irq: alcor_ack_irq,
device_interrupt: alcor_device_interrupt,
init_arch: cia_init_arch,
init_irq: alcor_init_irq,
- init_pit: common_init_pit,
+ init_rtc: common_init_rtc,
init_pci: common_init_pci,
kill_arch: alcor_kill_arch,
pci_map_irq: alcor_map_irq,
@@ -236,14 +268,11 @@
min_mem_address: CIA_DEFAULT_MEM_BASE,
nr_irqs: 48,
- irq_probe_mask: ALCOR_PROBE_MASK,
- update_irq_hw: alcor_update_irq_hw,
- ack_irq: alcor_ack_irq,
device_interrupt: alcor_device_interrupt,
init_arch: cia_init_arch,
init_irq: alcor_init_irq,
- init_pit: common_init_pit,
+ init_rtc: common_init_rtc,
init_pci: common_init_pci,
kill_arch: alcor_kill_arch,
pci_map_irq: alcor_map_irq,
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)