diff options
Diffstat (limited to 'arch/arm/mach-omap2/omap-smp.c')
| -rw-r--r-- | arch/arm/mach-omap2/omap-smp.c | 86 | 
1 files changed, 34 insertions, 52 deletions
diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c index cd42d921940..2a551f997ae 100644 --- a/arch/arm/mach-omap2/omap-smp.c +++ b/arch/arm/mach-omap2/omap-smp.c @@ -19,9 +19,8 @@  #include <linux/device.h>  #include <linux/smp.h>  #include <linux/io.h> +#include <linux/irqchip/arm-gic.h> -#include <asm/cacheflush.h> -#include <asm/hardware/gic.h>  #include <asm/smp_scu.h>  #include "omap-secure.h" @@ -67,13 +66,6 @@ static void __cpuinit omap4_secondary_init(unsigned int cpu)  							4, 0, 0, 0, 0, 0);  	/* -	 * If any interrupts are already enabled for the primary -	 * core (e.g. timer irq), then they will not have been enabled -	 * for us: do so -	 */ -	gic_secondary_init(0); - -	/*  	 * Synchronise with the boot thread.  	 */  	spin_lock(&boot_lock); @@ -84,6 +76,7 @@ static int __cpuinit omap4_boot_secondary(unsigned int cpu, struct task_struct *  {  	static struct clockdomain *cpu1_clkdm;  	static bool booted; +	static struct powerdomain *cpu1_pwrdm;  	void __iomem *base = omap_get_wakeupgen_base();  	/* @@ -103,11 +96,10 @@ static int __cpuinit omap4_boot_secondary(unsigned int cpu, struct task_struct *  	else  		__raw_writel(0x20, base + OMAP_AUX_CORE_BOOT_0); -	flush_cache_all(); -	smp_wmb(); - -	if (!cpu1_clkdm) +	if (!cpu1_clkdm && !cpu1_pwrdm) {  		cpu1_clkdm = clkdm_lookup("mpu1_clkdm"); +		cpu1_pwrdm = pwrdm_lookup("cpu1_pwrdm"); +	}  	/*  	 * The SGI(Software Generated Interrupts) are not wakeup capable @@ -120,7 +112,7 @@ static int __cpuinit omap4_boot_secondary(unsigned int cpu, struct task_struct *  	 * Section :  	 *	4.3.4.2 Power States of CPU0 and CPU1  	 */ -	if (booted) { +	if (booted && cpu1_pwrdm && cpu1_clkdm) {  		/*  		 * GIC distributor control register has changed between  		 * CortexA9 r1pX and r2pX. The Control Register secure @@ -141,7 +133,12 @@ static int __cpuinit omap4_boot_secondary(unsigned int cpu, struct task_struct *  			gic_dist_disable();  		} +		/* +		 * Ensure that CPU power state is set to ON to avoid CPU +		 * powerdomain transition on wfi +		 */  		clkdm_wakeup(cpu1_clkdm); +		omap_set_pwrdm_state(cpu1_pwrdm, PWRDM_POWER_ON);  		clkdm_allow_idle(cpu1_clkdm);  		if (IS_PM44XX_ERRATUM(PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD)) { @@ -157,7 +154,7 @@ static int __cpuinit omap4_boot_secondary(unsigned int cpu, struct task_struct *  		booted = true;  	} -	gic_raise_softirq(cpumask_of(cpu), 0); +	arch_send_wakeup_ipi_mask(cpumask_of(cpu));  	/*  	 * Now the secondary core is starting up let it run its @@ -168,38 +165,6 @@ static int __cpuinit omap4_boot_secondary(unsigned int cpu, struct task_struct *  	return 0;  } -static void __init wakeup_secondary(void) -{ -	void *startup_addr = omap_secondary_startup; -	void __iomem *base = omap_get_wakeupgen_base(); - -	if (cpu_is_omap446x()) { -		startup_addr = omap_secondary_startup_4460; -		pm44xx_errata |= PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD; -	} - -	/* -	 * Write the address of secondary startup routine into the -	 * AuxCoreBoot1 where ROM code will jump and start executing -	 * on secondary core once out of WFE -	 * A barrier is added to ensure that write buffer is drained -	 */ -	if (omap_secure_apis_support()) -		omap_auxcoreboot_addr(virt_to_phys(startup_addr)); -	else -		__raw_writel(virt_to_phys(omap5_secondary_startup), -						base + OMAP_AUX_CORE_BOOT_1); - -	smp_wmb(); - -	/* -	 * Send a 'sev' to wake the secondary core from WFE. -	 * Drain the outstanding writes to memory -	 */ -	dsb_sev(); -	mb(); -} -  /*   * Initialise the CPU possible map early - this describes the CPUs   * which may be present or become present in the system. @@ -209,13 +174,13 @@ static void __init omap4_smp_init_cpus(void)  	unsigned int i = 0, ncores = 1, cpu_id;  	/* Use ARM cpuid check here, as SoC detection will not work so early */ -	cpu_id = read_cpuid(CPUID_ID) & CPU_MASK; +	cpu_id = read_cpuid_id() & CPU_MASK;  	if (cpu_id == CPU_CORTEX_A9) {  		/*  		 * Currently we can't call ioremap here because  		 * SoC detection won't work until after init_early.  		 */ -		scu_base =  OMAP2_L4_IO_ADDRESS(OMAP44XX_SCU_BASE); +		scu_base =  OMAP2_L4_IO_ADDRESS(scu_a9_get_base());  		BUG_ON(!scu_base);  		ncores = scu_get_core_count(scu_base);  	} else if (cpu_id == CPU_CORTEX_A15) { @@ -231,12 +196,12 @@ static void __init omap4_smp_init_cpus(void)  	for (i = 0; i < ncores; i++)  		set_cpu_possible(i, true); - -	set_smp_cross_call(gic_raise_softirq);  }  static void __init omap4_smp_prepare_cpus(unsigned int max_cpus)  { +	void *startup_addr = omap_secondary_startup; +	void __iomem *base = omap_get_wakeupgen_base();  	/*  	 * Initialise the SCU and wake up the secondary core using @@ -244,7 +209,24 @@ static void __init omap4_smp_prepare_cpus(unsigned int max_cpus)  	 */  	if (scu_base)  		scu_enable(scu_base); -	wakeup_secondary(); + +	if (cpu_is_omap446x()) { +		startup_addr = omap_secondary_startup_4460; +		pm44xx_errata |= PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD; +	} + +	/* +	 * Write the address of secondary startup routine into the +	 * AuxCoreBoot1 where ROM code will jump and start executing +	 * on secondary core once out of WFE +	 * A barrier is added to ensure that write buffer is drained +	 */ +	if (omap_secure_apis_support()) +		omap_auxcoreboot_addr(virt_to_phys(startup_addr)); +	else +		__raw_writel(virt_to_phys(omap5_secondary_startup), +						base + OMAP_AUX_CORE_BOOT_1); +  }  struct smp_operations omap4_smp_ops __initdata = {  |