patch-2.4.10 linux/arch/alpha/kernel/sys_jensen.c
Next file: linux/arch/alpha/kernel/traps.c
Previous file: linux/arch/alpha/kernel/smp.c
Back to the patch index
Back to the overall index
- Lines: 162
- Date:
Thu Sep 13 15:21:32 2001
- Orig file:
v2.4.9/linux/arch/alpha/kernel/sys_jensen.c
- Orig date:
Fri Mar 2 11:12:07 2001
diff -u --recursive --new-file v2.4.9/linux/arch/alpha/kernel/sys_jensen.c linux/arch/alpha/kernel/sys_jensen.c
@@ -35,14 +35,16 @@
/*
* Jensen is special: the vector is 0x8X0 for EISA interrupt X, and
- * 0x9X0 for the local motherboard interrupts..
+ * 0x9X0 for the local motherboard interrupts.
+ *
+ * Note especially that those local interrupts CANNOT be masked,
+ * which causes much of the pain below...
*
* 0x660 - NMI
*
* 0x800 - IRQ0 interval timer (not used, as we use the RTC timer)
* 0x810 - IRQ1 line printer (duh..)
* 0x860 - IRQ6 floppy disk
- * 0x8E0 - IRQ14 SCSI controller
*
* 0x900 - COM1
* 0x920 - COM2
@@ -52,27 +54,77 @@
* PCI-based systems are more sane: they don't have the local
* interrupts at all, and have only normal PCI interrupts from
* devices. Happily it's easy enough to do a sane mapping from the
- * Jensen.. Note that this means that we may have to do a hardware
- * "ack" to a different interrupt than we report to the rest of the
+ * Jensen.
+ *
+ * Note that this means that we may have to do a hardware
+ * "local_op" to a different interrupt than we report to the rest of the
* world.
*/
+static unsigned int
+jensen_local_startup(unsigned int irq)
+{
+ /* the parport is really hw IRQ 1, silly Jensen. */
+ if (irq == 7)
+ i8259a_startup_irq(1);
+ else
+ /*
+ * For all true local interrupts, set the flag that prevents
+ * the IPL from being dropped during handler processing.
+ */
+ if (irq_desc[irq].action)
+ irq_desc[irq].action->flags |= SA_INTERRUPT;
+ return 0;
+}
+
+static void
+jensen_local_shutdown(unsigned int irq)
+{
+ /* the parport is really hw IRQ 1, silly Jensen. */
+ if (irq == 7)
+ i8259a_disable_irq(1);
+}
+
+static void
+jensen_local_enable(unsigned int irq)
+{
+ /* the parport is really hw IRQ 1, silly Jensen. */
+ if (irq == 7)
+ i8259a_enable_irq(1);
+}
+
+static void
+jensen_local_disable(unsigned int irq)
+{
+ /* the parport is really hw IRQ 1, silly Jensen. */
+ if (irq == 7)
+ i8259a_disable_irq(1);
+}
+
static void
jensen_local_ack(unsigned int irq)
{
- /* irq1 is supposed to be the keyboard, silly Jensen. */
+ /* the parport is really hw IRQ 1, silly Jensen. */
if (irq == 7)
i8259a_mask_and_ack_irq(1);
}
+static void
+jensen_local_end(unsigned int irq)
+{
+ /* the parport is really hw IRQ 1, silly Jensen. */
+ if (irq == 7)
+ i8259a_end_irq(1);
+}
+
static struct hw_interrupt_type jensen_local_irq_type = {
typename: "LOCAL",
- startup: i8259a_startup_irq,
- shutdown: i8259a_disable_irq,
- enable: i8259a_enable_irq,
- disable: i8259a_disable_irq,
+ startup: jensen_local_startup,
+ shutdown: jensen_local_shutdown,
+ enable: jensen_local_enable,
+ disable: jensen_local_disable,
ack: jensen_local_ack,
- end: i8259a_end_irq,
+ end: jensen_local_end,
};
static void
@@ -104,6 +156,47 @@
break;
}
+ /* If there is no handler yet... */
+ if (irq_desc[irq].action == NULL) {
+ /* If it is a local interrupt that cannot be masked... */
+ if (vector >= 0x900)
+ {
+ /* Clear keyboard/mouse state */
+ inb(0x64);
+ inb(0x60);
+ /* Reset serial ports */
+ inb(0x3fa);
+ inb(0x2fa);
+ outb(0x0c, 0x3fc);
+ outb(0x0c, 0x2fc);
+ /* Clear NMI */
+ outb(0,0x61);
+ outb(0,0x461);
+ }
+ }
+
+#if 0
+ /* A useful bit of code to find out if an interrupt is going wild. */
+ {
+ static unsigned int last_msg = 0, last_cc = 0;
+ static int last_irq = -1, count = 0;
+ unsigned int cc;
+
+ __asm __volatile("rpcc %0" : "=r"(cc));
+ ++count;
+#define JENSEN_CYCLES_PER_SEC (150000000)
+ if (cc - last_msg > ((JENSEN_CYCLES_PER_SEC) * 3) ||
+ irq != last_irq) {
+ printk(KERN_CRIT " irq %d count %d cc %u @ %lx\n",
+ irq, count, cc-last_cc, regs->pc);
+ count = 0;
+ last_msg = cc;
+ last_irq = irq;
+ }
+ last_cc = cc;
+ }
+#endif
+
handle_irq(irq, regs);
}
@@ -164,7 +257,7 @@
BUS(jensen),
machine_check: jensen_machine_check,
max_dma_address: ALPHA_MAX_DMA_ADDRESS,
- rtc_port: 0x170,
+ rtc_port: 0x170,
nr_irqs: 16,
device_interrupt: jensen_device_interrupt,
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)