xref: /OK3568_Linux_fs/kernel/arch/arm/include/asm/smp.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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