blob: f88595abc471771f1c0bd38c6af014477d3625fd [file] [log] [blame]
Joseph Lod457ef352012-10-31 17:41:17 +08001/*
2 * CPU complex suspend & resume functions for Tegra SoCs
3 *
4 * Copyright (c) 2009-2012, NVIDIA Corporation. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include <linux/kernel.h>
20#include <linux/spinlock.h>
21#include <linux/io.h>
22#include <linux/cpumask.h>
23
24#include "iomap.h"
25#include "reset.h"
26
27#ifdef CONFIG_PM_SLEEP
28static unsigned int g_diag_reg;
29static DEFINE_SPINLOCK(tegra_lp2_lock);
30
31void save_cpu_arch_register(void)
32{
33 /* read diagnostic register */
34 asm("mrc p15, 0, %0, c15, c0, 1" : "=r"(g_diag_reg) : : "cc");
35 return;
36}
37
38void restore_cpu_arch_register(void)
39{
40 /* write diagnostic register */
41 asm("mcr p15, 0, %0, c15, c0, 1" : : "r"(g_diag_reg) : "cc");
42 return;
43}
44
45void __cpuinit tegra_clear_cpu_in_lp2(int phy_cpu_id)
46{
47 u32 *cpu_in_lp2 = tegra_cpu_lp2_mask;
48
49 spin_lock(&tegra_lp2_lock);
50
51 BUG_ON(!(*cpu_in_lp2 & BIT(phy_cpu_id)));
52 *cpu_in_lp2 &= ~BIT(phy_cpu_id);
53
54 spin_unlock(&tegra_lp2_lock);
55}
56
57bool __cpuinit tegra_set_cpu_in_lp2(int phy_cpu_id)
58{
59 bool last_cpu = false;
60 cpumask_t *cpu_lp2_mask = tegra_cpu_lp2_mask;
61 u32 *cpu_in_lp2 = tegra_cpu_lp2_mask;
62
63 spin_lock(&tegra_lp2_lock);
64
65 BUG_ON((*cpu_in_lp2 & BIT(phy_cpu_id)));
66 *cpu_in_lp2 |= BIT(phy_cpu_id);
67
68 if ((phy_cpu_id == 0) && cpumask_equal(cpu_lp2_mask, cpu_online_mask))
69 last_cpu = true;
70
71 spin_unlock(&tegra_lp2_lock);
72 return last_cpu;
73}
74#endif