diff options
| -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  | 
