xref: /linux/arch/arm/mach-tegra/hotplug.c (revision 75bf465f0bc33e9b776a46d6a1b9b990f5fb7c37)
1*d2912cb1SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
21cea7326SColin Cross /*
31cea7326SColin Cross  *  Copyright (C) 2002 ARM Ltd.
41cea7326SColin Cross  *  All Rights Reserved
57469688eSHiroshi Doyu  *  Copyright (c) 2010, 2012-2013, NVIDIA Corporation. All rights reserved.
61cea7326SColin Cross  */
7a0524accSThierry Reding 
8a0524accSThierry Reding #include <linux/clk/tegra.h>
91cea7326SColin Cross #include <linux/kernel.h>
101cea7326SColin Cross #include <linux/smp.h>
111cea7326SColin Cross 
1205ccf196SThierry Reding #include <soc/tegra/common.h>
13304664eaSThierry Reding #include <soc/tegra/fuse.h>
14304664eaSThierry Reding 
1559b0f682SJoseph Lo #include <asm/smp_plat.h>
161cea7326SColin Cross 
175c753e04SThierry Reding #include "common.h"
1859b0f682SJoseph Lo #include "sleep.h"
191cea7326SColin Cross 
2059b0f682SJoseph Lo static void (*tegra_hotplug_shutdown)(void);
211cea7326SColin Cross 
tegra_cpu_kill(unsigned cpu)22b8119431SJoseph Lo int tegra_cpu_kill(unsigned cpu)
23b8119431SJoseph Lo {
24b8119431SJoseph Lo 	cpu = cpu_logical_map(cpu);
25b8119431SJoseph Lo 
26b8119431SJoseph Lo 	/* Clock gate the CPU */
27b8119431SJoseph Lo 	tegra_wait_cpu_in_reset(cpu);
28b8119431SJoseph Lo 	tegra_disable_cpu_clock(cpu);
29b8119431SJoseph Lo 
30b8119431SJoseph Lo 	return 1;
31b8119431SJoseph Lo }
32b8119431SJoseph Lo 
331cea7326SColin Cross /*
341cea7326SColin Cross  * platform-specific code to shutdown a CPU
351cea7326SColin Cross  *
361cea7326SColin Cross  * Called with IRQs disabled
371cea7326SColin Cross  */
tegra_cpu_die(unsigned int cpu)38b96fc2f3SStephen Boyd void tegra_cpu_die(unsigned int cpu)
391cea7326SColin Cross {
4005ccf196SThierry Reding 	if (!tegra_hotplug_shutdown) {
4105ccf196SThierry Reding 		WARN(1, "hotplug is not yet initialized\n");
4205ccf196SThierry Reding 		return;
4305ccf196SThierry Reding 	}
4405ccf196SThierry Reding 
4557886616SJoseph Lo 	/* Clean L1 data cache */
46ac2527bfSJoseph Lo 	tegra_disable_clean_inv_dcache(TEGRA_FLUSH_CACHE_LOUIS);
471cea7326SColin Cross 
4859b0f682SJoseph Lo 	/* Shut down the current CPU. */
4959b0f682SJoseph Lo 	tegra_hotplug_shutdown();
50d4450261SRussell King 
5159b0f682SJoseph Lo 	/* Should never return here. */
5259b0f682SJoseph Lo 	BUG();
531cea7326SColin Cross }
541cea7326SColin Cross 
tegra_hotplug_init(void)5505ccf196SThierry Reding static int __init tegra_hotplug_init(void)
56453689e4SJoseph Lo {
577469688eSHiroshi Doyu 	if (!IS_ENABLED(CONFIG_HOTPLUG_CPU))
5805ccf196SThierry Reding 		return 0;
5905ccf196SThierry Reding 
6005ccf196SThierry Reding 	if (!soc_is_tegra())
6105ccf196SThierry Reding 		return 0;
62453689e4SJoseph Lo 
63304664eaSThierry Reding 	if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) && tegra_get_chip_id() == TEGRA20)
647469688eSHiroshi Doyu 		tegra_hotplug_shutdown = tegra20_hotplug_shutdown;
65304664eaSThierry Reding 	if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) && tegra_get_chip_id() == TEGRA30)
6659b0f682SJoseph Lo 		tegra_hotplug_shutdown = tegra30_hotplug_shutdown;
67304664eaSThierry Reding 	if (IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC) && tegra_get_chip_id() == TEGRA114)
6833d5c019SJoseph Lo 		tegra_hotplug_shutdown = tegra30_hotplug_shutdown;
69304664eaSThierry Reding 	if (IS_ENABLED(CONFIG_ARCH_TEGRA_124_SOC) && tegra_get_chip_id() == TEGRA124)
709997e626SJoseph Lo 		tegra_hotplug_shutdown = tegra30_hotplug_shutdown;
7105ccf196SThierry Reding 
7205ccf196SThierry Reding 	return 0;
7359b0f682SJoseph Lo }
7405ccf196SThierry Reding pure_initcall(tegra_hotplug_init);
75