1*7d35b8d0SSantosh Shilimkar /* 2*7d35b8d0SSantosh Shilimkar * OMAP4 SMP cpu-hotplug support 3*7d35b8d0SSantosh Shilimkar * 4*7d35b8d0SSantosh Shilimkar * Copyright (C) 2010 Texas Instruments, Inc. 5*7d35b8d0SSantosh Shilimkar * Author: 6*7d35b8d0SSantosh Shilimkar * Santosh Shilimkar <santosh.shilimkar@ti.com> 7*7d35b8d0SSantosh Shilimkar * 8*7d35b8d0SSantosh Shilimkar * Platform file needed for the OMAP4 SMP. This file is based on arm 9*7d35b8d0SSantosh Shilimkar * realview smp platform. 10*7d35b8d0SSantosh Shilimkar * Copyright (c) 2002 ARM Limited. 11*7d35b8d0SSantosh Shilimkar * 12*7d35b8d0SSantosh Shilimkar * This program is free software; you can redistribute it and/or modify 13*7d35b8d0SSantosh Shilimkar * it under the terms of the GNU General Public License version 2 as 14*7d35b8d0SSantosh Shilimkar * published by the Free Software Foundation. 15*7d35b8d0SSantosh Shilimkar */ 16*7d35b8d0SSantosh Shilimkar 17*7d35b8d0SSantosh Shilimkar #include <linux/kernel.h> 18*7d35b8d0SSantosh Shilimkar #include <linux/errno.h> 19*7d35b8d0SSantosh Shilimkar #include <linux/smp.h> 20*7d35b8d0SSantosh Shilimkar #include <linux/completion.h> 21*7d35b8d0SSantosh Shilimkar 22*7d35b8d0SSantosh Shilimkar #include <asm/cacheflush.h> 23*7d35b8d0SSantosh Shilimkar #include <mach/omap4-common.h> 24*7d35b8d0SSantosh Shilimkar 25*7d35b8d0SSantosh Shilimkar static DECLARE_COMPLETION(cpu_killed); 26*7d35b8d0SSantosh Shilimkar 27*7d35b8d0SSantosh Shilimkar int platform_cpu_kill(unsigned int cpu) 28*7d35b8d0SSantosh Shilimkar { 29*7d35b8d0SSantosh Shilimkar return wait_for_completion_timeout(&cpu_killed, 5000); 30*7d35b8d0SSantosh Shilimkar } 31*7d35b8d0SSantosh Shilimkar 32*7d35b8d0SSantosh Shilimkar /* 33*7d35b8d0SSantosh Shilimkar * platform-specific code to shutdown a CPU 34*7d35b8d0SSantosh Shilimkar * Called with IRQs disabled 35*7d35b8d0SSantosh Shilimkar */ 36*7d35b8d0SSantosh Shilimkar void platform_cpu_die(unsigned int cpu) 37*7d35b8d0SSantosh Shilimkar { 38*7d35b8d0SSantosh Shilimkar unsigned int this_cpu = hard_smp_processor_id(); 39*7d35b8d0SSantosh Shilimkar 40*7d35b8d0SSantosh Shilimkar if (cpu != this_cpu) { 41*7d35b8d0SSantosh Shilimkar pr_crit("platform_cpu_die running on %u, should be %u\n", 42*7d35b8d0SSantosh Shilimkar this_cpu, cpu); 43*7d35b8d0SSantosh Shilimkar BUG(); 44*7d35b8d0SSantosh Shilimkar } 45*7d35b8d0SSantosh Shilimkar pr_notice("CPU%u: shutdown\n", cpu); 46*7d35b8d0SSantosh Shilimkar complete(&cpu_killed); 47*7d35b8d0SSantosh Shilimkar flush_cache_all(); 48*7d35b8d0SSantosh Shilimkar dsb(); 49*7d35b8d0SSantosh Shilimkar 50*7d35b8d0SSantosh Shilimkar /* 51*7d35b8d0SSantosh Shilimkar * we're ready for shutdown now, so do it 52*7d35b8d0SSantosh Shilimkar */ 53*7d35b8d0SSantosh Shilimkar if (omap_modify_auxcoreboot0(0x0, 0x200) != 0x0) 54*7d35b8d0SSantosh Shilimkar printk(KERN_CRIT "Secure clear status failed\n"); 55*7d35b8d0SSantosh Shilimkar 56*7d35b8d0SSantosh Shilimkar for (;;) { 57*7d35b8d0SSantosh Shilimkar /* 58*7d35b8d0SSantosh Shilimkar * Execute WFI 59*7d35b8d0SSantosh Shilimkar */ 60*7d35b8d0SSantosh Shilimkar do_wfi(); 61*7d35b8d0SSantosh Shilimkar 62*7d35b8d0SSantosh Shilimkar if (omap_read_auxcoreboot0() == cpu) { 63*7d35b8d0SSantosh Shilimkar /* 64*7d35b8d0SSantosh Shilimkar * OK, proper wakeup, we're done 65*7d35b8d0SSantosh Shilimkar */ 66*7d35b8d0SSantosh Shilimkar break; 67*7d35b8d0SSantosh Shilimkar } 68*7d35b8d0SSantosh Shilimkar pr_debug("CPU%u: spurious wakeup call\n", cpu); 69*7d35b8d0SSantosh Shilimkar } 70*7d35b8d0SSantosh Shilimkar } 71*7d35b8d0SSantosh Shilimkar 72*7d35b8d0SSantosh Shilimkar int platform_cpu_disable(unsigned int cpu) 73*7d35b8d0SSantosh Shilimkar { 74*7d35b8d0SSantosh Shilimkar /* 75*7d35b8d0SSantosh Shilimkar * we don't allow CPU 0 to be shutdown (it is still too special 76*7d35b8d0SSantosh Shilimkar * e.g. clock tick interrupts) 77*7d35b8d0SSantosh Shilimkar */ 78*7d35b8d0SSantosh Shilimkar return cpu == 0 ? -EPERM : 0; 79*7d35b8d0SSantosh Shilimkar } 80