1 /* 2 * SMP support for R-Mobile / SH-Mobile 3 * 4 * Copyright (C) 2010 Magnus Damm 5 * 6 * Based on realview, Copyright (C) 2002 ARM Ltd, All Rights Reserved 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License version 2 as 10 * published by the Free Software Foundation. 11 */ 12 #include <linux/kernel.h> 13 #include <linux/errno.h> 14 #include <linux/smp.h> 15 #include <linux/cpumask.h> 16 #include <linux/delay.h> 17 #include <mach/common.h> 18 #include <asm/cacheflush.h> 19 20 static cpumask_t dead_cpus; 21 platform_cpu_kill(unsigned int cpu)22int platform_cpu_kill(unsigned int cpu) 23 { 24 int k; 25 26 /* this function is running on another CPU than the offline target, 27 * here we need wait for shutdown code in platform_cpu_die() to 28 * finish before asking SoC-specific code to power off the CPU core. 29 */ 30 for (k = 0; k < 1000; k++) { 31 if (cpumask_test_cpu(cpu, &dead_cpus)) 32 return shmobile_platform_cpu_kill(cpu); 33 34 mdelay(1); 35 } 36 37 return 0; 38 } 39 platform_cpu_die(unsigned int cpu)40void platform_cpu_die(unsigned int cpu) 41 { 42 /* hardware shutdown code running on the CPU that is being offlined */ 43 flush_cache_all(); 44 dsb(); 45 46 /* notify platform_cpu_kill() that hardware shutdown is finished */ 47 cpumask_set_cpu(cpu, &dead_cpus); 48 49 /* wait for SoC code in platform_cpu_kill() to shut off CPU core 50 * power. CPU bring up starts from the reset vector. 51 */ 52 while (1) { 53 /* 54 * here's the WFI 55 */ 56 asm(".word 0xe320f003\n" 57 : 58 : 59 : "memory", "cc"); 60 } 61 } 62 platform_cpu_disable(unsigned int cpu)63int platform_cpu_disable(unsigned int cpu) 64 { 65 cpumask_clear_cpu(cpu, &dead_cpus); 66 /* 67 * we don't allow CPU 0 to be shutdown (it is still too special 68 * e.g. clock tick interrupts) 69 */ 70 return cpu == 0 ? -EPERM : 0; 71 } 72