diff options
author | Alexandre Courbot <acourbot@nvidia.com> | 2013-11-24 01:30:51 -0500 |
---|---|---|
committer | Stephen Warren <swarren@nvidia.com> | 2013-12-13 14:50:31 -0500 |
commit | 265c89c994611e75943563e9b741cb8ae04a43af (patch) | |
tree | 6652e169a599dc212a1bed55ff2feec095c4f288 /arch/arm/mach-tegra | |
parent | ad14ecee4d868a54556e40cdc3df7fe78e3ab9d0 (diff) |
ARM: tegra: set CPU reset handler using firmware
Use a firmware operation to set the CPU reset handler and only resort to
doing it ourselves if there is none defined.
This supports the booting of secondary CPUs on devices using a TrustZone
secure monitor.
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
Reviewed-by: Tomasz Figa <t.figa@samsung.com>
Reviewed-by: Stephen Warren <swarren@nvidia.com>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
Diffstat (limited to 'arch/arm/mach-tegra')
-rw-r--r-- | arch/arm/mach-tegra/reset.c | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/arch/arm/mach-tegra/reset.c b/arch/arm/mach-tegra/reset.c index 17c4b6d6b498..146fe8e0ae7c 100644 --- a/arch/arm/mach-tegra/reset.c +++ b/arch/arm/mach-tegra/reset.c | |||
@@ -21,6 +21,7 @@ | |||
21 | 21 | ||
22 | #include <asm/cacheflush.h> | 22 | #include <asm/cacheflush.h> |
23 | #include <asm/hardware/cache-l2x0.h> | 23 | #include <asm/hardware/cache-l2x0.h> |
24 | #include <asm/firmware.h> | ||
24 | 25 | ||
25 | #include "iomap.h" | 26 | #include "iomap.h" |
26 | #include "irammap.h" | 27 | #include "irammap.h" |
@@ -65,6 +66,7 @@ static void __init tegra_cpu_reset_handler_enable(void) | |||
65 | void __iomem *iram_base = IO_ADDRESS(TEGRA_IRAM_RESET_BASE); | 66 | void __iomem *iram_base = IO_ADDRESS(TEGRA_IRAM_RESET_BASE); |
66 | const u32 reset_address = TEGRA_IRAM_RESET_BASE + | 67 | const u32 reset_address = TEGRA_IRAM_RESET_BASE + |
67 | tegra_cpu_reset_handler_offset; | 68 | tegra_cpu_reset_handler_offset; |
69 | int err; | ||
68 | 70 | ||
69 | BUG_ON(is_enabled); | 71 | BUG_ON(is_enabled); |
70 | BUG_ON(tegra_cpu_reset_handler_size > TEGRA_IRAM_RESET_HANDLER_SIZE); | 72 | BUG_ON(tegra_cpu_reset_handler_size > TEGRA_IRAM_RESET_HANDLER_SIZE); |
@@ -72,9 +74,18 @@ static void __init tegra_cpu_reset_handler_enable(void) | |||
72 | memcpy(iram_base, (void *)__tegra_cpu_reset_handler_start, | 74 | memcpy(iram_base, (void *)__tegra_cpu_reset_handler_start, |
73 | tegra_cpu_reset_handler_size); | 75 | tegra_cpu_reset_handler_size); |
74 | 76 | ||
75 | tegra_cpu_reset_handler_set(reset_address); | 77 | err = call_firmware_op(set_cpu_boot_addr, 0, reset_address); |
76 | 78 | switch (err) { | |
77 | is_enabled = true; | 79 | case -ENOSYS: |
80 | tegra_cpu_reset_handler_set(reset_address); | ||
81 | /* pass-through */ | ||
82 | case 0: | ||
83 | is_enabled = true; | ||
84 | break; | ||
85 | default: | ||
86 | pr_crit("Cannot set CPU reset handler: %d\n", err); | ||
87 | BUG(); | ||
88 | } | ||
78 | } | 89 | } |
79 | 90 | ||
80 | void __init tegra_cpu_reset_handler_init(void) | 91 | void __init tegra_cpu_reset_handler_init(void) |