projects
/
cascardo
/
linux.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
ARCv2: SMP: Push IPI_IRQ into IPI provider
[cascardo/linux.git]
/
arch
/
arc
/
kernel
/
mcip.c
diff --git
a/arch/arc/kernel/mcip.c
b/arch/arc/kernel/mcip.c
index
bd237ac
..
e30d5d4
100644
(file)
--- a/
arch/arc/kernel/mcip.c
+++ b/
arch/arc/kernel/mcip.c
@@
-11,9
+11,13
@@
#include <linux/smp.h>
#include <linux/irq.h>
#include <linux/spinlock.h>
#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>
#include <asm/mcip.h>
#include <asm/setup.h>
+#define IPI_IRQ 19
+#define SOFTIRQ_IRQ 21
+
static char smp_cpuinfo_buf[128];
static int idu_detected;
static char smp_cpuinfo_buf[128];
static int idu_detected;
@@
-22,6
+26,7
@@
static DEFINE_RAW_SPINLOCK(mcip_lock);
static void mcip_setup_per_cpu(int cpu)
{
smp_ipi_irq_setup(cpu, IPI_IRQ);
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)
}
static void mcip_ipi_send(int cpu)
@@
-29,6
+34,12
@@
static void mcip_ipi_send(int cpu)
unsigned long flags;
int ipi_was_pending;
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
/*
* NOTE: We must spin here if the other cpu hasn't yet
* serviced a previous message. This can burn lots
@@
-63,6
+74,11
@@
static void mcip_ipi_clear(int irq)
unsigned long flags;
unsigned int __maybe_unused copy;
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 */
raw_spin_lock_irqsave(&mcip_lock, flags);
/* Who sent the IPI */
@@
-96,13
+112,13
@@
static void mcip_probe_n_setup(void)
#ifdef CONFIG_CPU_BIG_ENDIAN
unsigned int pad3:8,
idu:1, llm:1, num_cores:6,
#ifdef CONFIG_CPU_BIG_ENDIAN
unsigned int pad3:8,
idu:1, llm:1, num_cores:6,
- iocoh:1, g
rt
c:1, dbg:1, pad2:1,
+ iocoh:1, g
fr
c:1, dbg:1, pad2:1,
msg:1, sem:1, ipi:1, pad:1,
ver:8;
#else
unsigned int ver:8,
pad:1, ipi:1, sem:1, msg:1,
msg:1, sem:1, ipi:1, pad:1,
ver:8;
#else
unsigned int ver:8,
pad:1, ipi:1, sem:1, msg:1,
- pad2:1, dbg:1, g
rt
c:1, iocoh:1,
+ pad2:1, dbg:1, g
fr
c:1, iocoh:1,
num_cores:6, llm:1, idu:1,
pad3:8;
#endif
num_cores:6, llm:1, idu:1,
pad3:8;
#endif
@@
-111,12
+127,13
@@
static void mcip_probe_n_setup(void)
READ_BCR(ARC_REG_MCIP_BCR, mp);
sprintf(smp_cpuinfo_buf,
READ_BCR(ARC_REG_MCIP_BCR, mp);
sprintf(smp_cpuinfo_buf,
- "Extn [SMP]\t: ARConnect (v%d): %d cores with %s%s%s%s\n",
+ "Extn [SMP]\t: ARConnect (v%d): %d cores with %s%s%s%s
%s
\n",
mp.ver, mp.num_cores,
IS_AVAIL1(mp.ipi, "IPI "),
IS_AVAIL1(mp.idu, "IDU "),
mp.ver, mp.num_cores,
IS_AVAIL1(mp.ipi, "IPI "),
IS_AVAIL1(mp.idu, "IDU "),
+ IS_AVAIL1(mp.llm, "LLM "),
IS_AVAIL1(mp.dbg, "DEBUG "),
IS_AVAIL1(mp.dbg, "DEBUG "),
- IS_AVAIL1(mp.g
rtc, "GRT
C"));
+ IS_AVAIL1(mp.g
frc, "GFR
C"));
idu_detected = mp.idu;
idu_detected = mp.idu;
@@
-125,8
+142,8
@@
static void mcip_probe_n_setup(void)
__mcip_cmd_data(CMD_DEBUG_SET_MASK, 0xf, 0xf);
}
__mcip_cmd_data(CMD_DEBUG_SET_MASK, 0xf, 0xf);
}
- if (IS_ENABLED(CONFIG_ARC_HAS_G
RTC) && !mp.grt
c)
- panic("kernel trying to use non-existent G
RT
C\n");
+ if (IS_ENABLED(CONFIG_ARC_HAS_G
FRC) && !mp.gfr
c)
+ panic("kernel trying to use non-existent G
FR
C\n");
}
struct plat_smp_ops plat_smp_ops = {
}
struct plat_smp_ops plat_smp_ops = {