From 1924534671318e9c426d8705afea385072c8c18b Mon Sep 17 00:00:00 2001 From: Tomasz Figa Date: Tue, 11 Dec 2012 13:58:43 +0900 Subject: [PATCH] --- yaml --- r: 372663 b: refs/heads/master c: beddf63fc8e01f06799bd6d7a2dd879885bbc9c6 h: refs/heads/master i: 372661: ed447d946b785fc08f1728f9a3d2f5e0f72b983d 372659: fcdeda067a2766131ab4a6b3ab1ec57706c384e0 372655: 1b18a560385a51a7c338ecc3961005ca07fa0b11 v: v3 --- [refs] | 2 +- trunk/arch/arm/mach-exynos/platsmp.c | 32 +++++++++++++++++++++++----- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/[refs] b/[refs] index c7119bf5aefd..f0c623ae0474 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 41de89860baf8e62fd74e83338058575398ad21f +refs/heads/master: beddf63fc8e01f06799bd6d7a2dd879885bbc9c6 diff --git a/trunk/arch/arm/mach-exynos/platsmp.c b/trunk/arch/arm/mach-exynos/platsmp.c index 60f7c5be057d..a083e0591a56 100644 --- a/trunk/arch/arm/mach-exynos/platsmp.c +++ b/trunk/arch/arm/mach-exynos/platsmp.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -145,10 +146,21 @@ static int __cpuinit exynos_boot_secondary(unsigned int cpu, struct task_struct timeout = jiffies + (1 * HZ); while (time_before(jiffies, timeout)) { + unsigned long boot_addr; + smp_rmb(); - __raw_writel(virt_to_phys(exynos4_secondary_startup), - cpu_boot_reg(phys_cpu)); + boot_addr = virt_to_phys(exynos4_secondary_startup); + + /* + * Try to set boot address using firmware first + * and fall back to boot register if it fails. + */ + if (call_firmware_op(set_cpu_boot_addr, phys_cpu, boot_addr)) + __raw_writel(boot_addr, cpu_boot_reg(phys_cpu)); + + call_firmware_op(cpu_boot, phys_cpu); + arch_send_wakeup_ipi_mask(cpumask_of(cpu)); if (pen_release == -1) @@ -204,10 +216,20 @@ static void __init exynos_smp_prepare_cpus(unsigned int max_cpus) * system-wide flags register. The boot monitor waits * until it receives a soft interrupt, and then the * secondary CPU branches to this address. + * + * Try using firmware operation first and fall back to + * boot register if it fails. */ - for (i = 1; i < max_cpus; ++i) - __raw_writel(virt_to_phys(exynos4_secondary_startup), - cpu_boot_reg(cpu_logical_map(i))); + for (i = 1; i < max_cpus; ++i) { + unsigned long phys_cpu; + unsigned long boot_addr; + + phys_cpu = cpu_logical_map(i); + boot_addr = virt_to_phys(exynos4_secondary_startup); + + if (call_firmware_op(set_cpu_boot_addr, phys_cpu, boot_addr)) + __raw_writel(boot_addr, cpu_boot_reg(phys_cpu)); + } } struct smp_operations exynos_smp_ops __initdata = {