void platform_secondary_init(unsigned int cpu)
{
	pr_debug("CPU%u: Booted secondary processor\n", cpu);

	WARN_ON(msm_platform_secondary_init(cpu));

	/*
	 * 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);

	/*
	 * let the primary processor know we're out of the
	 * pen, then head off into the C entry point
	 */
	write_pen_release(-1);

	/* clear the IPC1(SPI-8) pending SPI */
	if (power_collapsed) {
		raise_clear_spi(1, false);
		clear_pending_spi(MSM8625_INT_ACSR_MP_CORE_IPC1);
		power_collapsed = 0;
	}

	/*
	 * Synchronise with the boot thread.
	 */
	spin_lock(&boot_lock);
	spin_unlock(&boot_lock);
}
void __cpuinit platform_secondary_init(unsigned int cpu)
{
	pr_debug("CPU%u: Booted secondary processor\n", cpu);

	WARN_ON(msm_platform_secondary_init(cpu));

	gic_secondary_init(0);

	write_pen_release(-1);

	
	if (per_cpu(power_collapsed, cpu)) {
		raise_clear_spi(cpu, false);
		clear_pending_spi(cpu_data[cpu].ipc_irq);		
		per_cpu(power_collapsed, cpu) = 0;
	}

	spin_lock(&boot_lock);
	spin_unlock(&boot_lock);
}
int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
{
	unsigned long timeout;

	preset_lpj = loops_per_jiffy;

	if (per_cpu(cold_boot_done, cpu) == false) {
		if (msm8625_release_secondary(cpu)) {
			pr_err("Failed to release core %u\n", cpu);
			return -ENODEV;
		}
		per_cpu(cold_boot_done, cpu) = true;
	}

	spin_lock(&boot_lock);

	write_pen_release(cpu);


	if (per_cpu(power_collapsed, cpu)) {
		gic_configure_and_raise(cpu_data[cpu].ipc_irq, cpu);
		raise_clear_spi(cpu, true);
	} else {
		gic_raise_softirq(cpumask_of(cpu), 1);
	}

	timeout = jiffies + (1 * HZ);
	while (time_before(jiffies, timeout)) {
		smp_rmb();
		if (pen_release == -1)
			break;

		udelay(10);
	}

	spin_unlock(&boot_lock);

	return 0;
}
Exemple #4
0
void __cpuinit msm8625_platform_secondary_init(unsigned int cpu)
{
	WARN_ON(msm_platform_secondary_init(cpu));

	/*
	 * let the primary processor know we're out of the
	 * pen, then head off into the C entry point
	 */
	write_pen_release(-1);

	/* clear the IPC pending SPI */
	if (per_cpu(power_collapsed, cpu)) {
		raise_clear_spi(cpu, false);
		clear_pending_spi(cpu_data[cpu].ipc_irq);
		per_cpu(power_collapsed, cpu) = 0;
	}

	/*
	 * Synchronise with the boot thread.
	 */
	spin_lock(&boot_lock);
	spin_unlock(&boot_lock);
}
Exemple #5
0
int __cpuinit msm8625_boot_secondary(unsigned int cpu, struct task_struct *idle)
{
	unsigned long timeout;

	preset_lpj = loops_per_jiffy;

	if (per_cpu(cold_boot_done, cpu) == false) {
		if (msm8625_release_secondary(cpu)) {
			pr_err("Failed to release core %u\n", cpu);
			return -ENODEV;
		}
		per_cpu(cold_boot_done, cpu) = true;
	}

	/*
	 * Set synchronisation state between this boot processor
	 * and the secondary one
	 */
	spin_lock(&boot_lock);

	/*
	 * This is really belt and braces; we hold unintended secondary
	 * CPUs in the holding pen until we're ready for them.  However,
	 * since we haven't sent them a soft interrupt, they shouldn't
	 * be there.
	 */
	write_pen_release(cpu);

	/*
	 * Send the secondary CPU a soft interrupt, thereby causing
	 * the boot monitor to read the system wide flags register,
	 * and branch to the address found there.
	 *
	 * power_collapsed is the flag which will be updated for Powercollapse.
	 * Once we are out of PC, as secondary cores will be in the state of
	 * GDFS which needs to be brought out by raising an SPI.
	 */

	if (per_cpu(power_collapsed, cpu)) {
		gic_configure_and_raise(cpu_data[cpu].ipc_irq, cpu);
		raise_clear_spi(cpu, true);
	} else {
		gic_raise_softirq(cpumask_of(cpu), 1);
	}

	timeout = jiffies + (1 * HZ);
	while (time_before(jiffies, timeout)) {
		smp_rmb();
		if (pen_release == -1)
			break;

		udelay(10);
	}

	/*
	 * now the secondary core is starting up let it run its
	 * calibrations, then wait for it to finish
	 */
	spin_unlock(&boot_lock);

	return 0;
}