From 6d803ba736abb5e122dede70a4720e4843dd6df4 Mon Sep 17 00:00:00 2001 From: Jean-Christop PLAGNIOL-VILLARD Date: Wed, 17 Nov 2010 10:04:33 +0100 Subject: ARM: 6483/1: arm & sh: factorised duplicated clkdev.c factorise some generic infrastructure to assist looking up struct clks for the ARM & SH architecture. as the code is identical at 99% put the arch specific code for allocation as example in asm/clkdev.h Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Acked-by: Paul Mundt Signed-off-by: Russell King --- arch/arm/mach-ux500/clock.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'arch/arm/mach-ux500') diff --git a/arch/arm/mach-ux500/clock.c b/arch/arm/mach-ux500/clock.c index 1675047daf20..531de5c63641 100644 --- a/arch/arm/mach-ux500/clock.c +++ b/arch/arm/mach-ux500/clock.c @@ -13,8 +13,7 @@ #include #include #include - -#include +#include #include #include -- cgit v1.2.3 From ad3b6993b9c5482e8a2ec5aed181538c921fdcbd Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 15 Nov 2010 09:42:08 +0000 Subject: ARM: SMP: pass an ipi number to smp_cross_call() This allows us to use smp_cross_call() to trigger a number of different software generated interrupts, rather than combining them all on one SGI. Recover the SGI number via do_IPI. Reviewed-by: Catalin Marinas Signed-off-by: Russell King --- arch/arm/mach-ux500/include/mach/smp.h | 4 ++-- arch/arm/mach-ux500/platsmp.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'arch/arm/mach-ux500') diff --git a/arch/arm/mach-ux500/include/mach/smp.h b/arch/arm/mach-ux500/include/mach/smp.h index 197e8417375e..bd57c50a5b86 100644 --- a/arch/arm/mach-ux500/include/mach/smp.h +++ b/arch/arm/mach-ux500/include/mach/smp.h @@ -18,8 +18,8 @@ extern void u8500_secondary_startup(void); /* * We use IRQ1 as the IPI */ -static inline void smp_cross_call(const struct cpumask *mask) +static inline void smp_cross_call(const struct cpumask *mask, int ipi) { - gic_raise_softirq(mask, 1); + gic_raise_softirq(mask, ipi); } #endif diff --git a/arch/arm/mach-ux500/platsmp.c b/arch/arm/mach-ux500/platsmp.c index 9e4c678de785..b8987bd21249 100644 --- a/arch/arm/mach-ux500/platsmp.c +++ b/arch/arm/mach-ux500/platsmp.c @@ -78,7 +78,7 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release)); outer_clean_range(__pa(&pen_release), __pa(&pen_release) + 1); - smp_cross_call(cpumask_of(cpu)); + smp_cross_call(cpumask_of(cpu), 1); timeout = jiffies + (1 * HZ); while (time_before(jiffies, timeout)) { -- cgit v1.2.3 From bbc3d14e9aca023bb98e580aa1c9350af8effdb1 Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 3 Dec 2010 10:42:58 +0000 Subject: ARM: SMP: move CPU number sanity checks to smp_init_cpus() Ensure that the number of CPUs is sanity checked before setting the number of possible CPUs. This avoids any chance of overflowing the cpu_possible bitmap. Signed-off-by: Russell King --- arch/arm/mach-ux500/platsmp.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'arch/arm/mach-ux500') diff --git a/arch/arm/mach-ux500/platsmp.c b/arch/arm/mach-ux500/platsmp.c index b8987bd21249..a51962b7579b 100644 --- a/arch/arm/mach-ux500/platsmp.c +++ b/arch/arm/mach-ux500/platsmp.c @@ -128,16 +128,6 @@ void __init smp_init_cpus(void) { unsigned int i, ncores = get_core_count(); - for (i = 0; i < ncores; i++) - set_cpu_possible(i, true); -} - -void __init smp_prepare_cpus(unsigned int max_cpus) -{ - unsigned int ncores = get_core_count(); - unsigned int cpu = smp_processor_id(); - int i; - /* sanity check */ if (ncores == 0) { printk(KERN_ERR @@ -145,14 +135,24 @@ void __init smp_prepare_cpus(unsigned int max_cpus) ncores = 1; } - if (ncores > num_possible_cpus()) { + if (ncores > NR_CPUS) { printk(KERN_WARNING "U8500: no. of cores (%d) greater than configured " "maximum of %d - clipping\n", - ncores, num_possible_cpus()); - ncores = num_possible_cpus(); + ncores, NR_CPUS); + ncores = NR_CPUS; } + for (i = 0; i < ncores; i++) + set_cpu_possible(i, true); +} + +void __init smp_prepare_cpus(unsigned int max_cpus) +{ + unsigned int ncores = num_possible_cpus(); + unsigned int cpu = smp_processor_id(); + int i; + smp_store_cpu_info(cpu); /* -- cgit v1.2.3 From 8975b6c0fdd57e061f4d1040163778ceaf340ad8 Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 3 Dec 2010 19:29:53 +0000 Subject: ARM: SMP: Clean up ncores sanity checks scu_get_core_count() never returns zero cores, so we don't need to check and correct if ncores is zero. Tegra was missing the check against NR_CPUS, leading to a potential bitfield overflow if this becomes the case. Signed-off-by: Russell King --- arch/arm/mach-ux500/platsmp.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'arch/arm/mach-ux500') diff --git a/arch/arm/mach-ux500/platsmp.c b/arch/arm/mach-ux500/platsmp.c index a51962b7579b..e31024e3a7cc 100644 --- a/arch/arm/mach-ux500/platsmp.c +++ b/arch/arm/mach-ux500/platsmp.c @@ -129,12 +129,6 @@ void __init smp_init_cpus(void) unsigned int i, ncores = get_core_count(); /* sanity check */ - if (ncores == 0) { - printk(KERN_ERR - "U8500: strange CM count of 0? Default to 1\n"); - ncores = 1; - } - if (ncores > NR_CPUS) { printk(KERN_WARNING "U8500: no. of cores (%d) greater than configured " -- cgit v1.2.3 From fd778f0ad7dda1108281410ddca0d07936256d3c Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 2 Dec 2010 18:09:37 +0000 Subject: ARM: SMP: get rid of get_core_count() We don't need this small function as well as scu_get_core_count() Signed-off-by: Russell King --- arch/arm/mach-ux500/platsmp.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'arch/arm/mach-ux500') diff --git a/arch/arm/mach-ux500/platsmp.c b/arch/arm/mach-ux500/platsmp.c index e31024e3a7cc..fd40fa175913 100644 --- a/arch/arm/mach-ux500/platsmp.c +++ b/arch/arm/mach-ux500/platsmp.c @@ -28,11 +28,6 @@ */ volatile int __cpuinitdata pen_release = -1; -static unsigned int __init get_core_count(void) -{ - return scu_get_core_count(__io_address(UX500_SCU_BASE)); -} - static DEFINE_SPINLOCK(boot_lock); void __cpuinit platform_secondary_init(unsigned int cpu) @@ -126,7 +121,9 @@ static void __init wakeup_secondary(void) */ void __init smp_init_cpus(void) { - unsigned int i, ncores = get_core_count(); + unsigned int i, ncores; + + ncores = scu_get_core_count(__io_address(UX500_SCU_BASE)); /* sanity check */ if (ncores > NR_CPUS) { -- cgit v1.2.3 From 05c74a6cbcfb416286a947668ba32f63d99fe74a Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 3 Dec 2010 11:09:48 +0000 Subject: ARM: SMP: consolidate the common parts of smp_prepare_cpus() There is a certain amount of smp_prepare_cpus() which doesn't belong in the platform support code - that is, code which is invariant to the SMP implementation. Move this code into arch/arm/kernel/smp.c, and add a platform_ prefix to the original function. Signed-off-by: Russell King --- arch/arm/mach-ux500/platsmp.c | 24 +++--------------------- 1 file changed, 3 insertions(+), 21 deletions(-) (limited to 'arch/arm/mach-ux500') diff --git a/arch/arm/mach-ux500/platsmp.c b/arch/arm/mach-ux500/platsmp.c index fd40fa175913..458a288981cb 100644 --- a/arch/arm/mach-ux500/platsmp.c +++ b/arch/arm/mach-ux500/platsmp.c @@ -18,7 +18,6 @@ #include #include -#include #include #include @@ -138,20 +137,10 @@ void __init smp_init_cpus(void) set_cpu_possible(i, true); } -void __init smp_prepare_cpus(unsigned int max_cpus) +void __init platform_smp_prepare_cpus(unsigned int max_cpus) { - unsigned int ncores = num_possible_cpus(); - unsigned int cpu = smp_processor_id(); int i; - smp_store_cpu_info(cpu); - - /* - * are we trying to boot more cores than exist? - */ - if (max_cpus > ncores) - max_cpus = ncores; - /* * Initialise the present map, which describes the set of CPUs * actually populated at the present time. @@ -159,13 +148,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus) for (i = 0; i < max_cpus; i++) set_cpu_present(i, true); - if (max_cpus > 1) { - /* - * Enable the local timer or broadcast device for the - * boot CPU, but only if we have more than one CPU. - */ - percpu_timer_setup(); - scu_enable(__io_address(UX500_SCU_BASE)); - wakeup_secondary(); - } + scu_enable(__io_address(UX500_SCU_BASE)); + wakeup_secondary(); } -- cgit v1.2.3 From 2c0136dba4e43b0916ccc9ecc7f11e6d6b73f046 Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 3 Dec 2010 15:00:49 +0000 Subject: ARM: SMP: consolidate trace_hardirqs_off() into common SMP code All platforms call trace_hardirqs_off() in their secondary startup code, so move this into the core SMP code - it doesn't need to be in the per-platform code. Signed-off-by: Russell King --- arch/arm/mach-ux500/platsmp.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'arch/arm/mach-ux500') diff --git a/arch/arm/mach-ux500/platsmp.c b/arch/arm/mach-ux500/platsmp.c index 458a288981cb..ddedbc80c41f 100644 --- a/arch/arm/mach-ux500/platsmp.c +++ b/arch/arm/mach-ux500/platsmp.c @@ -31,8 +31,6 @@ static DEFINE_SPINLOCK(boot_lock); void __cpuinit platform_secondary_init(unsigned int cpu) { - trace_hardirqs_off(); - /* * if any interrupts are already enabled for the primary * core (e.g. timer irq), then they will not have been enabled -- cgit v1.2.3 From 3c030beabf937b1d3b4ecaedfd1fb2f1e2aa0c70 Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 30 Nov 2010 11:07:35 +0000 Subject: ARM: CPU hotplug: move cpu_killed completion to core code We always need to wait for the dying CPU to reach a safe state before taking it down, irrespective of the requirements of the platform. Move the completion code into the ARM SMP hotplug code rather than having each platform re-implement this. Signed-off-by: Russell King --- arch/arm/mach-ux500/hotplug.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'arch/arm/mach-ux500') diff --git a/arch/arm/mach-ux500/hotplug.c b/arch/arm/mach-ux500/hotplug.c index b782a03024be..7a4890b96e5c 100644 --- a/arch/arm/mach-ux500/hotplug.c +++ b/arch/arm/mach-ux500/hotplug.c @@ -11,14 +11,11 @@ #include #include #include -#include #include extern volatile int pen_release; -static DECLARE_COMPLETION(cpu_killed); - static inline void platform_do_lowpower(unsigned int cpu) { flush_cache_all(); @@ -38,7 +35,7 @@ static inline void platform_do_lowpower(unsigned int cpu) int platform_cpu_kill(unsigned int cpu) { - return wait_for_completion_timeout(&cpu_killed, 5000); + return 1; } /* @@ -58,9 +55,6 @@ void platform_cpu_die(unsigned int cpu) } #endif - printk(KERN_NOTICE "CPU%u: shutdown\n", cpu); - complete(&cpu_killed); - /* directly enter low power state, skipping secure registers */ platform_do_lowpower(cpu); } -- cgit v1.2.3 From bbc81fd4327f9ed4480b05981e38acd48b1d184a Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 30 Nov 2010 11:12:30 +0000 Subject: ARM: CPU hotplug: remove bug checks in platform_cpu_die() platform_cpu_die() is entered from the CPU's own idle thread, which can not be migrated to other CPUs. Moreover, the 'cpu' argument comes from the thread info, which will always be the 'current' CPU. So remove this useless bug check. Signed-off-by: Russell King --- arch/arm/mach-ux500/hotplug.c | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'arch/arm/mach-ux500') diff --git a/arch/arm/mach-ux500/hotplug.c b/arch/arm/mach-ux500/hotplug.c index 7a4890b96e5c..dd8037ebccf8 100644 --- a/arch/arm/mach-ux500/hotplug.c +++ b/arch/arm/mach-ux500/hotplug.c @@ -45,16 +45,6 @@ int platform_cpu_kill(unsigned int cpu) */ void platform_cpu_die(unsigned int cpu) { -#ifdef DEBUG - unsigned int this_cpu = hard_smp_processor_id(); - - if (cpu != this_cpu) { - printk(KERN_CRIT "Eek! platform_cpu_die running on %u, should be %u\n", - this_cpu, cpu); - BUG(); - } -#endif - /* directly enter low power state, skipping secure registers */ platform_do_lowpower(cpu); } -- cgit v1.2.3 From 86e62b93368cffca9111996e3ed9e5b7bf6f0af3 Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 30 Nov 2010 18:24:57 +0000 Subject: ARM: SMP: remove smp_mpidr.h With "ARM: CPU hotplug: remove bug checks in platform_cpu_die()", we now do not use hard_smp_processor_id(), we no longer need to read the hardware processor ID. Remove the include providing this function. Signed-off-by: Russell King --- arch/arm/mach-ux500/include/mach/smp.h | 1 - 1 file changed, 1 deletion(-) (limited to 'arch/arm/mach-ux500') diff --git a/arch/arm/mach-ux500/include/mach/smp.h b/arch/arm/mach-ux500/include/mach/smp.h index bd57c50a5b86..ca2b15b1b3b1 100644 --- a/arch/arm/mach-ux500/include/mach/smp.h +++ b/arch/arm/mach-ux500/include/mach/smp.h @@ -10,7 +10,6 @@ #define ASMARM_ARCH_SMP_H #include -#include /* This is required to wakeup the secondary core */ extern void u8500_secondary_startup(void); -- cgit v1.2.3 From 3705ff6da538aff6dba535e2e9cbcbb9456d0d53 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 18 Dec 2010 10:53:12 +0000 Subject: ARM: Fix subtle race in CPU pen_release hotplug code There is a subtle race in the CPU hotplug code, where a CPU which has been offlined can online itself before being requested, which results in things going astray on the next online/offline cycle. What happens in the normal online/offline/online cycle is: CPU0 CPU3 requests boot of CPU3 pen_release = 3 flush cache line checks pen_release, reads 3 starts boot pen_release = -1 ... requests CPU3 offline ... ... dies ... checks pen_release, reads -1 requests boot of CPU3 pen_release = 3 flush cache line checks pen_release, reads 3 starts boot pen_release = -1 However, as the write of -1 of pen_release is not fully flushed back to memory, and the checking of pen_release is done with caches disabled, this allows CPU3 the opportunity to read the old value of pen_release: CPU0 CPU3 requests boot of CPU3 pen_release = 3 flush cache line checks pen_release, reads 3 starts boot pen_release = -1 ... requests CPU3 offline ... ... dies ... checks pen_release, reads 3 starts boot pen_release = -1 requests boot of CPU3 pen_release = 3 flush cache line Fix this by grouping the write of pen_release along with its cache line flushing code to ensure that any update to pen_release is always pushed out to physical memory. Signed-off-by: Russell King --- arch/arm/mach-ux500/platsmp.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) (limited to 'arch/arm/mach-ux500') diff --git a/arch/arm/mach-ux500/platsmp.c b/arch/arm/mach-ux500/platsmp.c index ddedbc80c41f..f71175a766d7 100644 --- a/arch/arm/mach-ux500/platsmp.c +++ b/arch/arm/mach-ux500/platsmp.c @@ -27,6 +27,19 @@ */ volatile int __cpuinitdata pen_release = -1; +/* + * Write pen_release in a way that is guaranteed to be visible to all + * observers, irrespective of whether they're taking part in coherency + * or not. This is necessary for the hotplug code to work reliably. + */ +static void write_pen_release(int val) +{ + pen_release = val; + smp_wmb(); + __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release)); + outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1)); +} + static DEFINE_SPINLOCK(boot_lock); void __cpuinit platform_secondary_init(unsigned int cpu) @@ -42,7 +55,7 @@ void __cpuinit platform_secondary_init(unsigned int cpu) * let the primary processor know we're out of the * pen, then head off into the C entry point */ - pen_release = -1; + write_pen_release(-1); /* * Synchronise with the boot thread. @@ -66,9 +79,7 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) * the holding pen - release it, then wait for it to flag * that it has been released by resetting pen_release. */ - pen_release = cpu; - __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release)); - outer_clean_range(__pa(&pen_release), __pa(&pen_release) + 1); + write_pen_release(cpu); smp_cross_call(cpumask_of(cpu), 1); @@ -89,9 +100,6 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) static void __init wakeup_secondary(void) { - /* nobody is to be released from the pen yet */ - pen_release = -1; - /* * write the address of secondary startup into the backup ram register * at offset 0x1FF4, then write the magic number 0xA1FEED01 to the -- cgit v1.2.3 From 78368c79944b12f91bcacb0b0b030c36016264e8 Mon Sep 17 00:00:00 2001 From: Srinidhi Kasagar Date: Wed, 22 Dec 2010 13:18:58 +0100 Subject: ARM: 6539/1: ux500: remove unnecessary barrier from the secondary startup Signed-off-by: srinidhi kasagar Acked-by: Linus Walleij Signed-off-by: Russell King --- arch/arm/mach-ux500/headsmp.S | 1 - 1 file changed, 1 deletion(-) (limited to 'arch/arm/mach-ux500') diff --git a/arch/arm/mach-ux500/headsmp.S b/arch/arm/mach-ux500/headsmp.S index a6be2cdf2b2f..64fa451edcfd 100644 --- a/arch/arm/mach-ux500/headsmp.S +++ b/arch/arm/mach-ux500/headsmp.S @@ -23,7 +23,6 @@ ENTRY(u8500_secondary_startup) ldmia r4, {r5, r6} sub r4, r4, r5 add r6, r6, r4 - dsb pen: ldr r7, [r6] cmp r7, r0 bne pen -- cgit v1.2.3