|
@@ -254,13 +254,21 @@ loongson3_send_ipi_mask(const struct cpumask *mask, unsigned int action)
|
|
|
loongson3_ipi_write32((u32)action, ipi_set0_regs[cpu_logical_map(i)]);
|
|
|
}
|
|
|
|
|
|
+#define IPI_IRQ_OFFSET 6
|
|
|
+
|
|
|
+void loongson3_send_irq_by_ipi(int cpu, int irqs)
|
|
|
+{
|
|
|
+ loongson3_ipi_write32(irqs << IPI_IRQ_OFFSET, ipi_set0_regs[cpu_logical_map(cpu)]);
|
|
|
+}
|
|
|
+
|
|
|
void loongson3_ipi_interrupt(struct pt_regs *regs)
|
|
|
{
|
|
|
int i, cpu = smp_processor_id();
|
|
|
- unsigned int action, c0count;
|
|
|
+ unsigned int action, c0count, irqs;
|
|
|
|
|
|
/* Load the ipi register to figure out what we're supposed to do */
|
|
|
action = loongson3_ipi_read32(ipi_status0_regs[cpu_logical_map(cpu)]);
|
|
|
+ irqs = action >> IPI_IRQ_OFFSET;
|
|
|
|
|
|
/* Clear the ipi register to clear the interrupt */
|
|
|
loongson3_ipi_write32((u32)action, ipi_clear0_regs[cpu_logical_map(cpu)]);
|
|
@@ -282,6 +290,14 @@ void loongson3_ipi_interrupt(struct pt_regs *regs)
|
|
|
core0_c0count[i] = c0count;
|
|
|
__wbflush(); /* Let others see the result ASAP */
|
|
|
}
|
|
|
+
|
|
|
+ if (irqs) {
|
|
|
+ int irq;
|
|
|
+ while ((irq = ffs(irqs))) {
|
|
|
+ do_IRQ(irq-1);
|
|
|
+ irqs &= ~(1<<(irq-1));
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
#define MAX_LOOPS 800
|