1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-only */ 2*4882a593Smuzhiyun /* 3*4882a593Smuzhiyun * arch/arm/include/asm/smp.h 4*4882a593Smuzhiyun * 5*4882a593Smuzhiyun * Copyright (C) 2004-2005 ARM Ltd. 6*4882a593Smuzhiyun */ 7*4882a593Smuzhiyun #ifndef __ASM_ARM_SMP_H 8*4882a593Smuzhiyun #define __ASM_ARM_SMP_H 9*4882a593Smuzhiyun 10*4882a593Smuzhiyun #include <linux/threads.h> 11*4882a593Smuzhiyun #include <linux/cpumask.h> 12*4882a593Smuzhiyun #include <linux/thread_info.h> 13*4882a593Smuzhiyun 14*4882a593Smuzhiyun #ifndef CONFIG_SMP 15*4882a593Smuzhiyun # error "<asm/smp.h> included in non-SMP build" 16*4882a593Smuzhiyun #endif 17*4882a593Smuzhiyun 18*4882a593Smuzhiyun #define raw_smp_processor_id() (current_thread_info()->cpu) 19*4882a593Smuzhiyun 20*4882a593Smuzhiyun struct seq_file; 21*4882a593Smuzhiyun 22*4882a593Smuzhiyun /* 23*4882a593Smuzhiyun * generate IPI list text 24*4882a593Smuzhiyun */ 25*4882a593Smuzhiyun extern void show_ipi_list(struct seq_file *, int); 26*4882a593Smuzhiyun 27*4882a593Smuzhiyun /* 28*4882a593Smuzhiyun * Called from assembly code, this handles an IPI. 29*4882a593Smuzhiyun */ 30*4882a593Smuzhiyun asmlinkage void do_IPI(int ipinr, struct pt_regs *regs); 31*4882a593Smuzhiyun 32*4882a593Smuzhiyun /* 33*4882a593Smuzhiyun * Called from C code, this handles an IPI. 34*4882a593Smuzhiyun */ 35*4882a593Smuzhiyun void handle_IPI(int ipinr, struct pt_regs *regs); 36*4882a593Smuzhiyun 37*4882a593Smuzhiyun /* 38*4882a593Smuzhiyun * Setup the set of possible CPUs (via set_cpu_possible) 39*4882a593Smuzhiyun */ 40*4882a593Smuzhiyun extern void smp_init_cpus(void); 41*4882a593Smuzhiyun 42*4882a593Smuzhiyun /* 43*4882a593Smuzhiyun * Register IPI interrupts with the arch SMP code 44*4882a593Smuzhiyun */ 45*4882a593Smuzhiyun extern void set_smp_ipi_range(int ipi_base, int nr_ipi); 46*4882a593Smuzhiyun 47*4882a593Smuzhiyun /* 48*4882a593Smuzhiyun * Called from platform specific assembly code, this is the 49*4882a593Smuzhiyun * secondary CPU entry point. 50*4882a593Smuzhiyun */ 51*4882a593Smuzhiyun asmlinkage void secondary_start_kernel(void); 52*4882a593Smuzhiyun 53*4882a593Smuzhiyun 54*4882a593Smuzhiyun /* 55*4882a593Smuzhiyun * Initial data for bringing up a secondary CPU. 56*4882a593Smuzhiyun */ 57*4882a593Smuzhiyun struct secondary_data { 58*4882a593Smuzhiyun union { 59*4882a593Smuzhiyun struct mpu_rgn_info *mpu_rgn_info; 60*4882a593Smuzhiyun u64 pgdir; 61*4882a593Smuzhiyun }; 62*4882a593Smuzhiyun unsigned long swapper_pg_dir; 63*4882a593Smuzhiyun void *stack; 64*4882a593Smuzhiyun }; 65*4882a593Smuzhiyun extern struct secondary_data secondary_data; 66*4882a593Smuzhiyun extern void secondary_startup(void); 67*4882a593Smuzhiyun extern void secondary_startup_arm(void); 68*4882a593Smuzhiyun 69*4882a593Smuzhiyun extern int __cpu_disable(void); 70*4882a593Smuzhiyun 71*4882a593Smuzhiyun extern void __cpu_die(unsigned int cpu); 72*4882a593Smuzhiyun 73*4882a593Smuzhiyun extern void arch_send_call_function_single_ipi(int cpu); 74*4882a593Smuzhiyun extern void arch_send_call_function_ipi_mask(const struct cpumask *mask); 75*4882a593Smuzhiyun extern void arch_send_wakeup_ipi_mask(const struct cpumask *mask); 76*4882a593Smuzhiyun 77*4882a593Smuzhiyun extern int register_ipi_completion(struct completion *completion, int cpu); 78*4882a593Smuzhiyun 79*4882a593Smuzhiyun struct smp_operations { 80*4882a593Smuzhiyun #ifdef CONFIG_SMP 81*4882a593Smuzhiyun /* 82*4882a593Smuzhiyun * Setup the set of possible CPUs (via set_cpu_possible) 83*4882a593Smuzhiyun */ 84*4882a593Smuzhiyun void (*smp_init_cpus)(void); 85*4882a593Smuzhiyun /* 86*4882a593Smuzhiyun * Initialize cpu_possible map, and enable coherency 87*4882a593Smuzhiyun */ 88*4882a593Smuzhiyun void (*smp_prepare_cpus)(unsigned int max_cpus); 89*4882a593Smuzhiyun 90*4882a593Smuzhiyun /* 91*4882a593Smuzhiyun * Perform platform specific initialisation of the specified CPU. 92*4882a593Smuzhiyun */ 93*4882a593Smuzhiyun void (*smp_secondary_init)(unsigned int cpu); 94*4882a593Smuzhiyun /* 95*4882a593Smuzhiyun * Boot a secondary CPU, and assign it the specified idle task. 96*4882a593Smuzhiyun * This also gives us the initial stack to use for this CPU. 97*4882a593Smuzhiyun */ 98*4882a593Smuzhiyun int (*smp_boot_secondary)(unsigned int cpu, struct task_struct *idle); 99*4882a593Smuzhiyun #ifdef CONFIG_HOTPLUG_CPU 100*4882a593Smuzhiyun int (*cpu_kill)(unsigned int cpu); 101*4882a593Smuzhiyun void (*cpu_die)(unsigned int cpu); 102*4882a593Smuzhiyun bool (*cpu_can_disable)(unsigned int cpu); 103*4882a593Smuzhiyun int (*cpu_disable)(unsigned int cpu); 104*4882a593Smuzhiyun #endif 105*4882a593Smuzhiyun #endif 106*4882a593Smuzhiyun }; 107*4882a593Smuzhiyun 108*4882a593Smuzhiyun struct of_cpu_method { 109*4882a593Smuzhiyun const char *method; 110*4882a593Smuzhiyun const struct smp_operations *ops; 111*4882a593Smuzhiyun }; 112*4882a593Smuzhiyun 113*4882a593Smuzhiyun #define CPU_METHOD_OF_DECLARE(name, _method, _ops) \ 114*4882a593Smuzhiyun static const struct of_cpu_method __cpu_method_of_table_##name \ 115*4882a593Smuzhiyun __used __section("__cpu_method_of_table") \ 116*4882a593Smuzhiyun = { .method = _method, .ops = _ops } 117*4882a593Smuzhiyun /* 118*4882a593Smuzhiyun * set platform specific SMP operations 119*4882a593Smuzhiyun */ 120*4882a593Smuzhiyun extern void smp_set_ops(const struct smp_operations *); 121*4882a593Smuzhiyun 122*4882a593Smuzhiyun #endif /* ifndef __ASM_ARM_SMP_H */ 123