summaryrefslogtreecommitdiff
path: root/arch/arm/mach-s5pv310/platsmp.c
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2011-01-06 22:32:52 +0000
committerRussell King <rmk+kernel@arm.linux.org.uk>2011-01-06 22:32:52 +0000
commit4073723acb9cdcdbe4df9c0e0c376c65d1697e43 (patch)
treef41c17eac157b1223ce104845cf9b1e5a9e6a83d /arch/arm/mach-s5pv310/platsmp.c
parent58daf18cdcab550262a5f4681e1f1e073e21965a (diff)
parent4ec3eb13634529c0bc7466658d84d0bbe3244aea (diff)
Merge branch 'misc' into devel
Conflicts: arch/arm/Kconfig arch/arm/common/Makefile arch/arm/kernel/Makefile arch/arm/kernel/smp.c
Diffstat (limited to 'arch/arm/mach-s5pv310/platsmp.c')
-rw-r--r--arch/arm/mach-s5pv310/platsmp.c66
1 files changed, 23 insertions, 43 deletions
diff --git a/arch/arm/mach-s5pv310/platsmp.c b/arch/arm/mach-s5pv310/platsmp.c
index 15929c169f81..34093b069f67 100644
--- a/arch/arm/mach-s5pv310/platsmp.c
+++ b/arch/arm/mach-s5pv310/platsmp.c
@@ -22,7 +22,6 @@
#include <linux/io.h>
#include <asm/cacheflush.h>
-#include <asm/localtimer.h>
#include <asm/smp_scu.h>
#include <asm/unified.h>
@@ -38,6 +37,19 @@ extern void s5pv310_secondary_startup(void);
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 void __iomem *scu_base_addr(void)
{
return (void __iomem *)(S5P_VA_SCU);
@@ -47,8 +59,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
@@ -60,8 +70,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;
- smp_wmb();
+ write_pen_release(-1);
/*
* Synchronise with the boot thread.
@@ -88,16 +97,14 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
* Note that "pen_release" is the hardware CPU ID, whereas
* "cpu" is Linux's internal ID.
*/
- 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);
/*
* 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.
*/
- smp_cross_call(cpumask_of(cpu));
+ smp_cross_call(cpumask_of(cpu), 1);
timeout = jiffies + (1 * HZ);
while (time_before(jiffies, timeout)) {
@@ -130,13 +137,6 @@ void __init smp_init_cpus(void)
ncores = scu_base ? scu_get_core_count(scu_base) : 1;
/* sanity check */
- if (ncores == 0) {
- printk(KERN_ERR
- "S5PV310: strange CM count of 0? Default to 1\n");
-
- ncores = 1;
- }
-
if (ncores > NR_CPUS) {
printk(KERN_WARNING
"S5PV310: no. of cores (%d) greater than configured "
@@ -149,18 +149,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.
@@ -168,25 +160,13 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
for (i = 0; i < max_cpus; i++)
set_cpu_present(i, true);
+ scu_enable(scu_base_addr());
+
/*
- * Initialise the SCU if there are more than one CPU and let
- * them know where to start.
+ * Write the address of secondary startup into the
+ * system-wide flags register. The boot monitor waits
+ * until it receives a soft interrupt, and then the
+ * secondary CPU branches to this address.
*/
- 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(scu_base_addr());
-
- /*
- * Write the address of secondary startup into the
- * system-wide flags register. The boot monitor waits
- * until it receives a soft interrupt, and then the
- * secondary CPU branches to this address.
- */
__raw_writel(BSYM(virt_to_phys(s5pv310_secondary_startup)), S5P_VA_SYSRAM);
- }
}