]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - arch/arc/kernel/mcip.c
Merge branch 'karo-tx6-mainline' into stable
[karo-tx-linux.git] / arch / arc / kernel / mcip.c
index 74a9b074ac3e4e64d97ef8e069f73a9104531682..30d806ce0c78273c4a1b917fb9bb876fac7ca793 100644 (file)
 #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 */
@@ -132,7 +147,7 @@ static void mcip_probe_n_setup(void)
 struct plat_smp_ops plat_smp_ops = {
        .info           = smp_cpuinfo_buf,
        .init_early_smp = mcip_probe_n_setup,
-       .init_irq_cpu   = mcip_setup_per_cpu,
+       .init_per_cpu   = mcip_setup_per_cpu,
        .ipi_send       = mcip_ipi_send,
        .ipi_clear      = mcip_ipi_clear,
 };