diff options
author | Olof Johansson <olof@lixom.net> | 2013-02-05 15:10:18 -0500 |
---|---|---|
committer | Olof Johansson <olof@lixom.net> | 2013-02-05 15:10:18 -0500 |
commit | f0390669d13b0a1592fc7906445b4f6c8ec5af23 (patch) | |
tree | 4a27ffbd016d24f54ba1e3a38d46a386ab924bc6 | |
parent | b60decad7791694a36ad218cede77a407c1475ce (diff) | |
parent | 24e30c9417230b359bf6dfeb923e90138df7c112 (diff) |
Merge tag 'tegra-for-3.9-cleanup' of git://git.kernel.org/pub/scm/linux/kernel/git/swarren/linux-tegra into next/cleanup
From Stephen Warren:
ARM: tegra: cleanup
This pull request contains various cleanup and minor changes to core
Tegra code:
* Tegra clocksource driver is moved to drivers/clocksource.
* Various typos, warning cleanup, statics cleanup, section mismatch
fixes, etc.
* Various small fixes/cleanups for CPU/hotplug/SMP code.
This pull request is based on a merge of v3.8-rc3 and at least part of
arm-soc's timer/cleanup branch.
* tag 'tegra-for-3.9-cleanup' of git://git.kernel.org/pub/scm/linux/kernel/git/swarren/linux-tegra:
ARM: tegra: fix compile error when disable CPU_IDLE
ARM: tegra30: make the wait time of CPU power up to proportional to HZ
ARM: tegra: make device can run on UP
ARM: tegra: clean up the CPUINIT section
ARM: tegra: moving the clock gating procedure to tegra_cpu_kill
ARM: tegra: update the cache maintenance order for CPU shutdown
ARM: tegra30: fix power up sequence for boot_secondary
ARM: tegra: cpufreq: move clk_get/put out of function tegra_cpu_init/exit
ARM: tegra: fix Kconfig warnings when !SMP
ARM: tegra: Make variables static
clocksource: tegra: cosmetic: Fix error message
ARM: tegra: move timer.c to drivers/clocksource/
Signed-off-by: Olof Johansson <olof@lixom.net>
Trivial conflicts:
arch/arm/mach-tegra/board-dt-tegra20.c
arch/arm/mach-tegra/board-dt-tegra30.c
drivers/clocksource/Makefile
25 files changed, 352 insertions, 291 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index af74b0fc4faa..c2950f3e678e 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -642,6 +642,7 @@ config ARCH_TEGRA | |||
642 | select ARCH_HAS_CPUFREQ | 642 | select ARCH_HAS_CPUFREQ |
643 | select CLKDEV_LOOKUP | 643 | select CLKDEV_LOOKUP |
644 | select CLKSRC_MMIO | 644 | select CLKSRC_MMIO |
645 | select CLKSRC_OF | ||
645 | select COMMON_CLK | 646 | select COMMON_CLK |
646 | select GENERIC_CLOCKEVENTS | 647 | select GENERIC_CLOCKEVENTS |
647 | select HAVE_CLK | 648 | select HAVE_CLK |
diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig index b442f15fd01a..1ec7f80e2af5 100644 --- a/arch/arm/mach-tegra/Kconfig +++ b/arch/arm/mach-tegra/Kconfig | |||
@@ -6,9 +6,9 @@ config ARCH_TEGRA_2x_SOC | |||
6 | bool "Enable support for Tegra20 family" | 6 | bool "Enable support for Tegra20 family" |
7 | select ARCH_REQUIRE_GPIOLIB | 7 | select ARCH_REQUIRE_GPIOLIB |
8 | select ARM_ERRATA_720789 | 8 | select ARM_ERRATA_720789 |
9 | select ARM_ERRATA_742230 | 9 | select ARM_ERRATA_742230 if SMP |
10 | select ARM_ERRATA_751472 | 10 | select ARM_ERRATA_751472 |
11 | select ARM_ERRATA_754327 | 11 | select ARM_ERRATA_754327 if SMP |
12 | select ARM_ERRATA_764369 if SMP | 12 | select ARM_ERRATA_764369 if SMP |
13 | select ARM_GIC | 13 | select ARM_GIC |
14 | select CPU_FREQ_TABLE if CPU_FREQ | 14 | select CPU_FREQ_TABLE if CPU_FREQ |
diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile index 0979e8bba78a..f0520961bafe 100644 --- a/arch/arm/mach-tegra/Makefile +++ b/arch/arm/mach-tegra/Makefile | |||
@@ -2,15 +2,16 @@ obj-y += common.o | |||
2 | obj-y += io.o | 2 | obj-y += io.o |
3 | obj-y += irq.o | 3 | obj-y += irq.o |
4 | obj-y += clock.o | 4 | obj-y += clock.o |
5 | obj-y += timer.o | ||
6 | obj-y += fuse.o | 5 | obj-y += fuse.o |
7 | obj-y += pmc.o | 6 | obj-y += pmc.o |
8 | obj-y += flowctrl.o | 7 | obj-y += flowctrl.o |
9 | obj-y += powergate.o | 8 | obj-y += powergate.o |
10 | obj-y += apbio.o | 9 | obj-y += apbio.o |
11 | obj-y += pm.o | 10 | obj-y += pm.o |
11 | obj-y += reset.o | ||
12 | obj-y += reset-handler.o | ||
13 | obj-y += sleep.o | ||
12 | obj-$(CONFIG_CPU_IDLE) += cpuidle.o | 14 | obj-$(CONFIG_CPU_IDLE) += cpuidle.o |
13 | obj-$(CONFIG_CPU_IDLE) += sleep.o | ||
14 | obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20_clocks.o | 15 | obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20_clocks.o |
15 | obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20_clocks_data.o | 16 | obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20_clocks_data.o |
16 | obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20_speedo.o | 17 | obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20_speedo.o |
@@ -27,7 +28,6 @@ ifeq ($(CONFIG_CPU_IDLE),y) | |||
27 | obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += cpuidle-tegra30.o | 28 | obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += cpuidle-tegra30.o |
28 | endif | 29 | endif |
29 | obj-$(CONFIG_SMP) += platsmp.o headsmp.o | 30 | obj-$(CONFIG_SMP) += platsmp.o headsmp.o |
30 | obj-$(CONFIG_SMP) += reset.o | ||
31 | obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o | 31 | obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o |
32 | obj-$(CONFIG_CPU_FREQ) += cpu-tegra.o | 32 | obj-$(CONFIG_CPU_FREQ) += cpu-tegra.o |
33 | obj-$(CONFIG_TEGRA_PCI) += pcie.o | 33 | obj-$(CONFIG_TEGRA_PCI) += pcie.o |
diff --git a/arch/arm/mach-tegra/apbio.c b/arch/arm/mach-tegra/apbio.c index d091675ba376..d7aa52ea6cfc 100644 --- a/arch/arm/mach-tegra/apbio.c +++ b/arch/arm/mach-tegra/apbio.c | |||
@@ -38,7 +38,7 @@ static void tegra_apb_writel_direct(u32 value, unsigned long offset); | |||
38 | static struct dma_chan *tegra_apb_dma_chan; | 38 | static struct dma_chan *tegra_apb_dma_chan; |
39 | static struct dma_slave_config dma_sconfig; | 39 | static struct dma_slave_config dma_sconfig; |
40 | 40 | ||
41 | bool tegra_apb_dma_init(void) | 41 | static bool tegra_apb_dma_init(void) |
42 | { | 42 | { |
43 | dma_cap_mask_t mask; | 43 | dma_cap_mask_t mask; |
44 | 44 | ||
diff --git a/arch/arm/mach-tegra/board-dt-tegra20.c b/arch/arm/mach-tegra/board-dt-tegra20.c index 5ed81bab2d4b..d320f7ad7350 100644 --- a/arch/arm/mach-tegra/board-dt-tegra20.c +++ b/arch/arm/mach-tegra/board-dt-tegra20.c | |||
@@ -15,6 +15,7 @@ | |||
15 | * | 15 | * |
16 | */ | 16 | */ |
17 | 17 | ||
18 | #include <linux/clocksource.h> | ||
18 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
19 | #include <linux/init.h> | 20 | #include <linux/init.h> |
20 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
@@ -43,31 +44,31 @@ | |||
43 | #include "common.h" | 44 | #include "common.h" |
44 | #include "iomap.h" | 45 | #include "iomap.h" |
45 | 46 | ||
46 | struct tegra_ehci_platform_data tegra_ehci1_pdata = { | 47 | static struct tegra_ehci_platform_data tegra_ehci1_pdata = { |
47 | .operating_mode = TEGRA_USB_OTG, | 48 | .operating_mode = TEGRA_USB_OTG, |
48 | .power_down_on_bus_suspend = 1, | 49 | .power_down_on_bus_suspend = 1, |
49 | .vbus_gpio = -1, | 50 | .vbus_gpio = -1, |
50 | }; | 51 | }; |
51 | 52 | ||
52 | struct tegra_ulpi_config tegra_ehci2_ulpi_phy_config = { | 53 | static struct tegra_ulpi_config tegra_ehci2_ulpi_phy_config = { |
53 | .reset_gpio = -1, | 54 | .reset_gpio = -1, |
54 | .clk = "cdev2", | 55 | .clk = "cdev2", |
55 | }; | 56 | }; |
56 | 57 | ||
57 | struct tegra_ehci_platform_data tegra_ehci2_pdata = { | 58 | static struct tegra_ehci_platform_data tegra_ehci2_pdata = { |
58 | .phy_config = &tegra_ehci2_ulpi_phy_config, | 59 | .phy_config = &tegra_ehci2_ulpi_phy_config, |
59 | .operating_mode = TEGRA_USB_HOST, | 60 | .operating_mode = TEGRA_USB_HOST, |
60 | .power_down_on_bus_suspend = 1, | 61 | .power_down_on_bus_suspend = 1, |
61 | .vbus_gpio = -1, | 62 | .vbus_gpio = -1, |
62 | }; | 63 | }; |
63 | 64 | ||
64 | struct tegra_ehci_platform_data tegra_ehci3_pdata = { | 65 | static struct tegra_ehci_platform_data tegra_ehci3_pdata = { |
65 | .operating_mode = TEGRA_USB_HOST, | 66 | .operating_mode = TEGRA_USB_HOST, |
66 | .power_down_on_bus_suspend = 1, | 67 | .power_down_on_bus_suspend = 1, |
67 | .vbus_gpio = -1, | 68 | .vbus_gpio = -1, |
68 | }; | 69 | }; |
69 | 70 | ||
70 | struct of_dev_auxdata tegra20_auxdata_lookup[] __initdata = { | 71 | static struct of_dev_auxdata tegra20_auxdata_lookup[] __initdata = { |
71 | OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC1_BASE, "sdhci-tegra.0", NULL), | 72 | OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC1_BASE, "sdhci-tegra.0", NULL), |
72 | OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC2_BASE, "sdhci-tegra.1", NULL), | 73 | OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC2_BASE, "sdhci-tegra.1", NULL), |
73 | OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC3_BASE, "sdhci-tegra.2", NULL), | 74 | OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC3_BASE, "sdhci-tegra.2", NULL), |
@@ -200,7 +201,7 @@ DT_MACHINE_START(TEGRA_DT, "nVidia Tegra20 (Flattened Device Tree)") | |||
200 | .smp = smp_ops(tegra_smp_ops), | 201 | .smp = smp_ops(tegra_smp_ops), |
201 | .init_early = tegra20_init_early, | 202 | .init_early = tegra20_init_early, |
202 | .init_irq = tegra_dt_init_irq, | 203 | .init_irq = tegra_dt_init_irq, |
203 | .init_time = tegra_init_timer, | 204 | .init_time = clocksource_of_init, |
204 | .init_machine = tegra_dt_init, | 205 | .init_machine = tegra_dt_init, |
205 | .init_late = tegra_dt_init_late, | 206 | .init_late = tegra_dt_init_late, |
206 | .restart = tegra_assert_system_reset, | 207 | .restart = tegra_assert_system_reset, |
diff --git a/arch/arm/mach-tegra/board-dt-tegra30.c b/arch/arm/mach-tegra/board-dt-tegra30.c index 12dc2ddeca64..97e1f67fc31d 100644 --- a/arch/arm/mach-tegra/board-dt-tegra30.c +++ b/arch/arm/mach-tegra/board-dt-tegra30.c | |||
@@ -23,6 +23,7 @@ | |||
23 | * | 23 | * |
24 | */ | 24 | */ |
25 | 25 | ||
26 | #include <linux/clocksource.h> | ||
26 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
27 | #include <linux/of.h> | 28 | #include <linux/of.h> |
28 | #include <linux/of_address.h> | 29 | #include <linux/of_address.h> |
@@ -37,7 +38,7 @@ | |||
37 | #include "common.h" | 38 | #include "common.h" |
38 | #include "iomap.h" | 39 | #include "iomap.h" |
39 | 40 | ||
40 | struct of_dev_auxdata tegra30_auxdata_lookup[] __initdata = { | 41 | static struct of_dev_auxdata tegra30_auxdata_lookup[] __initdata = { |
41 | OF_DEV_AUXDATA("nvidia,tegra20-sdhci", 0x78000000, "sdhci-tegra.0", NULL), | 42 | OF_DEV_AUXDATA("nvidia,tegra20-sdhci", 0x78000000, "sdhci-tegra.0", NULL), |
42 | OF_DEV_AUXDATA("nvidia,tegra20-sdhci", 0x78000200, "sdhci-tegra.1", NULL), | 43 | OF_DEV_AUXDATA("nvidia,tegra20-sdhci", 0x78000200, "sdhci-tegra.1", NULL), |
43 | OF_DEV_AUXDATA("nvidia,tegra20-sdhci", 0x78000400, "sdhci-tegra.2", NULL), | 44 | OF_DEV_AUXDATA("nvidia,tegra20-sdhci", 0x78000400, "sdhci-tegra.2", NULL), |
@@ -111,7 +112,7 @@ DT_MACHINE_START(TEGRA30_DT, "NVIDIA Tegra30 (Flattened Device Tree)") | |||
111 | .map_io = tegra_map_common_io, | 112 | .map_io = tegra_map_common_io, |
112 | .init_early = tegra30_init_early, | 113 | .init_early = tegra30_init_early, |
113 | .init_irq = tegra_dt_init_irq, | 114 | .init_irq = tegra_dt_init_irq, |
114 | .init_time = tegra_init_timer, | 115 | .init_time = clocksource_of_init, |
115 | .init_machine = tegra30_dt_init, | 116 | .init_machine = tegra30_dt_init, |
116 | .init_late = tegra_init_late, | 117 | .init_late = tegra_init_late, |
117 | .restart = tegra_assert_system_reset, | 118 | .restart = tegra_assert_system_reset, |
diff --git a/arch/arm/mach-tegra/board.h b/arch/arm/mach-tegra/board.h index 744cdd246f6a..da8f5a3c4240 100644 --- a/arch/arm/mach-tegra/board.h +++ b/arch/arm/mach-tegra/board.h | |||
@@ -55,5 +55,4 @@ static inline int harmony_pcie_init(void) { return 0; } | |||
55 | 55 | ||
56 | void __init tegra_paz00_wifikill_init(void); | 56 | void __init tegra_paz00_wifikill_init(void); |
57 | 57 | ||
58 | extern void tegra_init_timer(void); | ||
59 | #endif | 58 | #endif |
diff --git a/arch/arm/mach-tegra/common.c b/arch/arm/mach-tegra/common.c index 3599959517b3..8f0ffe97ffee 100644 --- a/arch/arm/mach-tegra/common.c +++ b/arch/arm/mach-tegra/common.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include "apbio.h" | 36 | #include "apbio.h" |
37 | #include "sleep.h" | 37 | #include "sleep.h" |
38 | #include "pm.h" | 38 | #include "pm.h" |
39 | #include "reset.h" | ||
39 | 40 | ||
40 | /* | 41 | /* |
41 | * Storage for debug-macro.S's state. | 42 | * Storage for debug-macro.S's state. |
@@ -131,6 +132,7 @@ static void __init tegra_init_cache(void) | |||
131 | #ifdef CONFIG_ARCH_TEGRA_2x_SOC | 132 | #ifdef CONFIG_ARCH_TEGRA_2x_SOC |
132 | void __init tegra20_init_early(void) | 133 | void __init tegra20_init_early(void) |
133 | { | 134 | { |
135 | tegra_cpu_reset_handler_init(); | ||
134 | tegra_apb_io_init(); | 136 | tegra_apb_io_init(); |
135 | tegra_init_fuse(); | 137 | tegra_init_fuse(); |
136 | tegra2_init_clocks(); | 138 | tegra2_init_clocks(); |
@@ -144,6 +146,7 @@ void __init tegra20_init_early(void) | |||
144 | #ifdef CONFIG_ARCH_TEGRA_3x_SOC | 146 | #ifdef CONFIG_ARCH_TEGRA_3x_SOC |
145 | void __init tegra30_init_early(void) | 147 | void __init tegra30_init_early(void) |
146 | { | 148 | { |
149 | tegra_cpu_reset_handler_init(); | ||
147 | tegra_apb_io_init(); | 150 | tegra_apb_io_init(); |
148 | tegra_init_fuse(); | 151 | tegra_init_fuse(); |
149 | tegra30_init_clocks(); | 152 | tegra30_init_clocks(); |
diff --git a/arch/arm/mach-tegra/common.h b/arch/arm/mach-tegra/common.h index 02f71b4f1e51..32f8eb3fe344 100644 --- a/arch/arm/mach-tegra/common.h +++ b/arch/arm/mach-tegra/common.h | |||
@@ -1,4 +1,5 @@ | |||
1 | extern struct smp_operations tegra_smp_ops; | 1 | extern struct smp_operations tegra_smp_ops; |
2 | 2 | ||
3 | extern int tegra_cpu_kill(unsigned int cpu); | ||
3 | extern void tegra_cpu_die(unsigned int cpu); | 4 | extern void tegra_cpu_die(unsigned int cpu); |
4 | extern int tegra_cpu_disable(unsigned int cpu); | 5 | extern int tegra_cpu_disable(unsigned int cpu); |
diff --git a/arch/arm/mach-tegra/cpu-tegra.c b/arch/arm/mach-tegra/cpu-tegra.c index a74d3c7d2e26..85d4a23bba03 100644 --- a/arch/arm/mach-tegra/cpu-tegra.c +++ b/arch/arm/mach-tegra/cpu-tegra.c | |||
@@ -214,24 +214,6 @@ static int tegra_cpu_init(struct cpufreq_policy *policy) | |||
214 | if (policy->cpu >= NUM_CPUS) | 214 | if (policy->cpu >= NUM_CPUS) |
215 | return -EINVAL; | 215 | return -EINVAL; |
216 | 216 | ||
217 | cpu_clk = clk_get_sys(NULL, "cpu"); | ||
218 | if (IS_ERR(cpu_clk)) | ||
219 | return PTR_ERR(cpu_clk); | ||
220 | |||
221 | pll_x_clk = clk_get_sys(NULL, "pll_x"); | ||
222 | if (IS_ERR(pll_x_clk)) | ||
223 | return PTR_ERR(pll_x_clk); | ||
224 | |||
225 | pll_p_clk = clk_get_sys(NULL, "pll_p"); | ||
226 | if (IS_ERR(pll_p_clk)) | ||
227 | return PTR_ERR(pll_p_clk); | ||
228 | |||
229 | emc_clk = clk_get_sys("cpu", "emc"); | ||
230 | if (IS_ERR(emc_clk)) { | ||
231 | clk_put(cpu_clk); | ||
232 | return PTR_ERR(emc_clk); | ||
233 | } | ||
234 | |||
235 | clk_prepare_enable(emc_clk); | 217 | clk_prepare_enable(emc_clk); |
236 | clk_prepare_enable(cpu_clk); | 218 | clk_prepare_enable(cpu_clk); |
237 | 219 | ||
@@ -256,8 +238,6 @@ static int tegra_cpu_exit(struct cpufreq_policy *policy) | |||
256 | { | 238 | { |
257 | cpufreq_frequency_table_cpuinfo(policy, freq_table); | 239 | cpufreq_frequency_table_cpuinfo(policy, freq_table); |
258 | clk_disable_unprepare(emc_clk); | 240 | clk_disable_unprepare(emc_clk); |
259 | clk_put(emc_clk); | ||
260 | clk_put(cpu_clk); | ||
261 | return 0; | 241 | return 0; |
262 | } | 242 | } |
263 | 243 | ||
@@ -278,12 +258,32 @@ static struct cpufreq_driver tegra_cpufreq_driver = { | |||
278 | 258 | ||
279 | static int __init tegra_cpufreq_init(void) | 259 | static int __init tegra_cpufreq_init(void) |
280 | { | 260 | { |
261 | cpu_clk = clk_get_sys(NULL, "cpu"); | ||
262 | if (IS_ERR(cpu_clk)) | ||
263 | return PTR_ERR(cpu_clk); | ||
264 | |||
265 | pll_x_clk = clk_get_sys(NULL, "pll_x"); | ||
266 | if (IS_ERR(pll_x_clk)) | ||
267 | return PTR_ERR(pll_x_clk); | ||
268 | |||
269 | pll_p_clk = clk_get_sys(NULL, "pll_p"); | ||
270 | if (IS_ERR(pll_p_clk)) | ||
271 | return PTR_ERR(pll_p_clk); | ||
272 | |||
273 | emc_clk = clk_get_sys("cpu", "emc"); | ||
274 | if (IS_ERR(emc_clk)) { | ||
275 | clk_put(cpu_clk); | ||
276 | return PTR_ERR(emc_clk); | ||
277 | } | ||
278 | |||
281 | return cpufreq_register_driver(&tegra_cpufreq_driver); | 279 | return cpufreq_register_driver(&tegra_cpufreq_driver); |
282 | } | 280 | } |
283 | 281 | ||
284 | static void __exit tegra_cpufreq_exit(void) | 282 | static void __exit tegra_cpufreq_exit(void) |
285 | { | 283 | { |
286 | cpufreq_unregister_driver(&tegra_cpufreq_driver); | 284 | cpufreq_unregister_driver(&tegra_cpufreq_driver); |
285 | clk_put(emc_clk); | ||
286 | clk_put(cpu_clk); | ||
287 | } | 287 | } |
288 | 288 | ||
289 | 289 | ||
diff --git a/arch/arm/mach-tegra/cpuidle-tegra30.c b/arch/arm/mach-tegra/cpuidle-tegra30.c index 5e8cbf5b799f..82530bd9b8c2 100644 --- a/arch/arm/mach-tegra/cpuidle-tegra30.c +++ b/arch/arm/mach-tegra/cpuidle-tegra30.c | |||
@@ -121,9 +121,9 @@ static inline bool tegra30_cpu_core_power_down(struct cpuidle_device *dev, | |||
121 | } | 121 | } |
122 | #endif | 122 | #endif |
123 | 123 | ||
124 | static int __cpuinit tegra30_idle_lp2(struct cpuidle_device *dev, | 124 | static int tegra30_idle_lp2(struct cpuidle_device *dev, |
125 | struct cpuidle_driver *drv, | 125 | struct cpuidle_driver *drv, |
126 | int index) | 126 | int index) |
127 | { | 127 | { |
128 | u32 cpu = is_smp() ? cpu_logical_map(dev->cpu) : dev->cpu; | 128 | u32 cpu = is_smp() ? cpu_logical_map(dev->cpu) : dev->cpu; |
129 | bool entered_lp2 = false; | 129 | bool entered_lp2 = false; |
diff --git a/arch/arm/mach-tegra/flowctrl.c b/arch/arm/mach-tegra/flowctrl.c index a2250ddae797..5393eb2cae21 100644 --- a/arch/arm/mach-tegra/flowctrl.c +++ b/arch/arm/mach-tegra/flowctrl.c | |||
@@ -26,14 +26,14 @@ | |||
26 | #include "flowctrl.h" | 26 | #include "flowctrl.h" |
27 | #include "iomap.h" | 27 | #include "iomap.h" |
28 | 28 | ||
29 | u8 flowctrl_offset_halt_cpu[] = { | 29 | static u8 flowctrl_offset_halt_cpu[] = { |
30 | FLOW_CTRL_HALT_CPU0_EVENTS, | 30 | FLOW_CTRL_HALT_CPU0_EVENTS, |
31 | FLOW_CTRL_HALT_CPU1_EVENTS, | 31 | FLOW_CTRL_HALT_CPU1_EVENTS, |
32 | FLOW_CTRL_HALT_CPU1_EVENTS + 8, | 32 | FLOW_CTRL_HALT_CPU1_EVENTS + 8, |
33 | FLOW_CTRL_HALT_CPU1_EVENTS + 16, | 33 | FLOW_CTRL_HALT_CPU1_EVENTS + 16, |
34 | }; | 34 | }; |
35 | 35 | ||
36 | u8 flowctrl_offset_cpu_csr[] = { | 36 | static u8 flowctrl_offset_cpu_csr[] = { |
37 | FLOW_CTRL_CPU0_CSR, | 37 | FLOW_CTRL_CPU0_CSR, |
38 | FLOW_CTRL_CPU1_CSR, | 38 | FLOW_CTRL_CPU1_CSR, |
39 | FLOW_CTRL_CPU1_CSR + 8, | 39 | FLOW_CTRL_CPU1_CSR + 8, |
diff --git a/arch/arm/mach-tegra/headsmp.S b/arch/arm/mach-tegra/headsmp.S index 4a317fae6860..b2834810b02b 100644 --- a/arch/arm/mach-tegra/headsmp.S +++ b/arch/arm/mach-tegra/headsmp.S | |||
@@ -1,22 +1,9 @@ | |||
1 | #include <linux/linkage.h> | 1 | #include <linux/linkage.h> |
2 | #include <linux/init.h> | 2 | #include <linux/init.h> |
3 | 3 | ||
4 | #include <asm/cache.h> | ||
5 | #include <asm/asm-offsets.h> | ||
6 | #include <asm/hardware/cache-l2x0.h> | ||
7 | |||
8 | #include "flowctrl.h" | ||
9 | #include "iomap.h" | ||
10 | #include "reset.h" | ||
11 | #include "sleep.h" | 4 | #include "sleep.h" |
12 | 5 | ||
13 | #define APB_MISC_GP_HIDREV 0x804 | ||
14 | #define PMC_SCRATCH41 0x140 | ||
15 | |||
16 | #define RESET_DATA(x) ((TEGRA_RESET_##x)*4) | ||
17 | |||
18 | .section ".text.head", "ax" | 6 | .section ".text.head", "ax" |
19 | __CPUINIT | ||
20 | 7 | ||
21 | /* | 8 | /* |
22 | * Tegra specific entry point for secondary CPUs. | 9 | * Tegra specific entry point for secondary CPUs. |
@@ -61,7 +48,6 @@ ENTRY(v7_invalidate_l1) | |||
61 | mov pc, lr | 48 | mov pc, lr |
62 | ENDPROC(v7_invalidate_l1) | 49 | ENDPROC(v7_invalidate_l1) |
63 | 50 | ||
64 | |||
65 | ENTRY(tegra_secondary_startup) | 51 | ENTRY(tegra_secondary_startup) |
66 | bl v7_invalidate_l1 | 52 | bl v7_invalidate_l1 |
67 | /* Enable coresight */ | 53 | /* Enable coresight */ |
@@ -69,210 +55,3 @@ ENTRY(tegra_secondary_startup) | |||
69 | mcr p14, 0, r0, c7, c12, 6 | 55 | mcr p14, 0, r0, c7, c12, 6 |
70 | b secondary_startup | 56 | b secondary_startup |
71 | ENDPROC(tegra_secondary_startup) | 57 | ENDPROC(tegra_secondary_startup) |
72 | |||
73 | #ifdef CONFIG_PM_SLEEP | ||
74 | /* | ||
75 | * tegra_resume | ||
76 | * | ||
77 | * CPU boot vector when restarting the a CPU following | ||
78 | * an LP2 transition. Also branched to by LP0 and LP1 resume after | ||
79 | * re-enabling sdram. | ||
80 | */ | ||
81 | ENTRY(tegra_resume) | ||
82 | bl v7_invalidate_l1 | ||
83 | /* Enable coresight */ | ||
84 | mov32 r0, 0xC5ACCE55 | ||
85 | mcr p14, 0, r0, c7, c12, 6 | ||
86 | |||
87 | cpu_id r0 | ||
88 | cmp r0, #0 @ CPU0? | ||
89 | bne cpu_resume @ no | ||
90 | |||
91 | #ifdef CONFIG_ARCH_TEGRA_3x_SOC | ||
92 | /* Are we on Tegra20? */ | ||
93 | mov32 r6, TEGRA_APB_MISC_BASE | ||
94 | ldr r0, [r6, #APB_MISC_GP_HIDREV] | ||
95 | and r0, r0, #0xff00 | ||
96 | cmp r0, #(0x20 << 8) | ||
97 | beq 1f @ Yes | ||
98 | /* Clear the flow controller flags for this CPU. */ | ||
99 | mov32 r2, TEGRA_FLOW_CTRL_BASE + FLOW_CTRL_CPU0_CSR @ CPU0 CSR | ||
100 | ldr r1, [r2] | ||
101 | /* Clear event & intr flag */ | ||
102 | orr r1, r1, \ | ||
103 | #FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG | ||
104 | movw r0, #0x0FFD @ enable, cluster_switch, immed, & bitmaps | ||
105 | bic r1, r1, r0 | ||
106 | str r1, [r2] | ||
107 | 1: | ||
108 | #endif | ||
109 | |||
110 | #ifdef CONFIG_HAVE_ARM_SCU | ||
111 | /* enable SCU */ | ||
112 | mov32 r0, TEGRA_ARM_PERIF_BASE | ||
113 | ldr r1, [r0] | ||
114 | orr r1, r1, #1 | ||
115 | str r1, [r0] | ||
116 | #endif | ||
117 | |||
118 | /* L2 cache resume & re-enable */ | ||
119 | l2_cache_resume r0, r1, r2, l2x0_saved_regs_addr | ||
120 | |||
121 | b cpu_resume | ||
122 | ENDPROC(tegra_resume) | ||
123 | #endif | ||
124 | |||
125 | #ifdef CONFIG_CACHE_L2X0 | ||
126 | .globl l2x0_saved_regs_addr | ||
127 | l2x0_saved_regs_addr: | ||
128 | .long 0 | ||
129 | #endif | ||
130 | |||
131 | .align L1_CACHE_SHIFT | ||
132 | ENTRY(__tegra_cpu_reset_handler_start) | ||
133 | |||
134 | /* | ||
135 | * __tegra_cpu_reset_handler: | ||
136 | * | ||
137 | * Common handler for all CPU reset events. | ||
138 | * | ||
139 | * Register usage within the reset handler: | ||
140 | * | ||
141 | * R7 = CPU present (to the OS) mask | ||
142 | * R8 = CPU in LP1 state mask | ||
143 | * R9 = CPU in LP2 state mask | ||
144 | * R10 = CPU number | ||
145 | * R11 = CPU mask | ||
146 | * R12 = pointer to reset handler data | ||
147 | * | ||
148 | * NOTE: This code is copied to IRAM. All code and data accesses | ||
149 | * must be position-independent. | ||
150 | */ | ||
151 | |||
152 | .align L1_CACHE_SHIFT | ||
153 | ENTRY(__tegra_cpu_reset_handler) | ||
154 | |||
155 | cpsid aif, 0x13 @ SVC mode, interrupts disabled | ||
156 | mrc p15, 0, r10, c0, c0, 5 @ MPIDR | ||
157 | and r10, r10, #0x3 @ R10 = CPU number | ||
158 | mov r11, #1 | ||
159 | mov r11, r11, lsl r10 @ R11 = CPU mask | ||
160 | adr r12, __tegra_cpu_reset_handler_data | ||
161 | |||
162 | #ifdef CONFIG_SMP | ||
163 | /* Does the OS know about this CPU? */ | ||
164 | ldr r7, [r12, #RESET_DATA(MASK_PRESENT)] | ||
165 | tst r7, r11 @ if !present | ||
166 | bleq __die @ CPU not present (to OS) | ||
167 | #endif | ||
168 | |||
169 | #ifdef CONFIG_ARCH_TEGRA_2x_SOC | ||
170 | /* Are we on Tegra20? */ | ||
171 | mov32 r6, TEGRA_APB_MISC_BASE | ||
172 | ldr r0, [r6, #APB_MISC_GP_HIDREV] | ||
173 | and r0, r0, #0xff00 | ||
174 | cmp r0, #(0x20 << 8) | ||
175 | bne 1f | ||
176 | /* If not CPU0, don't let CPU0 reset CPU1 now that CPU1 is coming up. */ | ||
177 | mov32 r6, TEGRA_PMC_BASE | ||
178 | mov r0, #0 | ||
179 | cmp r10, #0 | ||
180 | strne r0, [r6, #PMC_SCRATCH41] | ||
181 | 1: | ||
182 | #endif | ||
183 | |||
184 | /* Waking up from LP2? */ | ||
185 | ldr r9, [r12, #RESET_DATA(MASK_LP2)] | ||
186 | tst r9, r11 @ if in_lp2 | ||
187 | beq __is_not_lp2 | ||
188 | ldr lr, [r12, #RESET_DATA(STARTUP_LP2)] | ||
189 | cmp lr, #0 | ||
190 | bleq __die @ no LP2 startup handler | ||
191 | bx lr | ||
192 | |||
193 | __is_not_lp2: | ||
194 | |||
195 | #ifdef CONFIG_SMP | ||
196 | /* | ||
197 | * Can only be secondary boot (initial or hotplug) but CPU 0 | ||
198 | * cannot be here. | ||
199 | */ | ||
200 | cmp r10, #0 | ||
201 | bleq __die @ CPU0 cannot be here | ||
202 | ldr lr, [r12, #RESET_DATA(STARTUP_SECONDARY)] | ||
203 | cmp lr, #0 | ||
204 | bleq __die @ no secondary startup handler | ||
205 | bx lr | ||
206 | #endif | ||
207 | |||
208 | /* | ||
209 | * We don't know why the CPU reset. Just kill it. | ||
210 | * The LR register will contain the address we died at + 4. | ||
211 | */ | ||
212 | |||
213 | __die: | ||
214 | sub lr, lr, #4 | ||
215 | mov32 r7, TEGRA_PMC_BASE | ||
216 | str lr, [r7, #PMC_SCRATCH41] | ||
217 | |||
218 | mov32 r7, TEGRA_CLK_RESET_BASE | ||
219 | |||
220 | /* Are we on Tegra20? */ | ||
221 | mov32 r6, TEGRA_APB_MISC_BASE | ||
222 | ldr r0, [r6, #APB_MISC_GP_HIDREV] | ||
223 | and r0, r0, #0xff00 | ||
224 | cmp r0, #(0x20 << 8) | ||
225 | bne 1f | ||
226 | |||
227 | #ifdef CONFIG_ARCH_TEGRA_2x_SOC | ||
228 | mov32 r0, 0x1111 | ||
229 | mov r1, r0, lsl r10 | ||
230 | str r1, [r7, #0x340] @ CLK_RST_CPU_CMPLX_SET | ||
231 | #endif | ||
232 | 1: | ||
233 | #ifdef CONFIG_ARCH_TEGRA_3x_SOC | ||
234 | mov32 r6, TEGRA_FLOW_CTRL_BASE | ||
235 | |||
236 | cmp r10, #0 | ||
237 | moveq r1, #FLOW_CTRL_HALT_CPU0_EVENTS | ||
238 | moveq r2, #FLOW_CTRL_CPU0_CSR | ||
239 | movne r1, r10, lsl #3 | ||
240 | addne r2, r1, #(FLOW_CTRL_CPU1_CSR-8) | ||
241 | addne r1, r1, #(FLOW_CTRL_HALT_CPU1_EVENTS-8) | ||
242 | |||
243 | /* Clear CPU "event" and "interrupt" flags and power gate | ||
244 | it when halting but not before it is in the "WFI" state. */ | ||
245 | ldr r0, [r6, +r2] | ||
246 | orr r0, r0, #FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG | ||
247 | orr r0, r0, #FLOW_CTRL_CSR_ENABLE | ||
248 | str r0, [r6, +r2] | ||
249 | |||
250 | /* Unconditionally halt this CPU */ | ||
251 | mov r0, #FLOW_CTRL_WAITEVENT | ||
252 | str r0, [r6, +r1] | ||
253 | ldr r0, [r6, +r1] @ memory barrier | ||
254 | |||
255 | dsb | ||
256 | isb | ||
257 | wfi @ CPU should be power gated here | ||
258 | |||
259 | /* If the CPU didn't power gate above just kill it's clock. */ | ||
260 | |||
261 | mov r0, r11, lsl #8 | ||
262 | str r0, [r7, #348] @ CLK_CPU_CMPLX_SET | ||
263 | #endif | ||
264 | |||
265 | /* If the CPU still isn't dead, just spin here. */ | ||
266 | b . | ||
267 | ENDPROC(__tegra_cpu_reset_handler) | ||
268 | |||
269 | .align L1_CACHE_SHIFT | ||
270 | .type __tegra_cpu_reset_handler_data, %object | ||
271 | .globl __tegra_cpu_reset_handler_data | ||
272 | __tegra_cpu_reset_handler_data: | ||
273 | .rept TEGRA_RESET_DATA_SIZE | ||
274 | .long 0 | ||
275 | .endr | ||
276 | .align L1_CACHE_SHIFT | ||
277 | |||
278 | ENTRY(__tegra_cpu_reset_handler_end) | ||
diff --git a/arch/arm/mach-tegra/hotplug.c b/arch/arm/mach-tegra/hotplug.c index dca5141a2c31..6a27de4001ee 100644 --- a/arch/arm/mach-tegra/hotplug.c +++ b/arch/arm/mach-tegra/hotplug.c | |||
@@ -19,6 +19,17 @@ | |||
19 | 19 | ||
20 | static void (*tegra_hotplug_shutdown)(void); | 20 | static void (*tegra_hotplug_shutdown)(void); |
21 | 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 | |||
22 | /* | 33 | /* |
23 | * platform-specific code to shutdown a CPU | 34 | * platform-specific code to shutdown a CPU |
24 | * | 35 | * |
@@ -26,18 +37,12 @@ static void (*tegra_hotplug_shutdown)(void); | |||
26 | */ | 37 | */ |
27 | void __ref tegra_cpu_die(unsigned int cpu) | 38 | void __ref tegra_cpu_die(unsigned int cpu) |
28 | { | 39 | { |
29 | cpu = cpu_logical_map(cpu); | 40 | /* Clean L1 data cache */ |
30 | 41 | tegra_disable_clean_inv_dcache(); | |
31 | /* Flush the L1 data cache. */ | ||
32 | flush_cache_all(); | ||
33 | 42 | ||
34 | /* Shut down the current CPU. */ | 43 | /* Shut down the current CPU. */ |
35 | tegra_hotplug_shutdown(); | 44 | tegra_hotplug_shutdown(); |
36 | 45 | ||
37 | /* Clock gate the CPU */ | ||
38 | tegra_wait_cpu_in_reset(cpu); | ||
39 | tegra_disable_cpu_clock(cpu); | ||
40 | |||
41 | /* Should never return here. */ | 46 | /* Should never return here. */ |
42 | BUG(); | 47 | BUG(); |
43 | } | 48 | } |
diff --git a/arch/arm/mach-tegra/platsmp.c b/arch/arm/mach-tegra/platsmp.c index 18d7290cf93b..3c4a43c892a5 100644 --- a/arch/arm/mach-tegra/platsmp.c +++ b/arch/arm/mach-tegra/platsmp.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <asm/cacheflush.h> | 23 | #include <asm/cacheflush.h> |
24 | #include <asm/mach-types.h> | 24 | #include <asm/mach-types.h> |
25 | #include <asm/smp_scu.h> | 25 | #include <asm/smp_scu.h> |
26 | #include <asm/smp_plat.h> | ||
26 | 27 | ||
27 | #include <mach/powergate.h> | 28 | #include <mach/powergate.h> |
28 | 29 | ||
@@ -36,6 +37,7 @@ | |||
36 | 37 | ||
37 | extern void tegra_secondary_startup(void); | 38 | extern void tegra_secondary_startup(void); |
38 | 39 | ||
40 | static cpumask_t tegra_cpu_init_mask; | ||
39 | static void __iomem *scu_base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE); | 41 | static void __iomem *scu_base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE); |
40 | 42 | ||
41 | #define EVP_CPU_RESET_VECTOR \ | 43 | #define EVP_CPU_RESET_VECTOR \ |
@@ -50,6 +52,7 @@ static void __cpuinit tegra_secondary_init(unsigned int cpu) | |||
50 | */ | 52 | */ |
51 | gic_secondary_init(0); | 53 | gic_secondary_init(0); |
52 | 54 | ||
55 | cpumask_set_cpu(cpu, &tegra_cpu_init_mask); | ||
53 | } | 56 | } |
54 | 57 | ||
55 | static int tegra20_power_up_cpu(unsigned int cpu) | 58 | static int tegra20_power_up_cpu(unsigned int cpu) |
@@ -72,14 +75,42 @@ static int tegra30_power_up_cpu(unsigned int cpu) | |||
72 | if (pwrgateid < 0) | 75 | if (pwrgateid < 0) |
73 | return pwrgateid; | 76 | return pwrgateid; |
74 | 77 | ||
75 | /* If this is the first boot, toggle powergates directly. */ | 78 | /* |
79 | * The power up sequence of cold boot CPU and warm boot CPU | ||
80 | * was different. | ||
81 | * | ||
82 | * For warm boot CPU that was resumed from CPU hotplug, the | ||
83 | * power will be resumed automatically after un-halting the | ||
84 | * flow controller of the warm boot CPU. We need to wait for | ||
85 | * the confirmaiton that the CPU is powered then removing | ||
86 | * the IO clamps. | ||
87 | * For cold boot CPU, do not wait. After the cold boot CPU be | ||
88 | * booted, it will run to tegra_secondary_init() and set | ||
89 | * tegra_cpu_init_mask which influences what tegra30_power_up_cpu() | ||
90 | * next time around. | ||
91 | */ | ||
92 | if (cpumask_test_cpu(cpu, &tegra_cpu_init_mask)) { | ||
93 | timeout = jiffies + msecs_to_jiffies(50); | ||
94 | do { | ||
95 | if (!tegra_powergate_is_powered(pwrgateid)) | ||
96 | goto remove_clamps; | ||
97 | udelay(10); | ||
98 | } while (time_before(jiffies, timeout)); | ||
99 | } | ||
100 | |||
101 | /* | ||
102 | * The power status of the cold boot CPU is power gated as | ||
103 | * default. To power up the cold boot CPU, the power should | ||
104 | * be un-gated by un-toggling the power gate register | ||
105 | * manually. | ||
106 | */ | ||
76 | if (!tegra_powergate_is_powered(pwrgateid)) { | 107 | if (!tegra_powergate_is_powered(pwrgateid)) { |
77 | ret = tegra_powergate_power_on(pwrgateid); | 108 | ret = tegra_powergate_power_on(pwrgateid); |
78 | if (ret) | 109 | if (ret) |
79 | return ret; | 110 | return ret; |
80 | 111 | ||
81 | /* Wait for the power to come up. */ | 112 | /* Wait for the power to come up. */ |
82 | timeout = jiffies + 10*HZ; | 113 | timeout = jiffies + msecs_to_jiffies(100); |
83 | while (tegra_powergate_is_powered(pwrgateid)) { | 114 | while (tegra_powergate_is_powered(pwrgateid)) { |
84 | if (time_after(jiffies, timeout)) | 115 | if (time_after(jiffies, timeout)) |
85 | return -ETIMEDOUT; | 116 | return -ETIMEDOUT; |
@@ -87,6 +118,7 @@ static int tegra30_power_up_cpu(unsigned int cpu) | |||
87 | } | 118 | } |
88 | } | 119 | } |
89 | 120 | ||
121 | remove_clamps: | ||
90 | /* CPU partition is powered. Enable the CPU clock. */ | 122 | /* CPU partition is powered. Enable the CPU clock. */ |
91 | tegra_enable_cpu_clock(cpu); | 123 | tegra_enable_cpu_clock(cpu); |
92 | udelay(10); | 124 | udelay(10); |
@@ -105,6 +137,8 @@ static int __cpuinit tegra_boot_secondary(unsigned int cpu, struct task_struct * | |||
105 | { | 137 | { |
106 | int status; | 138 | int status; |
107 | 139 | ||
140 | cpu = cpu_logical_map(cpu); | ||
141 | |||
108 | /* | 142 | /* |
109 | * Force the CPU into reset. The CPU must remain in reset when the | 143 | * Force the CPU into reset. The CPU must remain in reset when the |
110 | * flow controller state is cleared (which will cause the flow | 144 | * flow controller state is cleared (which will cause the flow |
@@ -163,7 +197,9 @@ static void __init tegra_smp_init_cpus(void) | |||
163 | 197 | ||
164 | static void __init tegra_smp_prepare_cpus(unsigned int max_cpus) | 198 | static void __init tegra_smp_prepare_cpus(unsigned int max_cpus) |
165 | { | 199 | { |
166 | tegra_cpu_reset_handler_init(); | 200 | /* Always mark the boot CPU (CPU0) as initialized. */ |
201 | cpumask_set_cpu(0, &tegra_cpu_init_mask); | ||
202 | |||
167 | scu_enable(scu_base); | 203 | scu_enable(scu_base); |
168 | } | 204 | } |
169 | 205 | ||
@@ -173,6 +209,7 @@ struct smp_operations tegra_smp_ops __initdata = { | |||
173 | .smp_secondary_init = tegra_secondary_init, | 209 | .smp_secondary_init = tegra_secondary_init, |
174 | .smp_boot_secondary = tegra_boot_secondary, | 210 | .smp_boot_secondary = tegra_boot_secondary, |
175 | #ifdef CONFIG_HOTPLUG_CPU | 211 | #ifdef CONFIG_HOTPLUG_CPU |
212 | .cpu_kill = tegra_cpu_kill, | ||
176 | .cpu_die = tegra_cpu_die, | 213 | .cpu_die = tegra_cpu_die, |
177 | .cpu_disable = tegra_cpu_disable, | 214 | .cpu_disable = tegra_cpu_disable, |
178 | #endif | 215 | #endif |
diff --git a/arch/arm/mach-tegra/pm.c b/arch/arm/mach-tegra/pm.c index 1b11707eaca0..498d70b33775 100644 --- a/arch/arm/mach-tegra/pm.c +++ b/arch/arm/mach-tegra/pm.c | |||
@@ -148,7 +148,7 @@ static void suspend_cpu_complex(void) | |||
148 | save_cpu_arch_register(); | 148 | save_cpu_arch_register(); |
149 | } | 149 | } |
150 | 150 | ||
151 | void __cpuinit tegra_clear_cpu_in_lp2(int phy_cpu_id) | 151 | void tegra_clear_cpu_in_lp2(int phy_cpu_id) |
152 | { | 152 | { |
153 | u32 *cpu_in_lp2 = tegra_cpu_lp2_mask; | 153 | u32 *cpu_in_lp2 = tegra_cpu_lp2_mask; |
154 | 154 | ||
@@ -160,7 +160,7 @@ void __cpuinit tegra_clear_cpu_in_lp2(int phy_cpu_id) | |||
160 | spin_unlock(&tegra_lp2_lock); | 160 | spin_unlock(&tegra_lp2_lock); |
161 | } | 161 | } |
162 | 162 | ||
163 | bool __cpuinit tegra_set_cpu_in_lp2(int phy_cpu_id) | 163 | bool tegra_set_cpu_in_lp2(int phy_cpu_id) |
164 | { | 164 | { |
165 | bool last_cpu = false; | 165 | bool last_cpu = false; |
166 | cpumask_t *cpu_lp2_mask = tegra_cpu_lp2_mask; | 166 | cpumask_t *cpu_lp2_mask = tegra_cpu_lp2_mask; |
diff --git a/arch/arm/mach-tegra/reset-handler.S b/arch/arm/mach-tegra/reset-handler.S new file mode 100644 index 000000000000..54382ceade4a --- /dev/null +++ b/arch/arm/mach-tegra/reset-handler.S | |||
@@ -0,0 +1,239 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2012, NVIDIA Corporation. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
15 | */ | ||
16 | |||
17 | #include <linux/linkage.h> | ||
18 | #include <linux/init.h> | ||
19 | |||
20 | #include <asm/cache.h> | ||
21 | #include <asm/asm-offsets.h> | ||
22 | #include <asm/hardware/cache-l2x0.h> | ||
23 | |||
24 | #include "flowctrl.h" | ||
25 | #include "iomap.h" | ||
26 | #include "reset.h" | ||
27 | #include "sleep.h" | ||
28 | |||
29 | #define APB_MISC_GP_HIDREV 0x804 | ||
30 | #define PMC_SCRATCH41 0x140 | ||
31 | |||
32 | #define RESET_DATA(x) ((TEGRA_RESET_##x)*4) | ||
33 | |||
34 | #ifdef CONFIG_PM_SLEEP | ||
35 | /* | ||
36 | * tegra_resume | ||
37 | * | ||
38 | * CPU boot vector when restarting the a CPU following | ||
39 | * an LP2 transition. Also branched to by LP0 and LP1 resume after | ||
40 | * re-enabling sdram. | ||
41 | */ | ||
42 | ENTRY(tegra_resume) | ||
43 | bl v7_invalidate_l1 | ||
44 | /* Enable coresight */ | ||
45 | mov32 r0, 0xC5ACCE55 | ||
46 | mcr p14, 0, r0, c7, c12, 6 | ||
47 | |||
48 | cpu_id r0 | ||
49 | cmp r0, #0 @ CPU0? | ||
50 | bne cpu_resume @ no | ||
51 | |||
52 | #ifdef CONFIG_ARCH_TEGRA_3x_SOC | ||
53 | /* Are we on Tegra20? */ | ||
54 | mov32 r6, TEGRA_APB_MISC_BASE | ||
55 | ldr r0, [r6, #APB_MISC_GP_HIDREV] | ||
56 | and r0, r0, #0xff00 | ||
57 | cmp r0, #(0x20 << 8) | ||
58 | beq 1f @ Yes | ||
59 | /* Clear the flow controller flags for this CPU. */ | ||
60 | mov32 r2, TEGRA_FLOW_CTRL_BASE + FLOW_CTRL_CPU0_CSR @ CPU0 CSR | ||
61 | ldr r1, [r2] | ||
62 | /* Clear event & intr flag */ | ||
63 | orr r1, r1, \ | ||
64 | #FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG | ||
65 | movw r0, #0x0FFD @ enable, cluster_switch, immed, & bitmaps | ||
66 | bic r1, r1, r0 | ||
67 | str r1, [r2] | ||
68 | 1: | ||
69 | #endif | ||
70 | |||
71 | #ifdef CONFIG_HAVE_ARM_SCU | ||
72 | /* enable SCU */ | ||
73 | mov32 r0, TEGRA_ARM_PERIF_BASE | ||
74 | ldr r1, [r0] | ||
75 | orr r1, r1, #1 | ||
76 | str r1, [r0] | ||
77 | #endif | ||
78 | |||
79 | /* L2 cache resume & re-enable */ | ||
80 | l2_cache_resume r0, r1, r2, l2x0_saved_regs_addr | ||
81 | |||
82 | b cpu_resume | ||
83 | ENDPROC(tegra_resume) | ||
84 | #endif | ||
85 | |||
86 | #ifdef CONFIG_CACHE_L2X0 | ||
87 | .globl l2x0_saved_regs_addr | ||
88 | l2x0_saved_regs_addr: | ||
89 | .long 0 | ||
90 | #endif | ||
91 | |||
92 | .align L1_CACHE_SHIFT | ||
93 | ENTRY(__tegra_cpu_reset_handler_start) | ||
94 | |||
95 | /* | ||
96 | * __tegra_cpu_reset_handler: | ||
97 | * | ||
98 | * Common handler for all CPU reset events. | ||
99 | * | ||
100 | * Register usage within the reset handler: | ||
101 | * | ||
102 | * R7 = CPU present (to the OS) mask | ||
103 | * R8 = CPU in LP1 state mask | ||
104 | * R9 = CPU in LP2 state mask | ||
105 | * R10 = CPU number | ||
106 | * R11 = CPU mask | ||
107 | * R12 = pointer to reset handler data | ||
108 | * | ||
109 | * NOTE: This code is copied to IRAM. All code and data accesses | ||
110 | * must be position-independent. | ||
111 | */ | ||
112 | |||
113 | .align L1_CACHE_SHIFT | ||
114 | ENTRY(__tegra_cpu_reset_handler) | ||
115 | |||
116 | cpsid aif, 0x13 @ SVC mode, interrupts disabled | ||
117 | mrc p15, 0, r10, c0, c0, 5 @ MPIDR | ||
118 | and r10, r10, #0x3 @ R10 = CPU number | ||
119 | mov r11, #1 | ||
120 | mov r11, r11, lsl r10 @ R11 = CPU mask | ||
121 | adr r12, __tegra_cpu_reset_handler_data | ||
122 | |||
123 | #ifdef CONFIG_SMP | ||
124 | /* Does the OS know about this CPU? */ | ||
125 | ldr r7, [r12, #RESET_DATA(MASK_PRESENT)] | ||
126 | tst r7, r11 @ if !present | ||
127 | bleq __die @ CPU not present (to OS) | ||
128 | #endif | ||
129 | |||
130 | #ifdef CONFIG_ARCH_TEGRA_2x_SOC | ||
131 | /* Are we on Tegra20? */ | ||
132 | mov32 r6, TEGRA_APB_MISC_BASE | ||
133 | ldr r0, [r6, #APB_MISC_GP_HIDREV] | ||
134 | and r0, r0, #0xff00 | ||
135 | cmp r0, #(0x20 << 8) | ||
136 | bne 1f | ||
137 | /* If not CPU0, don't let CPU0 reset CPU1 now that CPU1 is coming up. */ | ||
138 | mov32 r6, TEGRA_PMC_BASE | ||
139 | mov r0, #0 | ||
140 | cmp r10, #0 | ||
141 | strne r0, [r6, #PMC_SCRATCH41] | ||
142 | 1: | ||
143 | #endif | ||
144 | |||
145 | /* Waking up from LP2? */ | ||
146 | ldr r9, [r12, #RESET_DATA(MASK_LP2)] | ||
147 | tst r9, r11 @ if in_lp2 | ||
148 | beq __is_not_lp2 | ||
149 | ldr lr, [r12, #RESET_DATA(STARTUP_LP2)] | ||
150 | cmp lr, #0 | ||
151 | bleq __die @ no LP2 startup handler | ||
152 | bx lr | ||
153 | |||
154 | __is_not_lp2: | ||
155 | |||
156 | #ifdef CONFIG_SMP | ||
157 | /* | ||
158 | * Can only be secondary boot (initial or hotplug) but CPU 0 | ||
159 | * cannot be here. | ||
160 | */ | ||
161 | cmp r10, #0 | ||
162 | bleq __die @ CPU0 cannot be here | ||
163 | ldr lr, [r12, #RESET_DATA(STARTUP_SECONDARY)] | ||
164 | cmp lr, #0 | ||
165 | bleq __die @ no secondary startup handler | ||
166 | bx lr | ||
167 | #endif | ||
168 | |||
169 | /* | ||
170 | * We don't know why the CPU reset. Just kill it. | ||
171 | * The LR register will contain the address we died at + 4. | ||
172 | */ | ||
173 | |||
174 | __die: | ||
175 | sub lr, lr, #4 | ||
176 | mov32 r7, TEGRA_PMC_BASE | ||
177 | str lr, [r7, #PMC_SCRATCH41] | ||
178 | |||
179 | mov32 r7, TEGRA_CLK_RESET_BASE | ||
180 | |||
181 | /* Are we on Tegra20? */ | ||
182 | mov32 r6, TEGRA_APB_MISC_BASE | ||
183 | ldr r0, [r6, #APB_MISC_GP_HIDREV] | ||
184 | and r0, r0, #0xff00 | ||
185 | cmp r0, #(0x20 << 8) | ||
186 | bne 1f | ||
187 | |||
188 | #ifdef CONFIG_ARCH_TEGRA_2x_SOC | ||
189 | mov32 r0, 0x1111 | ||
190 | mov r1, r0, lsl r10 | ||
191 | str r1, [r7, #0x340] @ CLK_RST_CPU_CMPLX_SET | ||
192 | #endif | ||
193 | 1: | ||
194 | #ifdef CONFIG_ARCH_TEGRA_3x_SOC | ||
195 | mov32 r6, TEGRA_FLOW_CTRL_BASE | ||
196 | |||
197 | cmp r10, #0 | ||
198 | moveq r1, #FLOW_CTRL_HALT_CPU0_EVENTS | ||
199 | moveq r2, #FLOW_CTRL_CPU0_CSR | ||
200 | movne r1, r10, lsl #3 | ||
201 | addne r2, r1, #(FLOW_CTRL_CPU1_CSR-8) | ||
202 | addne r1, r1, #(FLOW_CTRL_HALT_CPU1_EVENTS-8) | ||
203 | |||
204 | /* Clear CPU "event" and "interrupt" flags and power gate | ||
205 | it when halting but not before it is in the "WFI" state. */ | ||
206 | ldr r0, [r6, +r2] | ||
207 | orr r0, r0, #FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG | ||
208 | orr r0, r0, #FLOW_CTRL_CSR_ENABLE | ||
209 | str r0, [r6, +r2] | ||
210 | |||
211 | /* Unconditionally halt this CPU */ | ||
212 | mov r0, #FLOW_CTRL_WAITEVENT | ||
213 | str r0, [r6, +r1] | ||
214 | ldr r0, [r6, +r1] @ memory barrier | ||
215 | |||
216 | dsb | ||
217 | isb | ||
218 | wfi @ CPU should be power gated here | ||
219 | |||
220 | /* If the CPU didn't power gate above just kill it's clock. */ | ||
221 | |||
222 | mov r0, r11, lsl #8 | ||
223 | str r0, [r7, #348] @ CLK_CPU_CMPLX_SET | ||
224 | #endif | ||
225 | |||
226 | /* If the CPU still isn't dead, just spin here. */ | ||
227 | b . | ||
228 | ENDPROC(__tegra_cpu_reset_handler) | ||
229 | |||
230 | .align L1_CACHE_SHIFT | ||
231 | .type __tegra_cpu_reset_handler_data, %object | ||
232 | .globl __tegra_cpu_reset_handler_data | ||
233 | __tegra_cpu_reset_handler_data: | ||
234 | .rept TEGRA_RESET_DATA_SIZE | ||
235 | .long 0 | ||
236 | .endr | ||
237 | .align L1_CACHE_SHIFT | ||
238 | |||
239 | ENTRY(__tegra_cpu_reset_handler_end) | ||
diff --git a/arch/arm/mach-tegra/reset.c b/arch/arm/mach-tegra/reset.c index 3fd89ecd158e..1ac434e0068f 100644 --- a/arch/arm/mach-tegra/reset.c +++ b/arch/arm/mach-tegra/reset.c | |||
@@ -75,7 +75,7 @@ void __init tegra_cpu_reset_handler_init(void) | |||
75 | 75 | ||
76 | #ifdef CONFIG_SMP | 76 | #ifdef CONFIG_SMP |
77 | __tegra_cpu_reset_handler_data[TEGRA_RESET_MASK_PRESENT] = | 77 | __tegra_cpu_reset_handler_data[TEGRA_RESET_MASK_PRESENT] = |
78 | *((u32 *)cpu_present_mask); | 78 | *((u32 *)cpu_possible_mask); |
79 | __tegra_cpu_reset_handler_data[TEGRA_RESET_STARTUP_SECONDARY] = | 79 | __tegra_cpu_reset_handler_data[TEGRA_RESET_STARTUP_SECONDARY] = |
80 | virt_to_phys((void *)tegra_secondary_startup); | 80 | virt_to_phys((void *)tegra_secondary_startup); |
81 | #endif | 81 | #endif |
diff --git a/arch/arm/mach-tegra/sleep-tegra20.S b/arch/arm/mach-tegra/sleep-tegra20.S index 72ce709799da..ad2ca07d0578 100644 --- a/arch/arm/mach-tegra/sleep-tegra20.S +++ b/arch/arm/mach-tegra/sleep-tegra20.S | |||
@@ -33,9 +33,6 @@ | |||
33 | * should never return | 33 | * should never return |
34 | */ | 34 | */ |
35 | ENTRY(tegra20_hotplug_shutdown) | 35 | ENTRY(tegra20_hotplug_shutdown) |
36 | /* Turn off SMP coherency */ | ||
37 | exit_smp r4, r5 | ||
38 | |||
39 | /* Put this CPU down */ | 36 | /* Put this CPU down */ |
40 | cpu_id r0 | 37 | cpu_id r0 |
41 | bl tegra20_cpu_shutdown | 38 | bl tegra20_cpu_shutdown |
diff --git a/arch/arm/mach-tegra/sleep-tegra30.S b/arch/arm/mach-tegra/sleep-tegra30.S index 562a8e7e413d..63a15bd9b653 100644 --- a/arch/arm/mach-tegra/sleep-tegra30.S +++ b/arch/arm/mach-tegra/sleep-tegra30.S | |||
@@ -32,9 +32,6 @@ | |||
32 | * Should never return. | 32 | * Should never return. |
33 | */ | 33 | */ |
34 | ENTRY(tegra30_hotplug_shutdown) | 34 | ENTRY(tegra30_hotplug_shutdown) |
35 | /* Turn off SMP coherency */ | ||
36 | exit_smp r4, r5 | ||
37 | |||
38 | /* Powergate this CPU */ | 35 | /* Powergate this CPU */ |
39 | mov r0, #TEGRA30_POWER_HOTPLUG_SHUTDOWN | 36 | mov r0, #TEGRA30_POWER_HOTPLUG_SHUTDOWN |
40 | bl tegra30_cpu_shutdown | 37 | bl tegra30_cpu_shutdown |
diff --git a/arch/arm/mach-tegra/sleep.S b/arch/arm/mach-tegra/sleep.S index 26afa7cbed11..addae357da3f 100644 --- a/arch/arm/mach-tegra/sleep.S +++ b/arch/arm/mach-tegra/sleep.S | |||
@@ -34,7 +34,7 @@ | |||
34 | #include "flowctrl.h" | 34 | #include "flowctrl.h" |
35 | #include "sleep.h" | 35 | #include "sleep.h" |
36 | 36 | ||
37 | #ifdef CONFIG_PM_SLEEP | 37 | #if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_PM_SLEEP) |
38 | /* | 38 | /* |
39 | * tegra_disable_clean_inv_dcache | 39 | * tegra_disable_clean_inv_dcache |
40 | * | 40 | * |
@@ -60,7 +60,9 @@ ENTRY(tegra_disable_clean_inv_dcache) | |||
60 | 60 | ||
61 | ldmfd sp!, {r0, r4-r5, r7, r9-r11, pc} | 61 | ldmfd sp!, {r0, r4-r5, r7, r9-r11, pc} |
62 | ENDPROC(tegra_disable_clean_inv_dcache) | 62 | ENDPROC(tegra_disable_clean_inv_dcache) |
63 | #endif | ||
63 | 64 | ||
65 | #ifdef CONFIG_PM_SLEEP | ||
64 | /* | 66 | /* |
65 | * tegra_sleep_cpu_finish(unsigned long v2p) | 67 | * tegra_sleep_cpu_finish(unsigned long v2p) |
66 | * | 68 | * |
diff --git a/arch/arm/mach-tegra/sleep.h b/arch/arm/mach-tegra/sleep.h index 9821ee725420..56505c381ea8 100644 --- a/arch/arm/mach-tegra/sleep.h +++ b/arch/arm/mach-tegra/sleep.h | |||
@@ -106,6 +106,7 @@ exit_l2_resume: | |||
106 | #else | 106 | #else |
107 | void tegra_resume(void); | 107 | void tegra_resume(void); |
108 | int tegra_sleep_cpu_finish(unsigned long); | 108 | int tegra_sleep_cpu_finish(unsigned long); |
109 | void tegra_disable_clean_inv_dcache(void); | ||
109 | 110 | ||
110 | #ifdef CONFIG_HOTPLUG_CPU | 111 | #ifdef CONFIG_HOTPLUG_CPU |
111 | void tegra20_hotplug_init(void); | 112 | void tegra20_hotplug_init(void); |
diff --git a/arch/arm/mach-tegra/tegra30_clocks_data.c b/arch/arm/mach-tegra/tegra30_clocks_data.c index 6942c7add3bb..741d264d5ecb 100644 --- a/arch/arm/mach-tegra/tegra30_clocks_data.c +++ b/arch/arm/mach-tegra/tegra30_clocks_data.c | |||
@@ -1183,7 +1183,7 @@ static struct clk tegra_dsib = { | |||
1183 | .num_parents = ARRAY_SIZE(mux_plld_out0_plld2_out0), | 1183 | .num_parents = ARRAY_SIZE(mux_plld_out0_plld2_out0), |
1184 | }; | 1184 | }; |
1185 | 1185 | ||
1186 | struct clk *tegra_list_clks[] = { | 1186 | static struct clk *tegra_list_clks[] = { |
1187 | &tegra_apbdma, | 1187 | &tegra_apbdma, |
1188 | &tegra_rtc, | 1188 | &tegra_rtc, |
1189 | &tegra_kbc, | 1189 | &tegra_kbc, |
@@ -1289,7 +1289,7 @@ struct clk *tegra_list_clks[] = { | |||
1289 | * configuration. List those here to register them twice in the clock lookup | 1289 | * configuration. List those here to register them twice in the clock lookup |
1290 | * table under two names. | 1290 | * table under two names. |
1291 | */ | 1291 | */ |
1292 | struct clk_duplicate tegra_clk_duplicates[] = { | 1292 | static struct clk_duplicate tegra_clk_duplicates[] = { |
1293 | CLK_DUPLICATE("uarta", "serial8250.0", NULL), | 1293 | CLK_DUPLICATE("uarta", "serial8250.0", NULL), |
1294 | CLK_DUPLICATE("uartb", "serial8250.1", NULL), | 1294 | CLK_DUPLICATE("uartb", "serial8250.1", NULL), |
1295 | CLK_DUPLICATE("uartc", "serial8250.2", NULL), | 1295 | CLK_DUPLICATE("uartc", "serial8250.2", NULL), |
@@ -1340,7 +1340,7 @@ struct clk_duplicate tegra_clk_duplicates[] = { | |||
1340 | CLK_DUPLICATE("pll_d2_out0", "hdmi", "parent"), | 1340 | CLK_DUPLICATE("pll_d2_out0", "hdmi", "parent"), |
1341 | }; | 1341 | }; |
1342 | 1342 | ||
1343 | struct clk *tegra_ptr_clks[] = { | 1343 | static struct clk *tegra_ptr_clks[] = { |
1344 | &tegra_clk_32k, | 1344 | &tegra_clk_32k, |
1345 | &tegra_clk_m, | 1345 | &tegra_clk_m, |
1346 | &tegra_clk_m_div2, | 1346 | &tegra_clk_m_div2, |
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile index 440449c1ca21..596c45c2f192 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile | |||
@@ -17,6 +17,7 @@ obj-$(CONFIG_CLKSRC_DBX500_PRCMU) += clksrc-dbx500-prcmu.o | |||
17 | obj-$(CONFIG_ARMADA_370_XP_TIMER) += time-armada-370-xp.o | 17 | obj-$(CONFIG_ARMADA_370_XP_TIMER) += time-armada-370-xp.o |
18 | obj-$(CONFIG_ARCH_BCM2835) += bcm2835_timer.o | 18 | obj-$(CONFIG_ARCH_BCM2835) += bcm2835_timer.o |
19 | obj-$(CONFIG_SUNXI_TIMER) += sunxi_timer.o | 19 | obj-$(CONFIG_SUNXI_TIMER) += sunxi_timer.o |
20 | obj-$(CONFIG_ARCH_TEGRA) += tegra20_timer.o | ||
20 | obj-$(CONFIG_VT8500_TIMER) += vt8500_timer.o | 21 | obj-$(CONFIG_VT8500_TIMER) += vt8500_timer.o |
21 | 22 | ||
22 | obj-$(CONFIG_CLKSRC_ARM_GENERIC) += arm_generic.o | 23 | obj-$(CONFIG_CLKSRC_ARM_GENERIC) += arm_generic.o |
diff --git a/arch/arm/mach-tegra/timer.c b/drivers/clocksource/tegra20_timer.c index eba0969ded19..0bde03feb095 100644 --- a/arch/arm/mach-tegra/timer.c +++ b/drivers/clocksource/tegra20_timer.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * arch/arch/mach-tegra/timer.c | ||
3 | * | ||
4 | * Copyright (C) 2010 Google, Inc. | 2 | * Copyright (C) 2010 Google, Inc. |
5 | * | 3 | * |
6 | * Author: | 4 | * Author: |
@@ -33,8 +31,6 @@ | |||
33 | #include <asm/smp_twd.h> | 31 | #include <asm/smp_twd.h> |
34 | #include <asm/sched_clock.h> | 32 | #include <asm/sched_clock.h> |
35 | 33 | ||
36 | #include "board.h" | ||
37 | |||
38 | #define RTC_SECONDS 0x08 | 34 | #define RTC_SECONDS 0x08 |
39 | #define RTC_SHADOW_SECONDS 0x0c | 35 | #define RTC_SHADOW_SECONDS 0x0c |
40 | #define RTC_MILLISECONDS 0x10 | 36 | #define RTC_MILLISECONDS 0x10 |
@@ -168,7 +164,7 @@ static const struct of_device_id rtc_match[] __initconst = { | |||
168 | {} | 164 | {} |
169 | }; | 165 | }; |
170 | 166 | ||
171 | void __init tegra_init_timer(void) | 167 | static void __init tegra20_init_timer(void) |
172 | { | 168 | { |
173 | struct device_node *np; | 169 | struct device_node *np; |
174 | struct clk *clk; | 170 | struct clk *clk; |
@@ -183,7 +179,7 @@ void __init tegra_init_timer(void) | |||
183 | 179 | ||
184 | timer_reg_base = of_iomap(np, 0); | 180 | timer_reg_base = of_iomap(np, 0); |
185 | if (!timer_reg_base) { | 181 | if (!timer_reg_base) { |
186 | pr_err("Can't map timer registers"); | 182 | pr_err("Can't map timer registers\n"); |
187 | BUG(); | 183 | BUG(); |
188 | } | 184 | } |
189 | 185 | ||
@@ -268,6 +264,7 @@ void __init tegra_init_timer(void) | |||
268 | #endif | 264 | #endif |
269 | register_persistent_clock(NULL, tegra_read_persistent_clock); | 265 | register_persistent_clock(NULL, tegra_read_persistent_clock); |
270 | } | 266 | } |
267 | CLOCKSOURCE_OF_DECLARE(tegra20, "nvidia,tegra20-timer", tegra20_init_timer); | ||
271 | 268 | ||
272 | #ifdef CONFIG_PM | 269 | #ifdef CONFIG_PM |
273 | static u32 usec_config; | 270 | static u32 usec_config; |