patch-2.4.20 linux-2.4.20/arch/mips64/kernel/irq_cpu.c
Next file: linux-2.4.20/arch/mips64/kernel/linux32.c
Previous file: linux-2.4.20/arch/mips64/kernel/irq.c
Back to the patch index
Back to the overall index
- Lines: 96
- Date:
Thu Nov 28 15:53:10 2002
- Orig file:
linux-2.4.19/arch/mips64/kernel/irq_cpu.c
- Orig date:
Fri Aug 2 17:39:43 2002
diff -urN linux-2.4.19/arch/mips64/kernel/irq_cpu.c linux-2.4.20/arch/mips64/kernel/irq_cpu.c
@@ -2,6 +2,8 @@
* Copyright 2001 MontaVista Software Inc.
* Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
*
+ * Copyright (C) 2001 Ralf Baechle
+ *
* This file define the irq handler for MIPS CPU interrupts.
*
* This program is free software; you can redistribute it and/or modify it
@@ -13,8 +15,11 @@
/*
* Almost all MIPS CPUs define 8 interrupt sources. They are typically
* level triggered (i.e., cannot be cleared from CPU; must be cleared from
- * device). The first two are software interrupts. The last one is
- * usually cpu timer interrupt if coutner register is present.
+ * device). The first two are software interrupts which we don't really
+ * use or support. The last one is usually cpu timer interrupt if a counter
+ * register is present.
+ *
+ * Don't even think about using this on SMP. You have been warned.
*
* This file exports one global function:
* mips_cpu_irq_init(u32 irq_base);
@@ -24,18 +29,37 @@
#include <linux/kernel.h>
#include <asm/mipsregs.h>
+#include <asm/system.h>
+
+static int mips_cpu_irq_base;
+
+static inline void unmask_mips_irq(unsigned int irq)
+{
+ clear_cp0_cause(0x100 << (irq - mips_cpu_irq_base));
+ set_cp0_status(0x100 << (irq - mips_cpu_irq_base));
+}
-static int mips_cpu_irq_base = -1;
+static inline void mask_mips_irq(unsigned int irq)
+{
+ clear_cp0_status(0x100 << (irq - mips_cpu_irq_base));
+}
-static void mips_cpu_irq_enable(unsigned int irq)
+static inline void mips_cpu_irq_enable(unsigned int irq)
{
- clear_cp0_cause( 1 << (irq - mips_cpu_irq_base + 8));
- set_cp0_status(1 << (irq - mips_cpu_irq_base + 8));
+ unsigned long flags;
+
+ local_irq_save(flags);
+ unmask_mips_irq(irq);
+ local_irq_restore(flags);
}
static void mips_cpu_irq_disable(unsigned int irq)
{
- clear_cp0_status(1 << (irq - mips_cpu_irq_base + 8));
+ unsigned long flags;
+
+ local_irq_save(flags);
+ mask_mips_irq(irq);
+ local_irq_restore(flags);
}
static unsigned int mips_cpu_irq_startup(unsigned int irq)
@@ -47,21 +71,22 @@
#define mips_cpu_irq_shutdown mips_cpu_irq_disable
+/*
+ * While we ack the interrupt interrupts are disabled and thus we don't need
+ * to deal with concurrency issues. Same for mips_cpu_irq_end.
+ */
static void mips_cpu_irq_ack(unsigned int irq)
{
- /* although we attemp to clear the IP bit in cause reigster, I think
- * usually it is cleared by device (irq source)
- */
+ /* Only necessary for soft interrupts */
clear_cp0_cause(1 << (irq - mips_cpu_irq_base + 8));
- /* disable this interrupt - so that we safe proceed to the handler */
- mips_cpu_irq_disable(irq);
+ mask_mips_irq(irq);
}
static void mips_cpu_irq_end(unsigned int irq)
{
- if(!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
- mips_cpu_irq_enable(irq);
+ if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+ unmask_mips_irq(irq);
}
static hw_irq_controller mips_cpu_irq_controller = {
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)