[ARM/tegra] Add Tegra3 support
[linux-2.6.git] / arch / arm / mach-tegra / hotplug.c
1 /*
2  *  linux/arch/arm/mach-tegra/hotplug.c
3  *
4  *  Copyright (C) 2010 NVIDIA Corporation
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/io.h>
12 #include <linux/smp.h>
13
14 #include <asm/cpu_pm.h>
15
16 #include <mach/iomap.h>
17
18 #include "sleep.h"
19
20 #define CPU_CLOCK(cpu) (0x1<<(8+cpu))
21
22 #define CLK_RST_CONTROLLER_CLK_CPU_CMPLX \
23         (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x4c)
24 #define CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET \
25         (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x340)
26 #define CLK_RST_CONTROLLER_RST_CPU_CMPLX_CLR \
27         (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x344)
28
29 #ifdef CONFIG_ARCH_TEGRA_2x_SOC
30 /* For Tegra2 use the software-written value of the reset register for status.*/
31 #define CLK_RST_CONTROLLER_CPU_CMPLX_STATUS CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET
32 #else
33 #define CLK_RST_CONTROLLER_CPU_CMPLX_STATUS \
34         (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x470)
35 #endif
36
37 int platform_cpu_kill(unsigned int cpu)
38 {
39         unsigned int reg;
40
41         do {
42                 reg = readl(CLK_RST_CONTROLLER_CPU_CMPLX_STATUS);
43                 cpu_relax();
44         } while (!(reg & (1<<cpu)));
45
46         reg = readl(CLK_RST_CONTROLLER_CLK_CPU_CMPLX);
47         writel(reg | CPU_CLOCK(cpu), CLK_RST_CONTROLLER_CLK_CPU_CMPLX);
48
49         return 1;
50 }
51
52 void platform_cpu_die(unsigned int cpu)
53 {
54 #ifdef DEBUG
55         unsigned int this_cpu = hard_smp_processor_id();
56
57         if (cpu != this_cpu) {
58                 printk(KERN_CRIT "Eek! platform_cpu_die running on %u, should be %u\n",
59                            this_cpu, cpu);
60                 BUG();
61         }
62 #endif
63
64         tegra_sleep_reset();
65
66         /*
67          * tegra_cpu_suspend can return through tegra_cpu_resume, but that
68          * should never happen for a hotplugged cpu
69          */
70         BUG();
71 }
72
73 int platform_cpu_disable(unsigned int cpu)
74 {
75         /*
76          * we don't allow CPU 0 to be shutdown (it is still too special
77          * e.g. clock tick interrupts)
78          */
79         return cpu == 0 ? -EPERM : 0;
80 }