1d2912cb1SThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */ 24baa9922SRussell King /* 34baa9922SRussell King * arch/arm/include/asm/smp.h 44baa9922SRussell King * 54baa9922SRussell King * Copyright (C) 2004-2005 ARM Ltd. 64baa9922SRussell King */ 74baa9922SRussell King #ifndef __ASM_ARM_SMP_H 84baa9922SRussell King #define __ASM_ARM_SMP_H 94baa9922SRussell King 104baa9922SRussell King #include <linux/threads.h> 114baa9922SRussell King #include <linux/cpumask.h> 124baa9922SRussell King #include <linux/thread_info.h> 134baa9922SRussell King 144baa9922SRussell King #ifndef CONFIG_SMP 154baa9922SRussell King # error "<asm/smp.h> included in non-SMP build" 164baa9922SRussell King #endif 174baa9922SRussell King 184baa9922SRussell King #define raw_smp_processor_id() (current_thread_info()->cpu) 194baa9922SRussell King 204baa9922SRussell King struct seq_file; 214baa9922SRussell King 224baa9922SRussell King /* 234baa9922SRussell King * generate IPI list text 244baa9922SRussell King */ 25f13cd417SRussell King extern void show_ipi_list(struct seq_file *, int); 264baa9922SRussell King 274baa9922SRussell King /* 280b5a1b95SShawn Guo * Called from C code, this handles an IPI. 290b5a1b95SShawn Guo */ 300b5a1b95SShawn Guo void handle_IPI(int ipinr, struct pt_regs *regs); 310b5a1b95SShawn Guo 320b5a1b95SShawn Guo /* 33e03cdadeSRussell King * Setup the set of possible CPUs (via set_cpu_possible) 344baa9922SRussell King */ 354baa9922SRussell King extern void smp_init_cpus(void); 364baa9922SRussell King 374baa9922SRussell King /* 3856afcd3dSMarc Zyngier * Register IPI interrupts with the arch SMP code 3956afcd3dSMarc Zyngier */ 4056afcd3dSMarc Zyngier extern void set_smp_ipi_range(int ipi_base, int nr_ipi); 4156afcd3dSMarc Zyngier 4256afcd3dSMarc Zyngier /* 434baa9922SRussell King * Called from platform specific assembly code, this is the 444baa9922SRussell King * secondary CPU entry point. 454baa9922SRussell King */ 4619f29aebSKeith Packard asmlinkage void secondary_start_kernel(struct task_struct *task); 474baa9922SRussell King 4805c74a6cSRussell King 4905c74a6cSRussell King /* 504baa9922SRussell King * Initial data for bringing up a secondary CPU. 514baa9922SRussell King */ 524baa9922SRussell King struct secondary_data { 53eb08375eSJonathan Austin union { 54a0995c08SVladimir Murzin struct mpu_rgn_info *mpu_rgn_info; 55b2c3e38aSRussell King u64 pgdir; 56eb08375eSJonathan Austin }; 57d427958aSCatalin Marinas unsigned long swapper_pg_dir; 584baa9922SRussell King void *stack; 5919f29aebSKeith Packard struct task_struct *task; 604baa9922SRussell King }; 614baa9922SRussell King extern struct secondary_data secondary_data; 621146b600SArnd Bergmann extern void secondary_startup(void); 6329d2e563SYingjoe Chen extern void secondary_startup_arm(void); 644baa9922SRussell King 654baa9922SRussell King extern int __cpu_disable(void); 664baa9922SRussell King 67*5490e769SThomas Gleixner static inline void __cpu_die(unsigned int cpu) { } 684baa9922SRussell King 694baa9922SRussell King extern void arch_send_call_function_single_ipi(int cpu); 7082668104SRussell King extern void arch_send_call_function_ipi_mask(const struct cpumask *mask); 71b62655f4SShawn Guo extern void arch_send_wakeup_ipi_mask(const struct cpumask *mask); 724baa9922SRussell King 735135d875SNicolas Pitre extern int register_ipi_completion(struct completion *completion, int cpu); 745135d875SNicolas Pitre 75abcee5fbSMarc Zyngier struct smp_operations { 76abcee5fbSMarc Zyngier #ifdef CONFIG_SMP 77abcee5fbSMarc Zyngier /* 78abcee5fbSMarc Zyngier * Setup the set of possible CPUs (via set_cpu_possible) 79abcee5fbSMarc Zyngier */ 80abcee5fbSMarc Zyngier void (*smp_init_cpus)(void); 81abcee5fbSMarc Zyngier /* 82abcee5fbSMarc Zyngier * Initialize cpu_possible map, and enable coherency 83abcee5fbSMarc Zyngier */ 84abcee5fbSMarc Zyngier void (*smp_prepare_cpus)(unsigned int max_cpus); 85abcee5fbSMarc Zyngier 86abcee5fbSMarc Zyngier /* 87abcee5fbSMarc Zyngier * Perform platform specific initialisation of the specified CPU. 88abcee5fbSMarc Zyngier */ 89abcee5fbSMarc Zyngier void (*smp_secondary_init)(unsigned int cpu); 90abcee5fbSMarc Zyngier /* 91abcee5fbSMarc Zyngier * Boot a secondary CPU, and assign it the specified idle task. 92abcee5fbSMarc Zyngier * This also gives us the initial stack to use for this CPU. 93abcee5fbSMarc Zyngier */ 94abcee5fbSMarc Zyngier int (*smp_boot_secondary)(unsigned int cpu, struct task_struct *idle); 95abcee5fbSMarc Zyngier #ifdef CONFIG_HOTPLUG_CPU 96abcee5fbSMarc Zyngier int (*cpu_kill)(unsigned int cpu); 97abcee5fbSMarc Zyngier void (*cpu_die)(unsigned int cpu); 98787047eeSStephen Boyd bool (*cpu_can_disable)(unsigned int cpu); 99abcee5fbSMarc Zyngier int (*cpu_disable)(unsigned int cpu); 100abcee5fbSMarc Zyngier #endif 101abcee5fbSMarc Zyngier #endif 102abcee5fbSMarc Zyngier }; 103abcee5fbSMarc Zyngier 1046c3ff8b1SStephen Boyd struct of_cpu_method { 1056c3ff8b1SStephen Boyd const char *method; 106f460b6abSMasahiro Yamada const struct smp_operations *ops; 1076c3ff8b1SStephen Boyd }; 1086c3ff8b1SStephen Boyd 1096c3ff8b1SStephen Boyd #define CPU_METHOD_OF_DECLARE(name, _method, _ops) \ 1106c3ff8b1SStephen Boyd static const struct of_cpu_method __cpu_method_of_table_##name \ 11133def849SJoe Perches __used __section("__cpu_method_of_table") \ 1126c3ff8b1SStephen Boyd = { .method = _method, .ops = _ops } 113abcee5fbSMarc Zyngier /* 114abcee5fbSMarc Zyngier * set platform specific SMP operations 115abcee5fbSMarc Zyngier */ 1164caa9ddaSMasahiro Yamada extern void smp_set_ops(const struct smp_operations *); 117abcee5fbSMarc Zyngier 1184baa9922SRussell King #endif /* ifndef __ASM_ARM_SMP_H */ 119