summaryrefslogtreecommitdiff
path: root/arch/arm/mach-imx/platsmp.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-imx/platsmp.c')
-rw-r--r--arch/arm/mach-imx/platsmp.c85
1 files changed, 64 insertions, 21 deletions
diff --git a/arch/arm/mach-imx/platsmp.c b/arch/arm/mach-imx/platsmp.c
index c6e1ab544882..972639038be5 100644
--- a/arch/arm/mach-imx/platsmp.c
+++ b/arch/arm/mach-imx/platsmp.c
@@ -1,17 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* 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/of_address.h>
+#include <linux/of.h>
#include <linux/smp.h>
+
#include <asm/cacheflush.h>
#include <asm/page.h>
#include <asm/smp_scu.h>
@@ -20,8 +17,6 @@
#include "common.h"
#include "hardware.h"
-#define SCU_STANDBY_ENABLE (1 << 5)
-
u32 g_diag_reg;
static void __iomem *scu_base;
@@ -45,15 +40,7 @@ void __init imx_scu_map_io(void)
scu_base = IMX_IO_ADDRESS(base);
}
-void imx_scu_standby_enable(void)
-{
- u32 val = readl_relaxed(scu_base);
-
- val |= SCU_STANDBY_ENABLE;
- writel_relaxed(val, scu_base);
-}
-
-static int __cpuinit imx_boot_secondary(unsigned int cpu, struct task_struct *idle)
+static int imx_boot_secondary(unsigned int cpu, struct task_struct *idle)
{
imx_set_cpu_jump(cpu, v7_secondary_startup);
imx_enable_cpu(cpu, true);
@@ -92,11 +79,10 @@ static void __init imx_smp_prepare_cpus(unsigned int max_cpus)
* secondary cores when booting them.
*/
asm("mrc p15, 0, %0, c15, c0, 1" : "=r" (g_diag_reg) : : "cc");
- __cpuc_flush_dcache_area(&g_diag_reg, sizeof(g_diag_reg));
- outer_clean_range(__pa(&g_diag_reg), __pa(&g_diag_reg + 1));
+ sync_cache_w(&g_diag_reg);
}
-struct smp_operations imx_smp_ops __initdata = {
+const struct smp_operations imx_smp_ops __initconst = {
.smp_init_cpus = imx_smp_init_cpus,
.smp_prepare_cpus = imx_smp_prepare_cpus,
.smp_boot_secondary = imx_boot_secondary,
@@ -105,3 +91,60 @@ struct smp_operations imx_smp_ops __initdata = {
.cpu_kill = imx_cpu_kill,
#endif
};
+
+/*
+ * Initialise the CPU possible map early - this describes the CPUs
+ * which may be present or become present in the system.
+ */
+static void __init imx7_smp_init_cpus(void)
+{
+ struct device_node *np;
+ int i, ncores = 0;
+
+ /* The iMX7D SCU does not report core count, get it from DT */
+ for_each_of_cpu_node(np)
+ ncores++;
+
+ for (i = ncores; i < NR_CPUS; i++)
+ set_cpu_possible(i, false);
+}
+
+const struct smp_operations imx7_smp_ops __initconst = {
+ .smp_init_cpus = imx7_smp_init_cpus,
+ .smp_boot_secondary = imx_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+ .cpu_die = imx_cpu_die,
+ .cpu_kill = imx_cpu_kill,
+#endif
+};
+
+#define DCFG_CCSR_SCRATCHRW1 0x200
+
+static int ls1021a_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+ arch_send_wakeup_ipi_mask(cpumask_of(cpu));
+
+ return 0;
+}
+
+static void __init ls1021a_smp_prepare_cpus(unsigned int max_cpus)
+{
+ struct device_node *np;
+ void __iomem *dcfg_base;
+ unsigned long paddr;
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,ls1021a-dcfg");
+ dcfg_base = of_iomap(np, 0);
+ of_node_put(np);
+ BUG_ON(!dcfg_base);
+
+ paddr = __pa_symbol(secondary_startup);
+ writel_relaxed(cpu_to_be32(paddr), dcfg_base + DCFG_CCSR_SCRATCHRW1);
+
+ iounmap(dcfg_base);
+}
+
+const struct smp_operations ls1021a_smp_ops __initconst = {
+ .smp_prepare_cpus = ls1021a_smp_prepare_cpus,
+ .smp_boot_secondary = ls1021a_boot_secondary,
+};