diff options
Diffstat (limited to 'arch/arm/mach-mstar')
-rw-r--r-- | arch/arm/mach-mstar/mstarv7.c | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/arch/arm/mach-mstar/mstarv7.c b/arch/arm/mach-mstar/mstarv7.c index 1aa748fa006e..274c4f0df270 100644 --- a/arch/arm/mach-mstar/mstarv7.c +++ b/arch/arm/mach-mstar/mstarv7.c @@ -31,6 +31,13 @@ #define MSTARV7_L3BRIDGE_FLUSH_TRIGGER BIT(0) #define MSTARV7_L3BRIDGE_STATUS_DONE BIT(12) +#ifdef CONFIG_SMP +#define MSTARV7_CPU1_BOOT_ADDR_HIGH 0x4c +#define MSTARV7_CPU1_BOOT_ADDR_LOW 0x50 +#define MSTARV7_CPU1_UNLOCK 0x58 +#define MSTARV7_CPU1_UNLOCK_MAGIC 0xbabe +#endif + static void __iomem *l3bridge; static const char * const mstarv7_board_dt_compat[] __initconst = { @@ -63,6 +70,46 @@ static void mstarv7_mb(void) } } +#ifdef CONFIG_SMP +static int mstarv7_boot_secondary(unsigned int cpu, struct task_struct *idle) +{ + struct device_node *np; + u32 bootaddr = (u32) __pa_symbol(secondary_startup_arm); + void __iomem *smpctrl; + + /* + * right now we don't know how to boot anything except + * cpu 1. + */ + if (cpu != 1) + return -EINVAL; + + np = of_find_compatible_node(NULL, NULL, "mstar,smpctrl"); + smpctrl = of_iomap(np, 0); + + if (!smpctrl) + return -ENODEV; + + /* set the boot address for the second cpu */ + writew(bootaddr & 0xffff, smpctrl + MSTARV7_CPU1_BOOT_ADDR_LOW); + writew((bootaddr >> 16) & 0xffff, smpctrl + MSTARV7_CPU1_BOOT_ADDR_HIGH); + + /* unlock the second cpu */ + writew(MSTARV7_CPU1_UNLOCK_MAGIC, smpctrl + MSTARV7_CPU1_UNLOCK); + + /* and away we go...*/ + arch_send_wakeup_ipi_mask(cpumask_of(cpu)); + + iounmap(smpctrl); + + return 0; +} + +static const struct smp_operations __initdata mstarv7_smp_ops = { + .smp_boot_secondary = mstarv7_boot_secondary, +}; +#endif + static void __init mstarv7_init(void) { struct device_node *np; @@ -78,4 +125,5 @@ static void __init mstarv7_init(void) DT_MACHINE_START(MSTARV7_DT, "MStar/Sigmastar Armv7 (Device Tree)") .dt_compat = mstarv7_board_dt_compat, .init_machine = mstarv7_init, + .smp = smp_ops(mstarv7_smp_ops), MACHINE_END |