summaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-imx/platsmp.c
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2011-11-02 02:46:55 +0100
committerArnd Bergmann <arnd@arndb.de>2011-11-02 02:46:55 +0100
commitabc3f126ac736280c68db6472eb0040ddf6e1b1f (patch)
tree4e3333cde6da6c49dcd81920410bf5a33055f03a /arch/arm/mach-imx/platsmp.c
parentb8df0ea26ac17c9a073f235c7fdfbdd1851b59ea (diff)
parent8bcb97659656042f3132b2814b19709856aa1335 (diff)
downloadlinux-abc3f126ac736280c68db6472eb0040ddf6e1b1f.tar.bz2
Merge branch 'imx/imx6q' into next/soc
Conflicts: Documentation/devicetree/bindings/arm/fsl.txt arch/arm/Kconfig arch/arm/Kconfig.debug arch/arm/plat-mxc/include/mach/common.h
Diffstat (limited to 'arch/arm/mach-imx/platsmp.c')
-rw-r--r--arch/arm/mach-imx/platsmp.c85
1 files changed, 85 insertions, 0 deletions
diff --git a/arch/arm/mach-imx/platsmp.c b/arch/arm/mach-imx/platsmp.c
new file mode 100644
index 000000000000..ab98c6fec9eb
--- /dev/null
+++ b/arch/arm/mach-imx/platsmp.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <asm/page.h>
+#include <asm/smp_scu.h>
+#include <asm/hardware/gic.h>
+#include <asm/mach/map.h>
+#include <mach/common.h>
+#include <mach/hardware.h>
+
+static void __iomem *scu_base;
+
+static struct map_desc scu_io_desc __initdata = {
+ /* .virtual and .pfn are run-time assigned */
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+};
+
+void __init imx_scu_map_io(void)
+{
+ unsigned long base;
+
+ /* Get SCU base */
+ asm("mrc p15, 4, %0, c15, c0, 0" : "=r" (base));
+
+ scu_io_desc.virtual = IMX_IO_P2V(base);
+ scu_io_desc.pfn = __phys_to_pfn(base);
+ iotable_init(&scu_io_desc, 1);
+
+ scu_base = IMX_IO_ADDRESS(base);
+}
+
+void __cpuinit platform_secondary_init(unsigned int cpu)
+{
+ /*
+ * if any interrupts are already enabled for the primary
+ * core (e.g. timer irq), then they will not have been enabled
+ * for us: do so
+ */
+ gic_secondary_init(0);
+}
+
+int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+ imx_set_cpu_jump(cpu, v7_secondary_startup);
+ imx_enable_cpu(cpu, true);
+ return 0;
+}
+
+/*
+ * 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)
+{
+ int i, ncores;
+
+ ncores = scu_get_core_count(scu_base);
+
+ for (i = 0; i < ncores; i++)
+ set_cpu_possible(i, true);
+
+ set_smp_cross_call(gic_raise_softirq);
+}
+
+void imx_smp_prepare(void)
+{
+ scu_enable(scu_base);
+}
+
+void __init platform_smp_prepare_cpus(unsigned int max_cpus)
+{
+ imx_smp_prepare();
+}