summaryrefslogtreecommitdiff
path: root/arch/openrisc/kernel/smp.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/openrisc/kernel/smp.c')
-rw-r--r--arch/openrisc/kernel/smp.c22
1 files changed, 21 insertions, 1 deletions
diff --git a/arch/openrisc/kernel/smp.c b/arch/openrisc/kernel/smp.c
index 86da4bc5ee0b..040ca201b692 100644
--- a/arch/openrisc/kernel/smp.c
+++ b/arch/openrisc/kernel/smp.c
@@ -13,6 +13,7 @@
#include <linux/smp.h>
#include <linux/cpu.h>
+#include <linux/interrupt.h>
#include <linux/sched.h>
#include <linux/sched/mm.h>
#include <linux/irq.h>
@@ -25,6 +26,7 @@
asmlinkage __init void secondary_start_kernel(void);
+static unsigned int ipi_irq __ro_after_init;
static void (*smp_cross_call)(const struct cpumask *, unsigned int);
unsigned long secondary_release = -1;
@@ -39,6 +41,14 @@ enum ipi_msg_type {
static DEFINE_SPINLOCK(boot_lock);
+static void or1k_ipi_enable(void)
+{
+ if (WARN_ON_ONCE(!ipi_irq))
+ return;
+
+ enable_percpu_irq(ipi_irq, 0);
+}
+
static void boot_secondary(unsigned int cpu, struct task_struct *idle)
{
/*
@@ -136,6 +146,7 @@ asmlinkage __init void secondary_start_kernel(void)
complete(&cpu_running);
synchronise_count_slave(cpu);
+ or1k_ipi_enable();
set_cpu_online(cpu, true);
local_irq_enable();
@@ -195,9 +206,18 @@ void smp_send_stop(void)
smp_call_function(stop_this_cpu, NULL, 0);
}
-void __init set_smp_cross_call(void (*fn)(const struct cpumask *, unsigned int))
+void __init set_smp_cross_call(void (*fn)(const struct cpumask *, unsigned int),
+ unsigned int irq)
{
+ if (WARN_ON(ipi_irq))
+ return;
+
smp_cross_call = fn;
+
+ ipi_irq = irq;
+
+ /* Enabled IPIs for boot CPU immediately */
+ or1k_ipi_enable();
}
void arch_send_call_function_single_ipi(int cpu)