aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-socfpga/platsmp.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-socfpga/platsmp.c')
-rw-r--r--arch/arm/mach-socfpga/platsmp.c57
1 files changed, 39 insertions, 18 deletions
diff --git a/arch/arm/mach-socfpga/platsmp.c b/arch/arm/mach-socfpga/platsmp.c
index 79c5336c569f..c6f1df89f9af 100644
--- a/arch/arm/mach-socfpga/platsmp.c
+++ b/arch/arm/mach-socfpga/platsmp.c
@@ -54,32 +54,43 @@ static int socfpga_boot_secondary(unsigned int cpu, struct task_struct *idle)
54 return 0; 54 return 0;
55} 55}
56 56
57/* 57static int socfpga_a10_boot_secondary(unsigned int cpu, struct task_struct *idle)
58 * Initialise the CPU possible map early - this describes the CPUs
59 * which may be present or become present in the system.
60 */
61static void __init socfpga_smp_init_cpus(void)
62{ 58{
63 unsigned int i, ncores; 59 int trampoline_size = &secondary_trampoline_end - &secondary_trampoline;
64 60
65 ncores = scu_get_core_count(socfpga_scu_base_addr); 61 if (socfpga_cpu1start_addr) {
62 writel(RSTMGR_MPUMODRST_CPU1, rst_manager_base_addr +
63 SOCFPGA_A10_RSTMGR_MODMPURST);
64 memcpy(phys_to_virt(0), &secondary_trampoline, trampoline_size);
66 65
67 for (i = 0; i < ncores; i++) 66 writel(virt_to_phys(secondary_startup),
68 set_cpu_possible(i, true); 67 sys_manager_base_addr + (socfpga_cpu1start_addr & 0x00000fff));
69 68
70 /* sanity check */ 69 flush_cache_all();
71 if (ncores > num_possible_cpus()) { 70 smp_wmb();
72 pr_warn("socfpga: no. of cores (%d) greater than configured" 71 outer_clean_range(0, trampoline_size);
73 "maximum of %d - clipping\n", ncores, num_possible_cpus()); 72
74 ncores = num_possible_cpus(); 73 /* This will release CPU #1 out of reset. */
74 writel(0, rst_manager_base_addr + SOCFPGA_A10_RSTMGR_MODMPURST);
75 } 75 }
76 76
77 for (i = 0; i < ncores; i++) 77 return 0;
78 set_cpu_possible(i, true);
79} 78}
80 79
81static void __init socfpga_smp_prepare_cpus(unsigned int max_cpus) 80static void __init socfpga_smp_prepare_cpus(unsigned int max_cpus)
82{ 81{
82 struct device_node *np;
83 void __iomem *socfpga_scu_base_addr;
84
85 np = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-scu");
86 if (!np) {
87 pr_err("%s: missing scu\n", __func__);
88 return;
89 }
90
91 socfpga_scu_base_addr = of_iomap(np, 0);
92 if (!socfpga_scu_base_addr)
93 return;
83 scu_enable(socfpga_scu_base_addr); 94 scu_enable(socfpga_scu_base_addr);
84} 95}
85 96
@@ -95,11 +106,21 @@ static void socfpga_cpu_die(unsigned int cpu)
95 cpu_do_idle(); 106 cpu_do_idle();
96} 107}
97 108
98struct smp_operations socfpga_smp_ops __initdata = { 109static struct smp_operations socfpga_smp_ops __initdata = {
99 .smp_init_cpus = socfpga_smp_init_cpus,
100 .smp_prepare_cpus = socfpga_smp_prepare_cpus, 110 .smp_prepare_cpus = socfpga_smp_prepare_cpus,
101 .smp_boot_secondary = socfpga_boot_secondary, 111 .smp_boot_secondary = socfpga_boot_secondary,
102#ifdef CONFIG_HOTPLUG_CPU 112#ifdef CONFIG_HOTPLUG_CPU
103 .cpu_die = socfpga_cpu_die, 113 .cpu_die = socfpga_cpu_die,
104#endif 114#endif
105}; 115};
116
117static struct smp_operations socfpga_a10_smp_ops __initdata = {
118 .smp_prepare_cpus = socfpga_smp_prepare_cpus,
119 .smp_boot_secondary = socfpga_a10_boot_secondary,
120#ifdef CONFIG_HOTPLUG_CPU
121 .cpu_die = socfpga_cpu_die,
122#endif
123};
124
125CPU_METHOD_OF_DECLARE(socfpga_smp, "altr,socfpga-smp", &socfpga_smp_ops);
126CPU_METHOD_OF_DECLARE(socfpga_a10_smp, "altr,socfpga-a10-smp", &socfpga_a10_smp_ops);