patch-2.4.19 linux-2.4.19/arch/mips/cobalt/irq.c
Next file: linux-2.4.19/arch/mips/cobalt/pci.c
Previous file: linux-2.4.19/arch/mips/cobalt/int-handler.S
Back to the patch index
Back to the overall index
- Lines: 224
- Date:
Fri Aug 2 17:39:43 2002
- Orig file:
linux-2.4.18/arch/mips/cobalt/irq.c
- Orig date:
Wed Dec 31 16:00:00 1969
diff -urN linux-2.4.18/arch/mips/cobalt/irq.c linux-2.4.19/arch/mips/cobalt/irq.c
@@ -0,0 +1,223 @@
+/*
+ * IRQ vector handles
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 1996, 1997 by Ralf Baechle
+ * Copyright (C) 2001 by Liam Davies (ldavies@agile.tv)
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+
+#include <asm/cobalt/cobalt.h>
+
+/* Cobalt Exception handler */
+extern void cobalt_handle_int(void);
+
+/* Via masking routines */
+extern void unmask_irq(unsigned int irqr);
+extern void mask_irq(unsigned int irq);
+
+
+/*
+ * We have two types of interrupts that we handle, ones that come
+ * in through the CPU interrupt lines, and ones that come in on
+ * the via chip. The CPU mappings are:
+ * 0,1 - S/W (ignored)
+ * 2 - Galileo chip (timer)
+ * 3 - Tulip 0 + NCR SCSI
+ * 4 - Tulip 1
+ * 5 - 16550 UART
+ * 6 - VIA southbridge PIC
+ * 7 - PCI
+ *
+ * The VIA chip is a master/slave 8259 setup and has the
+ * following interrupts
+ * 8 - RTC
+ * 14 - IDE0
+ * 15 - IDE1
+ *
+ * In the table we use a 1 to indicate that we use a VIA interrupt
+ * line, and IE_IRQx to indicate that we use a CPU interrupt line
+ *
+ * We map all of these onto linux IRQ #s 0-15 and forget the rest
+ */
+#define NOINT_LINE 0
+#define CPUINT_LINE(x) IE_IRQ##x
+#define VIAINT_LINE 1
+
+#define COBALT_IRQS 16
+
+static unsigned short irqnr_to_type[COBALT_IRQS] =
+{ CPUINT_LINE(0), NOINT_LINE, VIAINT_LINE, NOINT_LINE,
+ CPUINT_LINE(1), NOINT_LINE, NOINT_LINE, CPUINT_LINE(3),
+ VIAINT_LINE, VIAINT_LINE, NOINT_LINE, NOINT_LINE,
+ NOINT_LINE, CPUINT_LINE(2), VIAINT_LINE, VIAINT_LINE };
+
+/*
+ * Cobalt CPU irq
+ */
+
+static void enable_cpu_irq(unsigned int irq)
+{
+ unsigned long flags;
+
+ save_and_cli(flags);
+ change_cp0_status(irqnr_to_type[irq], irqnr_to_type[irq]);
+ restore_flags(flags);
+}
+
+static unsigned startup_cpu_irq(unsigned int irq)
+{
+ enable_cpu_irq(irq);
+
+ return 0;
+}
+
+static void disable_cpu_irq(unsigned int irq)
+{
+ unsigned long flags;
+
+ save_and_cli(flags);
+ change_cp0_status(irqnr_to_type[irq], ~(irqnr_to_type[irq]));
+ restore_flags(flags);
+}
+
+#define shutdown_cpu_irq disable_cpu_irq
+#define mask_and_ack_cpu_irq disable_cpu_irq
+
+static void end_cpu_irq(unsigned int irq)
+{
+ if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+ enable_cpu_irq(irq);
+}
+
+static struct hw_interrupt_type cobalt_cpu_irq_type = {
+ "Cobalt CPU",
+ startup_cpu_irq,
+ shutdown_cpu_irq,
+ enable_cpu_irq,
+ disable_cpu_irq,
+ mask_and_ack_cpu_irq,
+ end_cpu_irq,
+ NULL
+};
+
+
+/*
+ * Cobalt VIA irq
+ */
+
+static void enable_via_irq(unsigned int irq)
+{
+ unsigned long flags;
+
+ save_and_cli(flags);
+ unmask_irq(irq);
+ restore_flags(flags);
+}
+
+static unsigned startup_via_irq(unsigned int irq)
+{
+ enable_via_irq(irq);
+
+ return 0;
+}
+
+static void disable_via_irq(unsigned int irq)
+{
+ unsigned long flags;
+
+ save_and_cli(flags);
+ mask_irq(irq);
+ restore_flags(flags);
+}
+
+#define shutdown_via_irq disable_via_irq
+#define mask_and_ack_via_irq disable_via_irq
+
+static void end_via_irq(unsigned int irq)
+{
+ if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+ enable_via_irq(irq);
+}
+
+static struct hw_interrupt_type cobalt_via_irq_type = {
+ "Cobalt VIA",
+ startup_via_irq,
+ shutdown_via_irq,
+ enable_via_irq,
+ disable_via_irq,
+ mask_and_ack_via_irq,
+ end_via_irq,
+ NULL
+};
+
+
+static struct irqaction via_irq2 = {
+ no_action, 0, 0, "slave cascade", NULL, NULL
+};
+
+static struct resource pic1_io_resource = {
+ "VIA PIC Master", 0x20, 0x3f, IORESOURCE_BUSY
+};
+
+static struct resource pic2_io_resource = {
+ "VIA PIC Slave", 0xa0, 0xbf, IORESOURCE_BUSY
+};
+
+
+void __init init_IRQ(void)
+{
+ int i;
+
+ /* Initialise all of the IRQ descriptors */
+ init_generic_irq();
+
+ /* Map the irqnr to the type int we have */
+ for (i=0; i < COBALT_IRQS; i++) {
+ if (irqnr_to_type[i] >= CPUINT_LINE(0))
+ /* cobalt_cpu_irq_type */
+ irq_desc[i].handler = &cobalt_cpu_irq_type;
+ else if (irqnr_to_type[i] == VIAINT_LINE)
+ /* VIA/8259 irq_type */
+ irq_desc[i].handler = &cobalt_via_irq_type;
+ else {} /* Leave it as disabled/no handler */
+ }
+
+ /* Setup the VIA interrupts */
+ request_resource(&ioport_resource, &pic1_io_resource);
+ request_resource(&ioport_resource, &pic2_io_resource);
+ setup_irq(2, &via_irq2);
+
+ /* This may be too simple.. FIX it later */
+ VIA_PORT_WRITE(0x20, 0x10);
+ VIA_PORT_WRITE(0x21, 0x00);
+ VIA_PORT_WRITE(0x21, 0x00);
+
+ VIA_PORT_WRITE(0xa0, 0x10);
+ VIA_PORT_WRITE(0xa1, 0x00);
+ VIA_PORT_WRITE(0xa1, 0x00);
+
+ /* Mask all cpu interrupts
+ (except IE4, we already masked those at VIA level) */
+ clear_cp0_status(ST0_IM);
+ set_cp0_status(IE_IRQ4);
+
+ cli();
+
+ set_except_vector(0, cobalt_handle_int);
+}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)