#include <asm/irq_cpu.h>
#include <asm/mipsregs.h>
+#include <asm/mipsmtregs.h>
#include <asm/system.h>
static int mips_cpu_irq_base;
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
*/
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);
}
}
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)
{
clear_c0_status(ST0_IM);
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].action = NULL;
irq_desc[i].depth = 1;