]> Pileus Git - ~andy/linux/commitdiff
ARM: tegra: split setting of CPU reset handler
authorAlexandre Courbot <acourbot@nvidia.com>
Sun, 24 Nov 2013 06:30:50 +0000 (15:30 +0900)
committerStephen Warren <swarren@nvidia.com>
Fri, 13 Dec 2013 19:50:31 +0000 (12:50 -0700)
Not all Tegra devices can set the CPU reset handler in the same way.
In particular, devices using a TrustZone secure monitor cannot set it
up directly and need to ask the firmware to do it.

This patch separates the act of setting the reset handler from its
preparation, so the former can be implemented in a different way.

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>
arch/arm/mach-tegra/reset.c

index 568f5bbf979da4429e677430dd582d2a6c2f9f29..17c4b6d6b498a5c1b6aba2ccbe1765d43277e97d 100644 (file)
 
 static bool is_enabled;
 
-static void __init tegra_cpu_reset_handler_enable(void)
+static void __init tegra_cpu_reset_handler_set(const u32 reset_address)
 {
-       void __iomem *iram_base = IO_ADDRESS(TEGRA_IRAM_RESET_BASE);
        void __iomem *evp_cpu_reset =
                IO_ADDRESS(TEGRA_EXCEPTION_VECTORS_BASE + 0x100);
        void __iomem *sb_ctrl = IO_ADDRESS(TEGRA_SB_BASE);
        u32 reg;
 
-       BUG_ON(is_enabled);
-       BUG_ON(tegra_cpu_reset_handler_size > TEGRA_IRAM_RESET_HANDLER_SIZE);
-
-       memcpy(iram_base, (void *)__tegra_cpu_reset_handler_start,
-                       tegra_cpu_reset_handler_size);
-
        /*
         * NOTE: This must be the one and only write to the EVP CPU reset
         *       vector in the entire system.
         */
-       writel(TEGRA_IRAM_RESET_BASE + tegra_cpu_reset_handler_offset,
-                       evp_cpu_reset);
+       writel(reset_address, evp_cpu_reset);
        wmb();
        reg = readl(evp_cpu_reset);
 
@@ -66,6 +58,21 @@ static void __init tegra_cpu_reset_handler_enable(void)
                writel(reg, sb_ctrl);
                wmb();
        }
+}
+
+static void __init tegra_cpu_reset_handler_enable(void)
+{
+       void __iomem *iram_base = IO_ADDRESS(TEGRA_IRAM_RESET_BASE);
+       const u32 reset_address = TEGRA_IRAM_RESET_BASE +
+                                               tegra_cpu_reset_handler_offset;
+
+       BUG_ON(is_enabled);
+       BUG_ON(tegra_cpu_reset_handler_size > TEGRA_IRAM_RESET_HANDLER_SIZE);
+
+       memcpy(iram_base, (void *)__tegra_cpu_reset_handler_start,
+                       tegra_cpu_reset_handler_size);
+
+       tegra_cpu_reset_handler_set(reset_address);
 
        is_enabled = true;
 }