diff options
Diffstat (limited to 'arch/arm/mach-shmobile/smp-sh73a0.c')
-rw-r--r-- | arch/arm/mach-shmobile/smp-sh73a0.c | 48 |
1 files changed, 44 insertions, 4 deletions
diff --git a/arch/arm/mach-shmobile/smp-sh73a0.c b/arch/arm/mach-shmobile/smp-sh73a0.c index e36c41c4ab40..624f00f70abf 100644 --- a/arch/arm/mach-shmobile/smp-sh73a0.c +++ b/arch/arm/mach-shmobile/smp-sh73a0.c | |||
@@ -22,8 +22,10 @@ | |||
22 | #include <linux/smp.h> | 22 | #include <linux/smp.h> |
23 | #include <linux/spinlock.h> | 23 | #include <linux/spinlock.h> |
24 | #include <linux/io.h> | 24 | #include <linux/io.h> |
25 | #include <linux/delay.h> | ||
25 | #include <mach/common.h> | 26 | #include <mach/common.h> |
26 | #include <asm/smp_plat.h> | 27 | #include <asm/smp_plat.h> |
28 | #include <mach/sh73a0.h> | ||
27 | #include <asm/smp_scu.h> | 29 | #include <asm/smp_scu.h> |
28 | #include <asm/smp_twd.h> | 30 | #include <asm/smp_twd.h> |
29 | #include <asm/hardware/gic.h> | 31 | #include <asm/hardware/gic.h> |
@@ -64,19 +66,19 @@ static void modify_scu_cpu_psr(unsigned long set, unsigned long clr) | |||
64 | __raw_writel(tmp, scu_base + 8); | 66 | __raw_writel(tmp, scu_base + 8); |
65 | } | 67 | } |
66 | 68 | ||
67 | unsigned int __init sh73a0_get_core_count(void) | 69 | static unsigned int __init sh73a0_get_core_count(void) |
68 | { | 70 | { |
69 | void __iomem *scu_base = scu_base_addr(); | 71 | void __iomem *scu_base = scu_base_addr(); |
70 | 72 | ||
71 | return scu_get_core_count(scu_base); | 73 | return scu_get_core_count(scu_base); |
72 | } | 74 | } |
73 | 75 | ||
74 | void __cpuinit sh73a0_secondary_init(unsigned int cpu) | 76 | static void __cpuinit sh73a0_secondary_init(unsigned int cpu) |
75 | { | 77 | { |
76 | gic_secondary_init(0); | 78 | gic_secondary_init(0); |
77 | } | 79 | } |
78 | 80 | ||
79 | int __cpuinit sh73a0_boot_secondary(unsigned int cpu) | 81 | static int __cpuinit sh73a0_boot_secondary(unsigned int cpu, struct task_struct *idle) |
80 | { | 82 | { |
81 | cpu = cpu_logical_map(cpu); | 83 | cpu = cpu_logical_map(cpu); |
82 | 84 | ||
@@ -91,7 +93,7 @@ int __cpuinit sh73a0_boot_secondary(unsigned int cpu) | |||
91 | return 0; | 93 | return 0; |
92 | } | 94 | } |
93 | 95 | ||
94 | void __init sh73a0_smp_prepare_cpus(void) | 96 | static void __init sh73a0_smp_prepare_cpus(unsigned int max_cpus) |
95 | { | 97 | { |
96 | int cpu = cpu_logical_map(0); | 98 | int cpu = cpu_logical_map(0); |
97 | 99 | ||
@@ -104,3 +106,41 @@ void __init sh73a0_smp_prepare_cpus(void) | |||
104 | /* enable cache coherency on CPU0 */ | 106 | /* enable cache coherency on CPU0 */ |
105 | modify_scu_cpu_psr(0, 3 << (cpu * 8)); | 107 | modify_scu_cpu_psr(0, 3 << (cpu * 8)); |
106 | } | 108 | } |
109 | |||
110 | static void __init sh73a0_smp_init_cpus(void) | ||
111 | { | ||
112 | unsigned int ncores = sh73a0_get_core_count(); | ||
113 | |||
114 | shmobile_smp_init_cpus(ncores); | ||
115 | } | ||
116 | |||
117 | static int __maybe_unused sh73a0_cpu_kill(unsigned int cpu) | ||
118 | { | ||
119 | int k; | ||
120 | |||
121 | /* this function is running on another CPU than the offline target, | ||
122 | * here we need wait for shutdown code in platform_cpu_die() to | ||
123 | * finish before asking SoC-specific code to power off the CPU core. | ||
124 | */ | ||
125 | for (k = 0; k < 1000; k++) { | ||
126 | if (shmobile_cpu_is_dead(cpu)) | ||
127 | return 1; | ||
128 | |||
129 | mdelay(1); | ||
130 | } | ||
131 | |||
132 | return 0; | ||
133 | } | ||
134 | |||
135 | |||
136 | struct smp_operations sh73a0_smp_ops __initdata = { | ||
137 | .smp_init_cpus = sh73a0_smp_init_cpus, | ||
138 | .smp_prepare_cpus = sh73a0_smp_prepare_cpus, | ||
139 | .smp_secondary_init = sh73a0_secondary_init, | ||
140 | .smp_boot_secondary = sh73a0_boot_secondary, | ||
141 | #ifdef CONFIG_HOTPLUG_CPU | ||
142 | .cpu_kill = sh73a0_cpu_kill, | ||
143 | .cpu_die = shmobile_cpu_die, | ||
144 | .cpu_disable = shmobile_cpu_disable, | ||
145 | #endif | ||
146 | }; | ||