18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci#include <linux/delay.h> 38c2ecf20Sopenharmony_ci#include <linux/init.h> 48c2ecf20Sopenharmony_ci#include <linux/smp.h> 58c2ecf20Sopenharmony_ci#include "smc.h" 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_cistatic int tango_boot_secondary(unsigned int cpu, struct task_struct *idle) 88c2ecf20Sopenharmony_ci{ 98c2ecf20Sopenharmony_ci tango_set_aux_boot_addr(__pa_symbol(secondary_startup)); 108c2ecf20Sopenharmony_ci tango_start_aux_core(cpu); 118c2ecf20Sopenharmony_ci return 0; 128c2ecf20Sopenharmony_ci} 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ci#ifdef CONFIG_HOTPLUG_CPU 158c2ecf20Sopenharmony_ci/* 168c2ecf20Sopenharmony_ci * cpu_kill() and cpu_die() run concurrently on different cores. 178c2ecf20Sopenharmony_ci * Firmware will only "kill" a core once it has properly "died". 188c2ecf20Sopenharmony_ci * Try a few times to kill a core before giving up, and sleep 198c2ecf20Sopenharmony_ci * between tries to give that core enough time to die. 208c2ecf20Sopenharmony_ci */ 218c2ecf20Sopenharmony_cistatic int tango_cpu_kill(unsigned int cpu) 228c2ecf20Sopenharmony_ci{ 238c2ecf20Sopenharmony_ci int i, err; 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ci for (i = 0; i < 10; ++i) { 268c2ecf20Sopenharmony_ci msleep(10); 278c2ecf20Sopenharmony_ci err = tango_aux_core_kill(cpu); 288c2ecf20Sopenharmony_ci if (!err) 298c2ecf20Sopenharmony_ci return true; 308c2ecf20Sopenharmony_ci } 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci return false; 338c2ecf20Sopenharmony_ci} 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_cistatic void tango_cpu_die(unsigned int cpu) 368c2ecf20Sopenharmony_ci{ 378c2ecf20Sopenharmony_ci while (tango_aux_core_die(cpu) < 0) 388c2ecf20Sopenharmony_ci cpu_relax(); 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci panic("cpu %d failed to die\n", cpu); 418c2ecf20Sopenharmony_ci} 428c2ecf20Sopenharmony_ci#endif 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_cistatic const struct smp_operations tango_smp_ops __initconst = { 458c2ecf20Sopenharmony_ci .smp_boot_secondary = tango_boot_secondary, 468c2ecf20Sopenharmony_ci#ifdef CONFIG_HOTPLUG_CPU 478c2ecf20Sopenharmony_ci .cpu_kill = tango_cpu_kill, 488c2ecf20Sopenharmony_ci .cpu_die = tango_cpu_die, 498c2ecf20Sopenharmony_ci#endif 508c2ecf20Sopenharmony_ci}; 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_ciCPU_METHOD_OF_DECLARE(tango4_smp, "sigma,tango4-smp", &tango_smp_ops); 53