+obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/headsmp.S
-@@ -0,0 +1,43 @@
+@@ -0,0 +1,42 @@
+/*
+ * linux/arch/arm/mach-cns3xxx/headsmp.S
+ *
-+ * Copyright (c) 2003 ARM Limited
-+ * Copyright 2011 Gateworks Corporation
-+ * Chris Lang <clang@gateworks.com
++ * Cloned from linux/arch/arm/plat-versatile/headsmp.S
+ *
++ * Copyright (c) 2003 ARM Limited
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ __INIT
+
+/*
-+ * CNS3XXX specific entry point for secondary CPUs. This
-+ * provides a "holding pen" into which all secondary cores are held
-+ * until we're ready for them to initialise.
++ * CNS3XXX specific entry point for secondary CPUs. This provides
++ * a "holding pen" into which all secondary cores are held until we're
++ * ready for them to initialise.
+ */
+ENTRY(cns3xxx_secondary_startup)
+ mrc p15, 0, r0, c0, c0, 5
+ .long pen_release
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/hotplug.c
-@@ -0,0 +1,131 @@
-+/*
-+ * linux/arch/arm/mach-cns3xxx/hotplug.c
+@@ -0,0 +1,130 @@
++/* linux arch/arm/mach-cns3xxx/hotplug.c
+ *
-+ * Copyright (C) 2002 ARM Ltd.
-+ * Copyright 2011 Gateworks Corporation
-+ * Chris Lang <clang@gateworks.com>
++ * Cloned from linux/arch/arm/mach-realview/hotplug.c
+ *
++ * Copyright (C) 2002 ARM Ltd.
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
-+ */
++*/
++
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/smp.h>
+
+ flush_cache_all();
+ asm volatile(
-+ "mcr p15, 0, %1, c7, c5, 0\n"
++ " mcr p15, 0, %1, c7, c5, 0\n"
+ " mcr p15, 0, %1, c7, c10, 4\n"
+ /*
+ * Turn off coherency
+ unsigned int v;
+
+ asm volatile(
-+ "mrc p15, 0, %0, c1, c0, 0\n"
++ "mrc p15, 0, %0, c1, c0, 0\n"
+ " orr %0, %0, %1\n"
+ " mcr p15, 0, %0, c1, c0, 0\n"
+ " mrc p15, 0, %0, c1, c0, 1\n"
+ */
+ return cpu == 0 ? -EPERM : 0;
+}
+--- a/arch/arm/mach-cns3xxx/Kconfig
++++ b/arch/arm/mach-cns3xxx/Kconfig
+@@ -3,6 +3,7 @@ menu "CNS3XXX platform type"
+
+ config MACH_CNS3420VB
+ bool "Support for CNS3420 Validation Board"
++ select HAVE_ARM_SCU if SMP
+ select MIGHT_HAVE_PCI
+ help
+ Include support for the Cavium Networks CNS3420 MPCore Platform
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/localtimer.c
-@@ -0,0 +1,29 @@
-+/*
-+ * linux/arch/arm/mach-cns3xxx/localtimer.c
+@@ -0,0 +1,26 @@
++/* linux/arch/arm/mach-cns3xxx/localtimer.c
+ *
-+ * Copyright (C) 2002 ARM Ltd.
-+ * Copyright 2011 Gateworks Corporation
-+ * Chris Lang <clang@gateworks.com>
++ * Cloned from linux/arch/arm/mach-realview/localtimer.c
+ *
++ * Copyright (C) 2002 ARM Ltd.
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
-+ */
-+#include <linux/init.h>
-+#include <linux/smp.h>
++*/
++
+#include <linux/clockchips.h>
+
-+#include <asm/smp_twd.h>
++#include <asm/irq.h>
+#include <asm/localtimer.h>
-+#include <mach/irqs.h>
+
+/*
+ * Setup the local clock events for a CPU.
+ */
-+void __cpuinit local_timer_setup(struct clock_event_device *evt)
++int __cpuinit local_timer_setup(struct clock_event_device *evt)
+{
+ evt->irq = IRQ_LOCALTIMER;
+ twd_timer_setup(evt);
++ return 0;
+}
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/platsmp.c
-@@ -0,0 +1,168 @@
-+/*
-+ * linux/arch/arm/mach-cns3xxx/platsmp.c
+@@ -0,0 +1,175 @@
++/* linux/arch/arm/mach-cns3xxx/platsmp.c
+ *
-+ * Copyright (C) 2002 ARM Ltd.
-+ * Copyright 2011 Gateworks Corporation
++ * Copyright 2011 Gateworks Corporation
+ * Chris Lang <clang@gateworks.com>
+ *
++ * Cloned from linux/arch/arm/mach-vexpress/platsmp.c
++ *
++ * Copyright (C) 2002 ARM Ltd.
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
-+ */
++*/
++
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+
+#include <asm/cacheflush.h>
++#include <asm/hardware/gic.h>
+#include <asm/smp_scu.h>
+#include <asm/unified.h>
-+#include <mach/hardware.h>
-+#include <mach/cns3xxx.h>
+
-+#include "core.h"
++#include <mach/cns3xxx.h>
+
+extern void cns3xxx_secondary_startup(void);
+
+ * control for which core is the next to come out of the secondary
+ * boot "holding pen"
+ */
++
+volatile int __cpuinitdata pen_release = -1;
+
+/*
+ * observers, irrespective of whether they're taking part in coherency
+ * or not. This is necessary for the hotplug code to work reliably.
+ */
-+static void __cpuinit write_pen_release(int val)
++static void write_pen_release(int val)
+{
+ pen_release = val;
+ smp_wmb();
+ spin_lock(&boot_lock);
+
+ /*
-+ * This is really belt and braces; we hold unintended secondary
-+ * CPUs in the holding pen until we're ready for them. However,
-+ * since we haven't sent them a soft interrupt, they shouldn't
-+ * be there.
++ * The secondary processor is waiting to be released from
++ * the holding pen - release it, then wait for it to flag
++ * that it has been released by resetting pen_release.
++ *
++ * Note that "pen_release" is the hardware CPU ID, whereas
++ * "cpu" is Linux's internal ID.
+ */
+ write_pen_release(cpu);
+
+ * the boot monitor to read the system wide flags register,
+ * and branch to the address found there.
+ */
-+ smp_cross_call(cpumask_of(cpu), 1);
++ gic_raise_softirq(cpumask_of(cpu), 1);
+
+ timeout = jiffies + (1 * HZ);
+ while (time_before(jiffies, timeout)) {
+ * Initialise the CPU possible map early - this describes the CPUs
+ * which may be present or become present in the system.
+ */
++
+void __init smp_init_cpus(void)
+{
+ void __iomem *scu_base = scu_base_addr();
+
+ for (i = 0; i < ncores; i++)
+ set_cpu_possible(i, true);
++
++ set_smp_cross_call(gic_raise_softirq);
+}
+
+void __init platform_smp_prepare_cpus(unsigned int max_cpus)
+ * secondary CPU branches to this address.
+ */
+ __raw_writel(virt_to_phys(cns3xxx_secondary_startup),
-+ (void __iomem *)(0xFFF07000 + 0x0600));
-+}
---- /dev/null
-+++ b/arch/arm/mach-cns3xxx/include/mach/smp.h
-@@ -0,0 +1,13 @@
-+#ifndef __MACH_SMP_H
-+#define __MACH_SMP_H
-+
-+#include <asm/hardware/gic.h>
-+
-+/*
-+ * We use IRQ1 as the IPI
-+ */
-+static inline void smp_cross_call(const struct cpumask *mask, int ipi)
-+{
-+ gic_raise_softirq(mask, ipi);
++ (void __iomem *)(CNS3XXX_MISC_BASE_VIRT + 0x0600));
+}
-+#endif
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
-@@ -1325,7 +1325,7 @@ config SMP
+@@ -1388,7 +1388,7 @@ config SMP
depends on REALVIEW_EB_ARM11MP || REALVIEW_EB_A9MP || \
MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 || \
ARCH_EXYNOS4 || ARCH_TEGRA || ARCH_U8500 || ARCH_VEXPRESS_CA9X4 || \