aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-exynos/platsmp.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-exynos/platsmp.c')
-rw-r--r--arch/arm/mach-exynos/platsmp.c32
1 files changed, 27 insertions, 5 deletions
diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c
index 95e04bd5813f..a0e8ff7758a4 100644
--- a/arch/arm/mach-exynos/platsmp.c
+++ b/arch/arm/mach-exynos/platsmp.c
@@ -24,6 +24,7 @@
24#include <asm/cacheflush.h> 24#include <asm/cacheflush.h>
25#include <asm/smp_plat.h> 25#include <asm/smp_plat.h>
26#include <asm/smp_scu.h> 26#include <asm/smp_scu.h>
27#include <asm/firmware.h>
27 28
28#include <mach/hardware.h> 29#include <mach/hardware.h>
29#include <mach/regs-clock.h> 30#include <mach/regs-clock.h>
@@ -137,10 +138,21 @@ static int __cpuinit exynos_boot_secondary(unsigned int cpu, struct task_struct
137 138
138 timeout = jiffies + (1 * HZ); 139 timeout = jiffies + (1 * HZ);
139 while (time_before(jiffies, timeout)) { 140 while (time_before(jiffies, timeout)) {
141 unsigned long boot_addr;
142
140 smp_rmb(); 143 smp_rmb();
141 144
142 __raw_writel(virt_to_phys(exynos4_secondary_startup), 145 boot_addr = virt_to_phys(exynos4_secondary_startup);
143 cpu_boot_reg(phys_cpu)); 146
147 /*
148 * Try to set boot address using firmware first
149 * and fall back to boot register if it fails.
150 */
151 if (call_firmware_op(set_cpu_boot_addr, phys_cpu, boot_addr))
152 __raw_writel(boot_addr, cpu_boot_reg(phys_cpu));
153
154 call_firmware_op(cpu_boot, phys_cpu);
155
144 arch_send_wakeup_ipi_mask(cpumask_of(cpu)); 156 arch_send_wakeup_ipi_mask(cpumask_of(cpu));
145 157
146 if (pen_release == -1) 158 if (pen_release == -1)
@@ -196,10 +208,20 @@ static void __init exynos_smp_prepare_cpus(unsigned int max_cpus)
196 * system-wide flags register. The boot monitor waits 208 * system-wide flags register. The boot monitor waits
197 * until it receives a soft interrupt, and then the 209 * until it receives a soft interrupt, and then the
198 * secondary CPU branches to this address. 210 * secondary CPU branches to this address.
211 *
212 * Try using firmware operation first and fall back to
213 * boot register if it fails.
199 */ 214 */
200 for (i = 1; i < max_cpus; ++i) 215 for (i = 1; i < max_cpus; ++i) {
201 __raw_writel(virt_to_phys(exynos4_secondary_startup), 216 unsigned long phys_cpu;
202 cpu_boot_reg(cpu_logical_map(i))); 217 unsigned long boot_addr;
218
219 phys_cpu = cpu_logical_map(i);
220 boot_addr = virt_to_phys(exynos4_secondary_startup);
221
222 if (call_firmware_op(set_cpu_boot_addr, phys_cpu, boot_addr))
223 __raw_writel(boot_addr, cpu_boot_reg(phys_cpu));
224 }
203} 225}
204 226
205struct smp_operations exynos_smp_ops __initdata = { 227struct smp_operations exynos_smp_ops __initdata = {