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; }
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); }
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; }