Message ID | 1433856824-30689-2-git-send-email-peter.griffin@linaro.org |
---|---|
State | Accepted |
Commit | 94a8cfceaa7ee7e7187c5de074eb5138a6b77dcf |
Headers | show |
Hi Russell, On Tue, 09 Jun 2015, Russell King - ARM Linux wrote: > On Tue, Jun 09, 2015 at 02:33:42PM +0100, Peter Griffin wrote: > > Most upstream devs boot STi platform via JTAG which abuses the > > boot process by setting the PC of secondary cores directly. As > > a consquence, booting STi platforms via u-boot results in only > > the primary core being brought up as the code to manage the > > holding pen is not upstream. > > Looking at the current mainline code: > > static void sti_secondary_init(unsigned int cpu) > { > trace_hardirqs_off(); > > Why is this necessary? After having a dig around, the comment at the top of the file says this implementation was originally cloned from arch/arm/mach-vexpress/platsmp.c. After some googling I can see that you submitted this patch http://lists.infradead.org/pipermail/linux-arm-kernel/2010-December/033678.html which consolidated this call back in December 2010 from the platform specific secondary startup code into the common SMP code. At this time, the STi implementation was being maintained 'out of tree', so although I can't say for certain, I strongly suspect that this could be why the call is there, and that when this implementation was submitted in 2013 it was missed during the review process. > If things aren't correctly setup in generic code, > please report a bug against the generic code rather than working around > the problem in platform specific code. This is the Linux kernel, not > some closed source project. 100% agree. This is a good example of why upstreaming code is a good idea. > What bug are you seeing which required the addition of that? None that I'm aware of, however I'm not the original author or submitter of the code. I just booted several times with this call removed and everything appears to work OK. As I suspect it is due to the implementation being 'out of tree' at the time of your patch, I will submit another patch which removes this call. regards, Peter. -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/arch/arm/mach-sti/headsmp.S b/arch/arm/mach-sti/headsmp.S index 4c09bae..e0ad4517 100644 --- a/arch/arm/mach-sti/headsmp.S +++ b/arch/arm/mach-sti/headsmp.S @@ -37,6 +37,7 @@ pen: ldr r7, [r6] * should now contain the SVC stack for this core */ b secondary_startup +ENDPROC(sti_secondary_startup) 1: .long . .long pen_release diff --git a/arch/arm/mach-sti/platsmp.c b/arch/arm/mach-sti/platsmp.c index d4b624f..86bb48d8 100644 --- a/arch/arm/mach-sti/platsmp.c +++ b/arch/arm/mach-sti/platsmp.c @@ -20,6 +20,7 @@ #include <linux/io.h> #include <linux/of.h> #include <linux/of_address.h> +#include <linux/memblock.h> #include <asm/cacheflush.h> #include <asm/smp_plat.h> @@ -99,14 +100,62 @@ static int sti_boot_secondary(unsigned int cpu, struct task_struct *idle) static void __init sti_smp_prepare_cpus(unsigned int max_cpus) { - void __iomem *scu_base = NULL; - struct device_node *np = of_find_compatible_node( - NULL, NULL, "arm,cortex-a9-scu"); + struct device_node *np; + void __iomem *scu_base; + u32 __iomem *cpu_strt_ptr; + u32 release_phys; + int cpu; + unsigned long entry_pa = virt_to_phys(sti_secondary_startup); + + np = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-scu"); + if (np) { scu_base = of_iomap(np, 0); scu_enable(scu_base); of_node_put(np); } + + if (max_cpus <= 1) + return; + + for_each_possible_cpu(cpu) { + + np = of_get_cpu_node(cpu, NULL); + + if (!np) + continue; + + if (of_property_read_u32(np, "cpu-release-addr", + &release_phys)) { + pr_err("CPU %d: missing or invalid cpu-release-addr " + "property\n", cpu); + continue; + } + + /* + * holding pen is usually configured in SBC DMEM but can also be + * in RAM. + */ + + if (!memblock_is_memory(release_phys)) + cpu_strt_ptr = + ioremap(release_phys, sizeof(release_phys)); + else + cpu_strt_ptr = + (u32 __iomem *)phys_to_virt(release_phys); + + __raw_writel(entry_pa, cpu_strt_ptr); + + /* + * wmb so that data is actually written + * before cache flush is done + */ + smp_wmb(); + sync_cache_w(cpu_strt_ptr); + + if (!memblock_is_memory(release_phys)) + iounmap(cpu_strt_ptr); + } } struct smp_operations __initdata sti_smp_ops = { diff --git a/arch/arm/mach-sti/smp.h b/arch/arm/mach-sti/smp.h index 1871b72..ae22707 100644 --- a/arch/arm/mach-sti/smp.h +++ b/arch/arm/mach-sti/smp.h @@ -14,4 +14,6 @@ extern struct smp_operations sti_smp_ops; +void sti_secondary_startup(void); + #endif