2 * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
15 #include <linux/sizes.h>
16 #include <linux/compiler.h>
17 #include <linux/init.h>
19 #include <linux/regmap.h>
20 #include <linux/mfd/syscon.h>
22 #include <asm/smp_scu.h>
24 static struct regmap *sbcm_regmap;
26 static void __init uniphier_smp_prepare_cpus(unsigned int max_cpus)
28 static cpumask_t only_cpu_0 = { CPU_BITS_CPU0 };
29 unsigned long scu_base_phys = 0;
30 void __iomem *scu_base;
32 sbcm_regmap = syscon_regmap_lookup_by_compatible(
33 "socionext,uniphier-system-bus-controller-misc");
34 if (IS_ERR(sbcm_regmap)) {
35 pr_err("failed to regmap system-bus-controller-misc\n");
39 if (scu_a9_has_base())
40 scu_base_phys = scu_a9_get_base();
43 pr_err("failed to get scu base\n");
47 scu_base = ioremap(scu_base_phys, SZ_128);
49 pr_err("failed to remap scu base (0x%08lx)\n", scu_base_phys);
58 pr_warn("disabling SMP\n");
59 init_cpu_present(&only_cpu_0);
63 static void __naked uniphier_secondary_startup(void)
65 asm("bl v7_invalidate_l1\n"
66 "b secondary_startup\n");
69 static int uniphier_boot_secondary(unsigned int cpu,
70 struct task_struct *idle)
77 ret = regmap_write(sbcm_regmap, 0x1208,
78 virt_to_phys(uniphier_secondary_startup));
80 asm("sev"); /* wake up secondary CPU */
85 struct smp_operations uniphier_smp_ops __initdata = {
86 .smp_prepare_cpus = uniphier_smp_prepare_cpus,
87 .smp_boot_secondary = uniphier_boot_secondary,
89 CPU_METHOD_OF_DECLARE(uniphier_smp, "socionext,uniphier-smp",