0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <linux/init.h>
0013 #include <linux/io.h>
0014 #include <linux/of.h>
0015 #include <linux/smp.h>
0016 #include <linux/mbus.h>
0017 #include <asm/smp_scu.h>
0018 #include <asm/smp_plat.h>
0019 #include "common.h"
0020 #include "pmsu.h"
0021
0022 extern void mvebu_cortex_a9_secondary_startup(void);
0023
0024 static int mvebu_cortex_a9_boot_secondary(unsigned int cpu,
0025 struct task_struct *idle)
0026 {
0027 int ret, hw_cpu;
0028
0029 pr_info("Booting CPU %d\n", cpu);
0030
0031
0032
0033
0034
0035
0036
0037 hw_cpu = cpu_logical_map(cpu);
0038 if (of_machine_is_compatible("marvell,armada375"))
0039 mvebu_system_controller_set_cpu_boot_addr(mvebu_cortex_a9_secondary_startup);
0040 else
0041 mvebu_pmsu_set_cpu_boot_addr(hw_cpu, mvebu_cortex_a9_secondary_startup);
0042 smp_wmb();
0043
0044
0045
0046
0047
0048 arch_send_wakeup_ipi_mask(cpumask_of(cpu));
0049
0050 ret = mvebu_cpu_reset_deassert(hw_cpu);
0051 if (ret) {
0052 pr_err("Could not start the secondary CPU: %d\n", ret);
0053 return ret;
0054 }
0055
0056 return 0;
0057 }
0058
0059
0060
0061
0062
0063
0064
0065
0066 static void armada_38x_secondary_init(unsigned int cpu)
0067 {
0068 mvebu_v7_pmsu_idle_exit();
0069 }
0070
0071 #ifdef CONFIG_HOTPLUG_CPU
0072 static void armada_38x_cpu_die(unsigned int cpu)
0073 {
0074
0075
0076
0077
0078 armada_38x_do_cpu_suspend(true);
0079 }
0080
0081
0082
0083
0084
0085
0086
0087 static int armada_38x_cpu_kill(unsigned int cpu)
0088 {
0089 return 1;
0090 }
0091 #endif
0092
0093 static const struct smp_operations mvebu_cortex_a9_smp_ops __initconst = {
0094 .smp_boot_secondary = mvebu_cortex_a9_boot_secondary,
0095 };
0096
0097 static const struct smp_operations armada_38x_smp_ops __initconst = {
0098 .smp_boot_secondary = mvebu_cortex_a9_boot_secondary,
0099 .smp_secondary_init = armada_38x_secondary_init,
0100 #ifdef CONFIG_HOTPLUG_CPU
0101 .cpu_die = armada_38x_cpu_die,
0102 .cpu_kill = armada_38x_cpu_kill,
0103 #endif
0104 };
0105
0106 CPU_METHOD_OF_DECLARE(mvebu_armada_375_smp, "marvell,armada-375-smp",
0107 &mvebu_cortex_a9_smp_ops);
0108 CPU_METHOD_OF_DECLARE(mvebu_armada_380_smp, "marvell,armada-380-smp",
0109 &armada_38x_smp_ops);
0110 CPU_METHOD_OF_DECLARE(mvebu_armada_390_smp, "marvell,armada-390-smp",
0111 &armada_38x_smp_ops);