|
@@ -33,6 +33,7 @@
|
|
|
|
|
|
#include <asm/irq_cpu.h>
|
|
#include <asm/irq_cpu.h>
|
|
#include <asm/mipsregs.h>
|
|
#include <asm/mipsregs.h>
|
|
|
|
+#include <asm/mipsmtregs.h>
|
|
#include <asm/system.h>
|
|
#include <asm/system.h>
|
|
|
|
|
|
static int mips_cpu_irq_base;
|
|
static int mips_cpu_irq_base;
|
|
@@ -76,7 +77,7 @@ static unsigned int mips_cpu_irq_startup(unsigned int irq)
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
-#define mips_cpu_irq_shutdown mips_cpu_irq_disable
|
|
|
|
|
|
+#define mips_cpu_irq_shutdown mips_cpu_irq_disable
|
|
|
|
|
|
/*
|
|
/*
|
|
* While we ack the interrupt interrupts are disabled and thus we don't need
|
|
* While we ack the interrupt interrupts are disabled and thus we don't need
|
|
@@ -84,9 +85,6 @@ static unsigned int mips_cpu_irq_startup(unsigned int irq)
|
|
*/
|
|
*/
|
|
static void mips_cpu_irq_ack(unsigned int irq)
|
|
static void mips_cpu_irq_ack(unsigned int irq)
|
|
{
|
|
{
|
|
- /* Only necessary for soft interrupts */
|
|
|
|
- clear_c0_cause(0x100 << (irq - mips_cpu_irq_base));
|
|
|
|
-
|
|
|
|
mask_mips_irq(irq);
|
|
mask_mips_irq(irq);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -97,15 +95,60 @@ static void mips_cpu_irq_end(unsigned int irq)
|
|
}
|
|
}
|
|
|
|
|
|
static hw_irq_controller mips_cpu_irq_controller = {
|
|
static hw_irq_controller mips_cpu_irq_controller = {
|
|
- .typename = "MIPS",
|
|
|
|
- .startup = mips_cpu_irq_startup,
|
|
|
|
- .shutdown = mips_cpu_irq_shutdown,
|
|
|
|
- .enable = mips_cpu_irq_enable,
|
|
|
|
- .disable = mips_cpu_irq_disable,
|
|
|
|
- .ack = mips_cpu_irq_ack,
|
|
|
|
- .end = mips_cpu_irq_end,
|
|
|
|
|
|
+ .typename = "MIPS",
|
|
|
|
+ .startup = mips_cpu_irq_startup,
|
|
|
|
+ .shutdown = mips_cpu_irq_shutdown,
|
|
|
|
+ .enable = mips_cpu_irq_enable,
|
|
|
|
+ .disable = mips_cpu_irq_disable,
|
|
|
|
+ .ack = mips_cpu_irq_ack,
|
|
|
|
+ .end = mips_cpu_irq_end,
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+/*
|
|
|
|
+ * Basically the same as above but taking care of all the MT stuff
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+#define unmask_mips_mt_irq unmask_mips_irq
|
|
|
|
+#define mask_mips_mt_irq mask_mips_irq
|
|
|
|
+#define mips_mt_cpu_irq_enable mips_cpu_irq_enable
|
|
|
|
+#define mips_mt_cpu_irq_disable mips_cpu_irq_disable
|
|
|
|
+
|
|
|
|
+static unsigned int mips_mt_cpu_irq_startup(unsigned int irq)
|
|
|
|
+{
|
|
|
|
+ unsigned int vpflags = dvpe();
|
|
|
|
+
|
|
|
|
+ clear_c0_cause(0x100 << (irq - mips_cpu_irq_base));
|
|
|
|
+ evpe(vpflags);
|
|
|
|
+ mips_mt_cpu_irq_enable(irq);
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+#define mips_mt_cpu_irq_shutdown mips_mt_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_mt_cpu_irq_ack(unsigned int irq)
|
|
|
|
+{
|
|
|
|
+ unsigned int vpflags = dvpe();
|
|
|
|
+ clear_c0_cause(0x100 << (irq - mips_cpu_irq_base));
|
|
|
|
+ evpe(vpflags);
|
|
|
|
+ mask_mips_mt_irq(irq);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+#define mips_mt_cpu_irq_end mips_cpu_irq_end
|
|
|
|
+
|
|
|
|
+static hw_irq_controller mips_mt_cpu_irq_controller = {
|
|
|
|
+ .typename = "MIPS",
|
|
|
|
+ .startup = mips_mt_cpu_irq_startup,
|
|
|
|
+ .shutdown = mips_mt_cpu_irq_shutdown,
|
|
|
|
+ .enable = mips_mt_cpu_irq_enable,
|
|
|
|
+ .disable = mips_mt_cpu_irq_disable,
|
|
|
|
+ .ack = mips_mt_cpu_irq_ack,
|
|
|
|
+ .end = mips_mt_cpu_irq_end,
|
|
|
|
+};
|
|
|
|
|
|
void __init mips_cpu_irq_init(int irq_base)
|
|
void __init mips_cpu_irq_init(int irq_base)
|
|
{
|
|
{
|
|
@@ -115,7 +158,19 @@ void __init mips_cpu_irq_init(int irq_base)
|
|
clear_c0_status(ST0_IM);
|
|
clear_c0_status(ST0_IM);
|
|
clear_c0_cause(CAUSEF_IP);
|
|
clear_c0_cause(CAUSEF_IP);
|
|
|
|
|
|
- for (i = irq_base; i < irq_base + 8; i++) {
|
|
|
|
|
|
+ /*
|
|
|
|
+ * Only MT is using the software interrupts currently, so we just
|
|
|
|
+ * leave them uninitialized for other processors.
|
|
|
|
+ */
|
|
|
|
+ if (cpu_has_mipsmt)
|
|
|
|
+ for (i = irq_base; i < irq_base + 2; i++) {
|
|
|
|
+ irq_desc[i].status = IRQ_DISABLED;
|
|
|
|
+ irq_desc[i].action = NULL;
|
|
|
|
+ irq_desc[i].depth = 1;
|
|
|
|
+ irq_desc[i].handler = &mips_mt_cpu_irq_controller;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ for (i = irq_base + 2; i < irq_base + 8; i++) {
|
|
irq_desc[i].status = IRQ_DISABLED;
|
|
irq_desc[i].status = IRQ_DISABLED;
|
|
irq_desc[i].action = NULL;
|
|
irq_desc[i].action = NULL;
|
|
irq_desc[i].depth = 1;
|
|
irq_desc[i].depth = 1;
|