arm64: SMP: enable PSCI boot method
authorMarc Zyngier <marc.zyngier@arm.com>
Wed, 2 Jan 2013 15:34:50 +0000 (15:34 +0000)
committerCatalin Marinas <catalin.marinas@arm.com>
Tue, 29 Jan 2013 16:56:37 +0000 (16:56 +0000)
Wire the PSCI implementation into the SMP secondary startup
code.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
arch/arm64/include/asm/smp.h
arch/arm64/kernel/Makefile
arch/arm64/kernel/smp.c
arch/arm64/kernel/smp_psci.c [new file with mode: 0644]

index b1f68c1..4b8023c 100644 (file)
@@ -75,5 +75,6 @@ struct smp_enable_ops {
 };
 
 extern const struct smp_enable_ops smp_spin_table_ops;
+extern const struct smp_enable_ops smp_psci_ops;
 
 #endif /* ifndef __ASM_SMP_H */
index 75a90c1..7b4b564 100644 (file)
@@ -14,7 +14,7 @@ arm64-obj-y           := cputable.o debug-monitors.o entry.o irq.o fpsimd.o   \
 arm64-obj-$(CONFIG_COMPAT)             += sys32.o kuser32.o signal32.o         \
                                           sys_compat.o
 arm64-obj-$(CONFIG_MODULES)            += arm64ksyms.o module.o
-arm64-obj-$(CONFIG_SMP)                        += smp.o smp_spin_table.o
+arm64-obj-$(CONFIG_SMP)                        += smp.o smp_spin_table.o smp_psci.o
 arm64-obj-$(CONFIG_HW_PERF_EVENTS)     += perf_event.o
 arm64-obj-$(CONFIG_HAVE_HW_BREAKPOINT)+= hw_breakpoint.o
 arm64-obj-$(CONFIG_EARLY_PRINTK)       += early_printk.o
index 7776922..bdd3459 100644 (file)
@@ -236,6 +236,7 @@ static void (*smp_cross_call)(const struct cpumask *, unsigned int);
 
 static const struct smp_enable_ops *enable_ops[] __initconst = {
        &smp_spin_table_ops,
+       &smp_psci_ops,
        NULL,
 };
 
diff --git a/arch/arm64/kernel/smp_psci.c b/arch/arm64/kernel/smp_psci.c
new file mode 100644 (file)
index 0000000..1120916
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * PSCI SMP initialisation
+ *
+ * Copyright (C) 2013 ARM Ltd.
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/init.h>
+#include <linux/of.h>
+#include <linux/smp.h>
+
+#include <asm/psci.h>
+
+static int __init smp_psci_init_cpu(struct device_node *dn, int cpu)
+{
+       return 0;
+}
+
+static int __init smp_psci_prepare_cpu(int cpu)
+{
+       int err;
+
+       if (!psci_ops.cpu_on) {
+               pr_err("psci: no cpu_on method, not booting CPU%d\n", cpu);
+               return -ENODEV;
+       }
+
+       err = psci_ops.cpu_on(cpu, __pa(secondary_holding_pen));
+       if (err) {
+               pr_err("psci: failed to boot CPU%d (%d)\n", cpu, err);
+               return err;
+       }
+
+       return 0;
+}
+
+const struct smp_enable_ops smp_psci_ops __initconst = {
+       .name           = "psci",
+       .init_cpu       = smp_psci_init_cpu,
+       .prepare_cpu    = smp_psci_prepare_cpu,
+};