smp.c (398539dd69341f8e3b87b8fea9355c7edfb6d99a) | smp.c (859e5f45cbb33fe5d591a8e429667f0b7d4f4be8) |
---|---|
1// SPDX-License-Identifier: GPL-2.0 2 3#include <linux/module.h> 4#include <linux/init.h> 5#include <linux/kernel.h> 6#include <linux/mm.h> 7#include <linux/sched.h> 8#include <linux/kernel_stat.h> 9#include <linux/notifier.h> 10#include <linux/cpu.h> 11#include <linux/percpu.h> 12#include <linux/delay.h> 13#include <linux/err.h> 14#include <linux/irq.h> 15#include <linux/irqdomain.h> 16#include <linux/of.h> 17#include <linux/sched/task_stack.h> 18#include <linux/sched/mm.h> | 1// SPDX-License-Identifier: GPL-2.0 2 3#include <linux/module.h> 4#include <linux/init.h> 5#include <linux/kernel.h> 6#include <linux/mm.h> 7#include <linux/sched.h> 8#include <linux/kernel_stat.h> 9#include <linux/notifier.h> 10#include <linux/cpu.h> 11#include <linux/percpu.h> 12#include <linux/delay.h> 13#include <linux/err.h> 14#include <linux/irq.h> 15#include <linux/irqdomain.h> 16#include <linux/of.h> 17#include <linux/sched/task_stack.h> 18#include <linux/sched/mm.h> |
19#include <linux/sched/hotplug.h> |
|
19#include <asm/irq.h> 20#include <asm/traps.h> 21#include <asm/sections.h> 22#include <asm/mmu_context.h> 23#include <asm/pgalloc.h> 24 25struct ipi_data_struct { 26 unsigned long bits ____cacheline_aligned; --- 80 unchanged lines hidden (view full) --- 107void __init smp_prepare_boot_cpu(void) 108{ 109} 110 111void __init smp_prepare_cpus(unsigned int max_cpus) 112{ 113} 114 | 20#include <asm/irq.h> 21#include <asm/traps.h> 22#include <asm/sections.h> 23#include <asm/mmu_context.h> 24#include <asm/pgalloc.h> 25 26struct ipi_data_struct { 27 unsigned long bits ____cacheline_aligned; --- 80 unchanged lines hidden (view full) --- 108void __init smp_prepare_boot_cpu(void) 109{ 110} 111 112void __init smp_prepare_cpus(unsigned int max_cpus) 113{ 114} 115 |
115static void __init enable_smp_ipi(void) 116{ 117 enable_percpu_irq(ipi_irq, 0); 118} 119 | |
120static int ipi_dummy_dev; | 116static int ipi_dummy_dev; |
117 |
|
121void __init setup_smp_ipi(void) 122{ 123 int rc; 124 125 if (ipi_irq == 0) 126 panic("%s IRQ mapping failed\n", __func__); 127 128 rc = request_percpu_irq(ipi_irq, handle_ipi, "IPI Interrupt", 129 &ipi_dummy_dev); 130 if (rc) 131 panic("%s IRQ request failed\n", __func__); 132 | 118void __init setup_smp_ipi(void) 119{ 120 int rc; 121 122 if (ipi_irq == 0) 123 panic("%s IRQ mapping failed\n", __func__); 124 125 rc = request_percpu_irq(ipi_irq, handle_ipi, "IPI Interrupt", 126 &ipi_dummy_dev); 127 if (rc) 128 panic("%s IRQ request failed\n", __func__); 129 |
133 enable_smp_ipi(); | 130 enable_percpu_irq(ipi_irq, 0); |
134} 135 136void __init setup_smp(void) 137{ 138 struct device_node *node = NULL; 139 int cpu; 140 141 for_each_of_cpu_node(node) { --- 14 unchanged lines hidden (view full) --- 156extern void _start_smp_secondary(void); 157 158volatile unsigned int secondary_hint; 159volatile unsigned int secondary_ccr; 160volatile unsigned int secondary_stack; 161 162int __cpu_up(unsigned int cpu, struct task_struct *tidle) 163{ | 131} 132 133void __init setup_smp(void) 134{ 135 struct device_node *node = NULL; 136 int cpu; 137 138 for_each_of_cpu_node(node) { --- 14 unchanged lines hidden (view full) --- 153extern void _start_smp_secondary(void); 154 155volatile unsigned int secondary_hint; 156volatile unsigned int secondary_ccr; 157volatile unsigned int secondary_stack; 158 159int __cpu_up(unsigned int cpu, struct task_struct *tidle) 160{ |
164 unsigned int tmp; | 161 unsigned long mask = 1 << cpu; |
165 | 162 |
166 secondary_stack = (unsigned int)tidle->stack + THREAD_SIZE; 167 | 163 secondary_stack = (unsigned int)tidle->stack + THREAD_SIZE - 8; |
168 secondary_hint = mfcr("cr31"); | 164 secondary_hint = mfcr("cr31"); |
169 | |
170 secondary_ccr = mfcr("cr18"); 171 172 /* 173 * Because other CPUs are in reset status, we must flush data 174 * from cache to out and secondary CPUs use them in 175 * csky_start_secondary(void) 176 */ 177 mtcr("cr17", 0x22); 178 | 165 secondary_ccr = mfcr("cr18"); 166 167 /* 168 * Because other CPUs are in reset status, we must flush data 169 * from cache to out and secondary CPUs use them in 170 * csky_start_secondary(void) 171 */ 172 mtcr("cr17", 0x22); 173 |
179 /* Enable cpu in SMP reset ctrl reg */ 180 tmp = mfcr("cr<29, 0>"); 181 tmp |= 1 << cpu; 182 mtcr("cr<29, 0>", tmp); | 174 if (mask & mfcr("cr<29, 0>")) { 175 send_arch_ipi(cpumask_of(cpu)); 176 } else { 177 /* Enable cpu in SMP reset ctrl reg */ 178 mask |= mfcr("cr<29, 0>"); 179 mtcr("cr<29, 0>", mask); 180 } |
183 184 /* Wait for the cpu online */ 185 while (!cpu_online(cpu)); 186 187 secondary_stack = 0; 188 189 return 0; 190} --- 23 unchanged lines hidden (view full) --- 214 TLBMISS_HANDLER_SETUP_PGD_KERNEL(swapper_pg_dir); 215 216 asid_cache(smp_processor_id()) = ASID_FIRST_VERSION; 217 218#ifdef CONFIG_CPU_HAS_FPU 219 init_fpu(); 220#endif 221 | 181 182 /* Wait for the cpu online */ 183 while (!cpu_online(cpu)); 184 185 secondary_stack = 0; 186 187 return 0; 188} --- 23 unchanged lines hidden (view full) --- 212 TLBMISS_HANDLER_SETUP_PGD_KERNEL(swapper_pg_dir); 213 214 asid_cache(smp_processor_id()) = ASID_FIRST_VERSION; 215 216#ifdef CONFIG_CPU_HAS_FPU 217 init_fpu(); 218#endif 219 |
222 enable_smp_ipi(); | 220 enable_percpu_irq(ipi_irq, 0); |
223 224 mmget(mm); 225 mmgrab(mm); 226 current->active_mm = mm; 227 cpumask_set_cpu(cpu, mm_cpumask(mm)); 228 229 notify_cpu_starting(cpu); 230 set_cpu_online(cpu, true); 231 232 pr_info("CPU%u Online: %s...\n", cpu, __func__); 233 234 local_irq_enable(); 235 preempt_disable(); 236 cpu_startup_entry(CPUHP_AP_ONLINE_IDLE); 237} | 221 222 mmget(mm); 223 mmgrab(mm); 224 current->active_mm = mm; 225 cpumask_set_cpu(cpu, mm_cpumask(mm)); 226 227 notify_cpu_starting(cpu); 228 set_cpu_online(cpu, true); 229 230 pr_info("CPU%u Online: %s...\n", cpu, __func__); 231 232 local_irq_enable(); 233 preempt_disable(); 234 cpu_startup_entry(CPUHP_AP_ONLINE_IDLE); 235} |
236 237#ifdef CONFIG_HOTPLUG_CPU 238int __cpu_disable(void) 239{ 240 unsigned int cpu = smp_processor_id(); 241 242 set_cpu_online(cpu, false); 243 244 irq_migrate_all_off_this_cpu(); 245 246 clear_tasks_mm_cpumask(cpu); 247 248 return 0; 249} 250 251void __cpu_die(unsigned int cpu) 252{ 253 if (!cpu_wait_death(cpu, 5)) { 254 pr_crit("CPU%u: shutdown failed\n", cpu); 255 return; 256 } 257 pr_notice("CPU%u: shutdown\n", cpu); 258} 259 260void arch_cpu_idle_dead(void) 261{ 262 idle_task_exit(); 263 264 cpu_report_death(); 265 266 while (!secondary_stack) 267 arch_cpu_idle(); 268 269 local_irq_disable(); 270 271 asm volatile( 272 "mov sp, %0\n" 273 "mov r8, %0\n" 274 "jmpi csky_start_secondary" 275 : 276 : "r" (secondary_stack)); 277} 278#endif |
|