summaryrefslogtreecommitdiffstats
path: root/arch/mips/loongson/loongson-3/irq.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/loongson/loongson-3/irq.c')
-rw-r--r--arch/mips/loongson/loongson-3/irq.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/arch/mips/loongson/loongson-3/irq.c b/arch/mips/loongson/loongson-3/irq.c
index b2dc62b97a0f..088fd5e4fd64 100644
--- a/arch/mips/loongson/loongson-3/irq.c
+++ b/arch/mips/loongson/loongson-3/irq.c
@@ -26,6 +26,10 @@ void mach_irq_dispatch(unsigned int pending)
{
if (pending & CAUSEF_IP7)
do_IRQ(LOONGSON_TIMER_IRQ);
+#if defined(CONFIG_SMP)
+ else if (pending & CAUSEF_IP6)
+ loongson3_ipi_interrupt(NULL);
+#endif
else if (pending & CAUSEF_IP3)
ht_irqdispatch();
else if (pending & CAUSEF_IP2)
@@ -45,10 +49,26 @@ static inline void mask_loongson_irq(struct irq_data *d)
{
clear_c0_status(0x100 << (d->irq - MIPS_CPU_IRQ_BASE));
irq_disable_hazard();
+
+ /* Workaround: UART IRQ may deliver to any core */
+ if (d->irq == LOONGSON_UART_IRQ) {
+ int cpu = smp_processor_id();
+
+ LOONGSON_INT_ROUTER_INTENCLR = 1 << 10;
+ LOONGSON_INT_ROUTER_LPC = 0x10 + (1<<cpu);
+ }
}
static inline void unmask_loongson_irq(struct irq_data *d)
{
+ /* Workaround: UART IRQ may deliver to any core */
+ if (d->irq == LOONGSON_UART_IRQ) {
+ int cpu = smp_processor_id();
+
+ LOONGSON_INT_ROUTER_INTENSET = 1 << 10;
+ LOONGSON_INT_ROUTER_LPC = 0x10 + (1<<cpu);
+ }
+
set_c0_status(0x100 << (d->irq - MIPS_CPU_IRQ_BASE));
irq_enable_hazard();
}
OpenPOWER on IntegriCloud