11cea7326b3fff97d17d33fb8f33163409a84431bColin Cross/* 21cea7326b3fff97d17d33fb8f33163409a84431bColin Cross * Copyright (C) 2002 ARM Ltd. 31cea7326b3fff97d17d33fb8f33163409a84431bColin Cross * All Rights Reserved 47469688e832e340a84a1f6d4c290d8680c723256Hiroshi Doyu * Copyright (c) 2010, 2012-2013, NVIDIA Corporation. All rights reserved. 51cea7326b3fff97d17d33fb8f33163409a84431bColin Cross * 61cea7326b3fff97d17d33fb8f33163409a84431bColin Cross * This program is free software; you can redistribute it and/or modify 71cea7326b3fff97d17d33fb8f33163409a84431bColin Cross * it under the terms of the GNU General Public License version 2 as 81cea7326b3fff97d17d33fb8f33163409a84431bColin Cross * published by the Free Software Foundation. 91cea7326b3fff97d17d33fb8f33163409a84431bColin Cross */ 10a0524acc94c91c72c2968a76eddc6f3afe82f9f2Thierry Reding 11a0524acc94c91c72c2968a76eddc6f3afe82f9f2Thierry Reding#include <linux/clk/tegra.h> 121cea7326b3fff97d17d33fb8f33163409a84431bColin Cross#include <linux/kernel.h> 131cea7326b3fff97d17d33fb8f33163409a84431bColin Cross#include <linux/smp.h> 141cea7326b3fff97d17d33fb8f33163409a84431bColin Cross 1505ccf19602cc16fc96401b4f2617d1b8e20e642dThierry Reding#include <soc/tegra/common.h> 16304664eab93f9e95a8d28fbd9702ede88bb10cc5Thierry Reding#include <soc/tegra/fuse.h> 17304664eab93f9e95a8d28fbd9702ede88bb10cc5Thierry Reding 1859b0f6825c15d24859e22b1024440ae2a094983eJoseph Lo#include <asm/smp_plat.h> 191cea7326b3fff97d17d33fb8f33163409a84431bColin Cross 2059b0f6825c15d24859e22b1024440ae2a094983eJoseph Lo#include "sleep.h" 211cea7326b3fff97d17d33fb8f33163409a84431bColin Cross 2259b0f6825c15d24859e22b1024440ae2a094983eJoseph Lostatic void (*tegra_hotplug_shutdown)(void); 231cea7326b3fff97d17d33fb8f33163409a84431bColin Cross 24b811943160cf3b040341c50d23440cf6d68ae079Joseph Loint tegra_cpu_kill(unsigned cpu) 25b811943160cf3b040341c50d23440cf6d68ae079Joseph Lo{ 26b811943160cf3b040341c50d23440cf6d68ae079Joseph Lo cpu = cpu_logical_map(cpu); 27b811943160cf3b040341c50d23440cf6d68ae079Joseph Lo 28b811943160cf3b040341c50d23440cf6d68ae079Joseph Lo /* Clock gate the CPU */ 29b811943160cf3b040341c50d23440cf6d68ae079Joseph Lo tegra_wait_cpu_in_reset(cpu); 30b811943160cf3b040341c50d23440cf6d68ae079Joseph Lo tegra_disable_cpu_clock(cpu); 31b811943160cf3b040341c50d23440cf6d68ae079Joseph Lo 32b811943160cf3b040341c50d23440cf6d68ae079Joseph Lo return 1; 33b811943160cf3b040341c50d23440cf6d68ae079Joseph Lo} 34b811943160cf3b040341c50d23440cf6d68ae079Joseph Lo 351cea7326b3fff97d17d33fb8f33163409a84431bColin Cross/* 361cea7326b3fff97d17d33fb8f33163409a84431bColin Cross * platform-specific code to shutdown a CPU 371cea7326b3fff97d17d33fb8f33163409a84431bColin Cross * 381cea7326b3fff97d17d33fb8f33163409a84431bColin Cross * Called with IRQs disabled 391cea7326b3fff97d17d33fb8f33163409a84431bColin Cross */ 40a17257322f5e6ca376c15908b55423369274fcadMarc Zyngiervoid __ref tegra_cpu_die(unsigned int cpu) 411cea7326b3fff97d17d33fb8f33163409a84431bColin Cross{ 4205ccf19602cc16fc96401b4f2617d1b8e20e642dThierry Reding if (!tegra_hotplug_shutdown) { 4305ccf19602cc16fc96401b4f2617d1b8e20e642dThierry Reding WARN(1, "hotplug is not yet initialized\n"); 4405ccf19602cc16fc96401b4f2617d1b8e20e642dThierry Reding return; 4505ccf19602cc16fc96401b4f2617d1b8e20e642dThierry Reding } 4605ccf19602cc16fc96401b4f2617d1b8e20e642dThierry Reding 4757886616ca7bff844a6427436d0c8faf74653f73Joseph Lo /* Clean L1 data cache */ 48ac2527bfc21739b77d687df1bfc4e973103fef7bJoseph Lo tegra_disable_clean_inv_dcache(TEGRA_FLUSH_CACHE_LOUIS); 491cea7326b3fff97d17d33fb8f33163409a84431bColin Cross 5059b0f6825c15d24859e22b1024440ae2a094983eJoseph Lo /* Shut down the current CPU. */ 5159b0f6825c15d24859e22b1024440ae2a094983eJoseph Lo tegra_hotplug_shutdown(); 5259b0f6825c15d24859e22b1024440ae2a094983eJoseph Lo 5359b0f6825c15d24859e22b1024440ae2a094983eJoseph Lo /* Should never return here. */ 5459b0f6825c15d24859e22b1024440ae2a094983eJoseph Lo BUG(); 551cea7326b3fff97d17d33fb8f33163409a84431bColin Cross} 561cea7326b3fff97d17d33fb8f33163409a84431bColin Cross 5705ccf19602cc16fc96401b4f2617d1b8e20e642dThierry Redingstatic int __init tegra_hotplug_init(void) 58453689e407f2b7c0a72a2e6fb2ef84c20475773bJoseph Lo{ 597469688e832e340a84a1f6d4c290d8680c723256Hiroshi Doyu if (!IS_ENABLED(CONFIG_HOTPLUG_CPU)) 6005ccf19602cc16fc96401b4f2617d1b8e20e642dThierry Reding return 0; 6105ccf19602cc16fc96401b4f2617d1b8e20e642dThierry Reding 6205ccf19602cc16fc96401b4f2617d1b8e20e642dThierry Reding if (!soc_is_tegra()) 6305ccf19602cc16fc96401b4f2617d1b8e20e642dThierry Reding return 0; 64453689e407f2b7c0a72a2e6fb2ef84c20475773bJoseph Lo 65304664eab93f9e95a8d28fbd9702ede88bb10cc5Thierry Reding if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) && tegra_get_chip_id() == TEGRA20) 667469688e832e340a84a1f6d4c290d8680c723256Hiroshi Doyu tegra_hotplug_shutdown = tegra20_hotplug_shutdown; 67304664eab93f9e95a8d28fbd9702ede88bb10cc5Thierry Reding if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) && tegra_get_chip_id() == TEGRA30) 687469688e832e340a84a1f6d4c290d8680c723256Hiroshi Doyu tegra_hotplug_shutdown = tegra30_hotplug_shutdown; 69304664eab93f9e95a8d28fbd9702ede88bb10cc5Thierry Reding if (IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC) && tegra_get_chip_id() == TEGRA114) 7033d5c01915ccca298a5fda7e0cb33199d225e03aJoseph Lo tegra_hotplug_shutdown = tegra30_hotplug_shutdown; 71304664eab93f9e95a8d28fbd9702ede88bb10cc5Thierry Reding if (IS_ENABLED(CONFIG_ARCH_TEGRA_124_SOC) && tegra_get_chip_id() == TEGRA124) 729997e62682e0fe68566c88f70ed320ded4e16529Joseph Lo tegra_hotplug_shutdown = tegra30_hotplug_shutdown; 7305ccf19602cc16fc96401b4f2617d1b8e20e642dThierry Reding 7405ccf19602cc16fc96401b4f2617d1b8e20e642dThierry Reding return 0; 7559b0f6825c15d24859e22b1024440ae2a094983eJoseph Lo} 7605ccf19602cc16fc96401b4f2617d1b8e20e642dThierry Redingpure_initcall(tegra_hotplug_init); 77