162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * arch/arm/include/asm/smp.h 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (C) 2004-2005 ARM Ltd. 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci#ifndef __ASM_ARM_SMP_H 862306a36Sopenharmony_ci#define __ASM_ARM_SMP_H 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#include <linux/threads.h> 1162306a36Sopenharmony_ci#include <linux/cpumask.h> 1262306a36Sopenharmony_ci#include <linux/thread_info.h> 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci#ifndef CONFIG_SMP 1562306a36Sopenharmony_ci# error "<asm/smp.h> included in non-SMP build" 1662306a36Sopenharmony_ci#endif 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci#define raw_smp_processor_id() (current_thread_info()->cpu) 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_cistruct seq_file; 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci/* 2362306a36Sopenharmony_ci * generate IPI list text 2462306a36Sopenharmony_ci */ 2562306a36Sopenharmony_ciextern void show_ipi_list(struct seq_file *, int); 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci/* 2862306a36Sopenharmony_ci * Called from C code, this handles an IPI. 2962306a36Sopenharmony_ci */ 3062306a36Sopenharmony_civoid handle_IPI(int ipinr, struct pt_regs *regs); 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ci/* 3362306a36Sopenharmony_ci * Setup the set of possible CPUs (via set_cpu_possible) 3462306a36Sopenharmony_ci */ 3562306a36Sopenharmony_ciextern void smp_init_cpus(void); 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci/* 3862306a36Sopenharmony_ci * Register IPI interrupts with the arch SMP code 3962306a36Sopenharmony_ci */ 4062306a36Sopenharmony_ciextern void set_smp_ipi_range(int ipi_base, int nr_ipi); 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci/* 4362306a36Sopenharmony_ci * Called from platform specific assembly code, this is the 4462306a36Sopenharmony_ci * secondary CPU entry point. 4562306a36Sopenharmony_ci */ 4662306a36Sopenharmony_ciasmlinkage void secondary_start_kernel(struct task_struct *task); 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_ci/* 5062306a36Sopenharmony_ci * Initial data for bringing up a secondary CPU. 5162306a36Sopenharmony_ci */ 5262306a36Sopenharmony_cistruct secondary_data { 5362306a36Sopenharmony_ci union { 5462306a36Sopenharmony_ci struct mpu_rgn_info *mpu_rgn_info; 5562306a36Sopenharmony_ci u64 pgdir; 5662306a36Sopenharmony_ci }; 5762306a36Sopenharmony_ci unsigned long swapper_pg_dir; 5862306a36Sopenharmony_ci void *stack; 5962306a36Sopenharmony_ci struct task_struct *task; 6062306a36Sopenharmony_ci}; 6162306a36Sopenharmony_ciextern struct secondary_data secondary_data; 6262306a36Sopenharmony_ciextern void secondary_startup(void); 6362306a36Sopenharmony_ciextern void secondary_startup_arm(void); 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ciextern int __cpu_disable(void); 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_cistatic inline void __cpu_die(unsigned int cpu) { } 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ciextern void arch_send_call_function_single_ipi(int cpu); 7062306a36Sopenharmony_ciextern void arch_send_call_function_ipi_mask(const struct cpumask *mask); 7162306a36Sopenharmony_ciextern void arch_send_wakeup_ipi_mask(const struct cpumask *mask); 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_ciextern int register_ipi_completion(struct completion *completion, int cpu); 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_cistruct smp_operations { 7662306a36Sopenharmony_ci#ifdef CONFIG_SMP 7762306a36Sopenharmony_ci /* 7862306a36Sopenharmony_ci * Setup the set of possible CPUs (via set_cpu_possible) 7962306a36Sopenharmony_ci */ 8062306a36Sopenharmony_ci void (*smp_init_cpus)(void); 8162306a36Sopenharmony_ci /* 8262306a36Sopenharmony_ci * Initialize cpu_possible map, and enable coherency 8362306a36Sopenharmony_ci */ 8462306a36Sopenharmony_ci void (*smp_prepare_cpus)(unsigned int max_cpus); 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci /* 8762306a36Sopenharmony_ci * Perform platform specific initialisation of the specified CPU. 8862306a36Sopenharmony_ci */ 8962306a36Sopenharmony_ci void (*smp_secondary_init)(unsigned int cpu); 9062306a36Sopenharmony_ci /* 9162306a36Sopenharmony_ci * Boot a secondary CPU, and assign it the specified idle task. 9262306a36Sopenharmony_ci * This also gives us the initial stack to use for this CPU. 9362306a36Sopenharmony_ci */ 9462306a36Sopenharmony_ci int (*smp_boot_secondary)(unsigned int cpu, struct task_struct *idle); 9562306a36Sopenharmony_ci#ifdef CONFIG_HOTPLUG_CPU 9662306a36Sopenharmony_ci int (*cpu_kill)(unsigned int cpu); 9762306a36Sopenharmony_ci void (*cpu_die)(unsigned int cpu); 9862306a36Sopenharmony_ci bool (*cpu_can_disable)(unsigned int cpu); 9962306a36Sopenharmony_ci int (*cpu_disable)(unsigned int cpu); 10062306a36Sopenharmony_ci#endif 10162306a36Sopenharmony_ci#endif 10262306a36Sopenharmony_ci}; 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_cistruct of_cpu_method { 10562306a36Sopenharmony_ci const char *method; 10662306a36Sopenharmony_ci const struct smp_operations *ops; 10762306a36Sopenharmony_ci}; 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ci#define CPU_METHOD_OF_DECLARE(name, _method, _ops) \ 11062306a36Sopenharmony_ci static const struct of_cpu_method __cpu_method_of_table_##name \ 11162306a36Sopenharmony_ci __used __section("__cpu_method_of_table") \ 11262306a36Sopenharmony_ci = { .method = _method, .ops = _ops } 11362306a36Sopenharmony_ci/* 11462306a36Sopenharmony_ci * set platform specific SMP operations 11562306a36Sopenharmony_ci */ 11662306a36Sopenharmony_ciextern void smp_set_ops(const struct smp_operations *); 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ci#endif /* ifndef __ASM_ARM_SMP_H */ 119