diff options
Diffstat (limited to 'arch/openrisc/kernel/smp.c')
| -rw-r--r-- | arch/openrisc/kernel/smp.c | 22 |
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) |
