Merge branch 'smp' into devel
[pandora-kernel.git] / arch / arm / mach-realview / platsmp.c
index 8fce85f..ca74217 100644 (file)
 #include <linux/errno.h>
 #include <linux/delay.h>
 #include <linux/device.h>
+#include <linux/jiffies.h>
 #include <linux/smp.h>
 #include <linux/io.h>
 
 #include <asm/cacheflush.h>
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
+#include <asm/localtimer.h>
 
 #include <mach/board-eb.h>
 #include <mach/board-pb11mp.h>
-#include <mach/scu.h>
+#include <asm/smp_scu.h>
 
 #include "core.h"
 
@@ -43,31 +45,12 @@ static void __iomem *scu_base_addr(void)
                return (void __iomem *)0;
 }
 
-static unsigned int __init get_core_count(void)
+static inline unsigned int get_core_count(void)
 {
-       unsigned int ncores;
        void __iomem *scu_base = scu_base_addr();
-
-       if (scu_base) {
-               ncores = __raw_readl(scu_base + SCU_CONFIG);
-               ncores = (ncores & 0x03) + 1;
-       } else
-               ncores = 1;
-
-       return ncores;
-}
-
-/*
- * Setup the SCU
- */
-static void scu_enable(void)
-{
-       u32 scu_ctrl;
-       void __iomem *scu_base = scu_base_addr();
-
-       scu_ctrl = __raw_readl(scu_base + SCU_CTRL);
-       scu_ctrl |= 1;
-       __raw_writel(scu_ctrl, scu_base + SCU_CTRL);
+       if (scu_base)
+               return scu_get_core_count(scu_base);
+       return 1;
 }
 
 static DEFINE_SPINLOCK(boot_lock);
@@ -76,13 +59,6 @@ void __cpuinit platform_secondary_init(unsigned int cpu)
 {
        trace_hardirqs_off();
 
-       /*
-        * the primary core may have used a "cross call" soft interrupt
-        * to get this processor out of WFI in the BootMonitor - make
-        * sure that we are no longer being sent this soft interrupt
-        */
-       smp_cross_call_done(cpumask_of_cpu(cpu));
-
        /*
         * if any interrupts are already enabled for the primary
         * core (e.g. timer irq), then they will not have been enabled
@@ -135,7 +111,7 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
         * Use smp_cross_call() for this, since there's little
         * point duplicating the code here
         */
-       smp_cross_call(cpumask_of_cpu(cpu));
+       smp_cross_call(cpumask_of(cpu));
 
        timeout = jiffies + (1 * HZ);
        while (time_before(jiffies, timeout)) {
@@ -190,7 +166,7 @@ void __init smp_init_cpus(void)
        unsigned int i, ncores = get_core_count();
 
        for (i = 0; i < ncores; i++)
-               cpu_set(i, cpu_possible_map);
+               set_cpu_possible(i, true);
 }
 
 void __init smp_prepare_cpus(unsigned int max_cpus)
@@ -223,21 +199,12 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
        if (max_cpus > ncores)
                max_cpus = ncores;
 
-#ifdef CONFIG_LOCAL_TIMERS
-       /*
-        * Enable the local timer for primary CPU. If the device is
-        * dummy (!CONFIG_LOCAL_TIMERS), it was already registers in
-        * realview_timer_init
-        */
-       local_timer_setup();
-#endif
-
        /*
         * Initialise the present map, which describes the set of CPUs
         * actually populated at the present time.
         */
        for (i = 0; i < max_cpus; i++)
-               cpu_set(i, cpu_present_map);
+               set_cpu_present(i, true);
 
        /*
         * Initialise the SCU if there are more than one CPU and let
@@ -247,7 +214,13 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
         * WFI
         */
        if (max_cpus > 1) {
-               scu_enable();
+               /*
+                * 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());
                poke_milo();
        }
 }