|
@@ -11,9 +11,12 @@
|
|
|
#include <linux/smp.h>
|
|
|
#include <linux/irq.h>
|
|
|
#include <linux/spinlock.h>
|
|
|
+#include <asm/irqflags-arcv2.h>
|
|
|
#include <asm/mcip.h>
|
|
|
#include <asm/setup.h>
|
|
|
|
|
|
+#define SOFTIRQ_IRQ 21
|
|
|
+
|
|
|
static char smp_cpuinfo_buf[128];
|
|
|
static int idu_detected;
|
|
|
|
|
@@ -22,6 +25,7 @@ static DEFINE_RAW_SPINLOCK(mcip_lock);
|
|
|
static void mcip_setup_per_cpu(int cpu)
|
|
|
{
|
|
|
smp_ipi_irq_setup(cpu, IPI_IRQ);
|
|
|
+ smp_ipi_irq_setup(cpu, SOFTIRQ_IRQ);
|
|
|
}
|
|
|
|
|
|
static void mcip_ipi_send(int cpu)
|
|
@@ -29,6 +33,12 @@ static void mcip_ipi_send(int cpu)
|
|
|
unsigned long flags;
|
|
|
int ipi_was_pending;
|
|
|
|
|
|
+ /* ARConnect can only send IPI to others */
|
|
|
+ if (unlikely(cpu == raw_smp_processor_id())) {
|
|
|
+ arc_softirq_trigger(SOFTIRQ_IRQ);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
/*
|
|
|
* NOTE: We must spin here if the other cpu hasn't yet
|
|
|
* serviced a previous message. This can burn lots
|
|
@@ -63,6 +73,11 @@ static void mcip_ipi_clear(int irq)
|
|
|
unsigned long flags;
|
|
|
unsigned int __maybe_unused copy;
|
|
|
|
|
|
+ if (unlikely(irq == SOFTIRQ_IRQ)) {
|
|
|
+ arc_softirq_clear(irq);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
raw_spin_lock_irqsave(&mcip_lock, flags);
|
|
|
|
|
|
/* Who sent the IPI */
|