24
24
#include <asm/suspend.h>
25
25
#include "common.h"
26
26
#include "platsmp-apmu.h"
27
+ #include "rcar-gen2.h"
27
28
28
29
static struct {
29
30
void __iomem * iomem ;
@@ -118,14 +119,66 @@ static void apmu_parse_cfg(void (*fn)(struct resource *res, int cpu, int bit),
118
119
}
119
120
}
120
121
121
- void __init shmobile_smp_apmu_prepare_cpus (unsigned int max_cpus ,
122
- struct rcar_apmu_config * apmu_config ,
123
- int num )
122
+ static const struct of_device_id apmu_ids [] = {
123
+ { .compatible = "renesas,apmu" },
124
+ { /*sentinel*/ }
125
+ };
126
+
127
+ static void apmu_parse_dt (void (* fn )(struct resource * res , int cpu , int bit ))
128
+ {
129
+ struct device_node * np_apmu , * np_cpu ;
130
+ struct resource res ;
131
+ int bit , index ;
132
+ u32 id ;
133
+
134
+ for_each_matching_node (np_apmu , apmu_ids ) {
135
+ /* only enable the cluster that includes the boot CPU */
136
+ bool is_allowed = false;
137
+
138
+ for (bit = 0 ; bit < CONFIG_NR_CPUS ; bit ++ ) {
139
+ np_cpu = of_parse_phandle (np_apmu , "cpus" , bit );
140
+ if (np_cpu ) {
141
+ if (!of_property_read_u32 (np_cpu , "reg" , & id )) {
142
+ if (id == cpu_logical_map (0 )) {
143
+ is_allowed = true;
144
+ of_node_put (np_cpu );
145
+ break ;
146
+ }
147
+
148
+ }
149
+ of_node_put (np_cpu );
150
+ }
151
+ }
152
+ if (!is_allowed )
153
+ continue ;
154
+
155
+ for (bit = 0 ; bit < CONFIG_NR_CPUS ; bit ++ ) {
156
+ np_cpu = of_parse_phandle (np_apmu , "cpus" , bit );
157
+ if (np_cpu ) {
158
+ if (!of_property_read_u32 (np_cpu , "reg" , & id )) {
159
+ index = get_logical_index (id );
160
+ if ((index >= 0 ) &&
161
+ !of_address_to_resource (np_apmu ,
162
+ 0 , & res ))
163
+ fn (& res , index , bit );
164
+ }
165
+ of_node_put (np_cpu );
166
+ }
167
+ }
168
+ }
169
+ }
170
+
171
+ static void __init shmobile_smp_apmu_setup_boot (void )
124
172
{
125
173
/* install boot code shared by all CPUs */
126
174
shmobile_boot_fn = virt_to_phys (shmobile_smp_boot );
175
+ }
127
176
128
- /* perform per-cpu setup */
177
+ void __init shmobile_smp_apmu_prepare_cpus (unsigned int max_cpus ,
178
+ struct rcar_apmu_config * apmu_config ,
179
+ int num )
180
+ {
181
+ shmobile_smp_apmu_setup_boot ();
129
182
apmu_parse_cfg (apmu_init_cpu , apmu_config , num );
130
183
}
131
184
@@ -136,7 +189,38 @@ int shmobile_smp_apmu_boot_secondary(unsigned int cpu, struct task_struct *idle)
136
189
137
190
return apmu_wrap (cpu , apmu_power_on );
138
191
}
192
+
193
+ static void __init shmobile_smp_apmu_prepare_cpus_dt (unsigned int max_cpus )
194
+ {
195
+ shmobile_smp_apmu_setup_boot ();
196
+ apmu_parse_dt (apmu_init_cpu );
197
+ rcar_gen2_pm_init ();
198
+ }
199
+
200
+ static int shmobile_smp_apmu_boot_secondary_md21 (unsigned int cpu ,
201
+ struct task_struct * idle )
202
+ {
203
+ /* Error out when hardware debug mode is enabled */
204
+ if (rcar_gen2_read_mode_pins () & BIT (21 )) {
205
+ pr_warn ("Unable to boot CPU%u when MD21 is set\n" , cpu );
206
+ return - ENOTSUPP ;
207
+ }
208
+
209
+ return shmobile_smp_apmu_boot_secondary (cpu , idle );
210
+ }
211
+
212
+ static struct smp_operations apmu_smp_ops __initdata = {
213
+ .smp_prepare_cpus = shmobile_smp_apmu_prepare_cpus_dt ,
214
+ .smp_boot_secondary = shmobile_smp_apmu_boot_secondary_md21 ,
215
+ #ifdef CONFIG_HOTPLUG_CPU
216
+ .cpu_can_disable = shmobile_smp_cpu_can_disable ,
217
+ .cpu_die = shmobile_smp_apmu_cpu_die ,
218
+ .cpu_kill = shmobile_smp_apmu_cpu_kill ,
139
219
#endif
220
+ };
221
+
222
+ CPU_METHOD_OF_DECLARE (shmobile_smp_apmu , "renesas,apmu" , & apmu_smp_ops );
223
+ #endif /* CONFIG_SMP */
140
224
141
225
#if defined(CONFIG_HOTPLUG_CPU ) || defined(CONFIG_SUSPEND )
142
226
/* nicked from arch/arm/mach-exynos/hotplug.c */
0 commit comments