aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-tegra
diff options
context:
space:
mode:
authorAlexandre Courbot <acourbot@nvidia.com>2013-11-24 01:30:51 -0500
committerStephen Warren <swarren@nvidia.com>2013-12-13 14:50:31 -0500
commit265c89c994611e75943563e9b741cb8ae04a43af (patch)
tree6652e169a599dc212a1bed55ff2feec095c4f288 /arch/arm/mach-tegra
parentad14ecee4d868a54556e40cdc3df7fe78e3ab9d0 (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.c17
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
80void __init tegra_cpu_reset_handler_init(void) 91void __init tegra_cpu_reset_handler_init(void)