OSDN Git Service

ARM: mvebu: add function to set the resume boot address for Armada 375
authorGregory CLEMENT <gregory.clement@free-electrons.com>
Mon, 14 Apr 2014 13:54:03 +0000 (15:54 +0200)
committerJason Cooper <jason@lakedaemon.net>
Thu, 8 May 2014 16:08:14 +0000 (16:08 +0000)
In order to boot the secondary CPUs on Armada 375, we need to set the
boot address of these CPUs, through a register part of the System
Controller (this deviates from the Armada XP design, where the boot
address was defined using a register part of the PMSU unit).

Therefore, this commit adds a new helper function in the System
Controller driver to set the secondary CPU boot address.

Moreover, it moves the System Controller initialization as an
early_initcall(), since arch_initcall() is too late for an SMP-related
initialization.

Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
Link: https://lkml.kernel.org/r/1397483648-26611-7-git-send-email-thomas.petazzoni@free-electrons.com
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Link: https://lkml.kernel.org/r/1397483648-26611-7-git-send-email-thomas.petazzoni@free-electrons.com
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
arch/arm/mach-mvebu/common.h
arch/arm/mach-mvebu/system-controller.c

index 2b88eb0..b67fb7a 100644 (file)
@@ -20,6 +20,7 @@
 void mvebu_restart(enum reboot_mode mode, const char *cmd);
 int mvebu_cpu_reset_deassert(int cpu);
 void mvebu_pmsu_set_cpu_boot_addr(int hw_cpu, void *boot_addr);
+void mvebu_system_controller_set_cpu_boot_addr(void *boot_addr);
 
 void armada_xp_cpu_die(unsigned int cpu);
 
index 614ba68..0c5524a 100644 (file)
@@ -37,6 +37,8 @@ struct mvebu_system_controller {
 
        u32 rstoutn_mask_reset_out_en;
        u32 system_soft_reset;
+
+       u32 resume_boot_addr;
 };
 static struct mvebu_system_controller *mvebu_sc;
 
@@ -52,6 +54,7 @@ static const struct mvebu_system_controller armada_375_system_controller = {
        .system_soft_reset_offset = 0x58,
        .rstoutn_mask_reset_out_en = 0x1,
        .system_soft_reset = 0x1,
+       .resume_boot_addr = 0xd4,
 };
 
 static const struct mvebu_system_controller orion_system_controller = {
@@ -98,6 +101,16 @@ void mvebu_restart(enum reboot_mode mode, const char *cmd)
                ;
 }
 
+#ifdef CONFIG_SMP
+void mvebu_system_controller_set_cpu_boot_addr(void *boot_addr)
+{
+       BUG_ON(system_controller_base == NULL);
+       BUG_ON(mvebu_sc->resume_boot_addr == 0);
+       writel(virt_to_phys(boot_addr), system_controller_base +
+              mvebu_sc->resume_boot_addr);
+}
+#endif
+
 static int __init mvebu_system_controller_init(void)
 {
        const struct of_device_id *match;
@@ -114,4 +127,4 @@ static int __init mvebu_system_controller_init(void)
        return 0;
 }
 
-arch_initcall(mvebu_system_controller_init);
+early_initcall(mvebu_system_controller_init);