1 /* 2 * Copyright (C) 2002 ARM Ltd. 3 * All Rights Reserved 4 * Copyright (c) 2010, 2012-2013, NVIDIA Corporation. All rights reserved. 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 2 as 8 * published by the Free Software Foundation. 9 */ 10 #include <linux/kernel.h> 11 #include <linux/smp.h> 12 #include <linux/clk/tegra.h> 13 14 #include <asm/cacheflush.h> 15 #include <asm/smp_plat.h> 16 17 #include "fuse.h" 18 #include "sleep.h" 19 20 static void (*tegra_hotplug_shutdown)(void); 21 22 int tegra_cpu_kill(unsigned cpu) 23 { 24 cpu = cpu_logical_map(cpu); 25 26 /* Clock gate the CPU */ 27 tegra_wait_cpu_in_reset(cpu); 28 tegra_disable_cpu_clock(cpu); 29 30 return 1; 31 } 32 33 /* 34 * platform-specific code to shutdown a CPU 35 * 36 * Called with IRQs disabled 37 */ 38 void __ref tegra_cpu_die(unsigned int cpu) 39 { 40 /* Clean L1 data cache */ 41 tegra_disable_clean_inv_dcache(); 42 43 /* Shut down the current CPU. */ 44 tegra_hotplug_shutdown(); 45 46 /* Should never return here. */ 47 BUG(); 48 } 49 50 int tegra_cpu_disable(unsigned int cpu) 51 { 52 /* 53 * we don't allow CPU 0 to be shutdown (it is still too special 54 * e.g. clock tick interrupts) 55 */ 56 return cpu == 0 ? -EPERM : 0; 57 } 58 59 void __init tegra_hotplug_init(void) 60 { 61 if (!IS_ENABLED(CONFIG_HOTPLUG_CPU)) 62 return; 63 64 if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) && tegra_chip_id == TEGRA20) 65 tegra_hotplug_shutdown = tegra20_hotplug_shutdown; 66 if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) && tegra_chip_id == TEGRA30) 67 tegra_hotplug_shutdown = tegra30_hotplug_shutdown; 68 } 69