1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later 2*4882a593Smuzhiyun /* 3*4882a593Smuzhiyun * Copyright 2011 Freescale Semiconductor, Inc. 4*4882a593Smuzhiyun * Copyright 2011 Linaro Ltd. 5*4882a593Smuzhiyun */ 6*4882a593Smuzhiyun 7*4882a593Smuzhiyun #include <linux/errno.h> 8*4882a593Smuzhiyun #include <linux/jiffies.h> 9*4882a593Smuzhiyun #include <asm/cacheflush.h> 10*4882a593Smuzhiyun #include <asm/cp15.h> 11*4882a593Smuzhiyun #include <asm/proc-fns.h> 12*4882a593Smuzhiyun 13*4882a593Smuzhiyun #include "common.h" 14*4882a593Smuzhiyun 15*4882a593Smuzhiyun /* 16*4882a593Smuzhiyun * platform-specific code to shutdown a CPU 17*4882a593Smuzhiyun * 18*4882a593Smuzhiyun * Called with IRQs disabled 19*4882a593Smuzhiyun */ imx_cpu_die(unsigned int cpu)20*4882a593Smuzhiyunvoid imx_cpu_die(unsigned int cpu) 21*4882a593Smuzhiyun { 22*4882a593Smuzhiyun v7_exit_coherency_flush(louis); 23*4882a593Smuzhiyun /* 24*4882a593Smuzhiyun * We use the cpu jumping argument register to sync with 25*4882a593Smuzhiyun * imx_cpu_kill() which is running on cpu0 and waiting for 26*4882a593Smuzhiyun * the register being cleared to kill the cpu. 27*4882a593Smuzhiyun */ 28*4882a593Smuzhiyun imx_set_cpu_arg(cpu, ~0); 29*4882a593Smuzhiyun 30*4882a593Smuzhiyun while (1) 31*4882a593Smuzhiyun cpu_do_idle(); 32*4882a593Smuzhiyun } 33*4882a593Smuzhiyun imx_cpu_kill(unsigned int cpu)34*4882a593Smuzhiyunint imx_cpu_kill(unsigned int cpu) 35*4882a593Smuzhiyun { 36*4882a593Smuzhiyun unsigned long timeout = jiffies + msecs_to_jiffies(50); 37*4882a593Smuzhiyun 38*4882a593Smuzhiyun while (imx_get_cpu_arg(cpu) == 0) 39*4882a593Smuzhiyun if (time_after(jiffies, timeout)) 40*4882a593Smuzhiyun return 0; 41*4882a593Smuzhiyun imx_enable_cpu(cpu, false); 42*4882a593Smuzhiyun imx_set_cpu_arg(cpu, 0); 43*4882a593Smuzhiyun return 1; 44*4882a593Smuzhiyun } 45