aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGeert Uytterhoeven <geert+renesas@glider.be>2015-01-14 07:11:21 -0500
committerSimon Horman <horms+renesas@verge.net.au>2015-01-15 21:02:37 -0500
commit60e26435623001424f1c62dde26edb614b29d8ae (patch)
tree21c612d8c4d2732d50d8bed55b8806e90e9bdfbb
parente43ee86efb68808c8847de17e58f5427b006363c (diff)
ARM: shmobile: R-Mobile: Generalize adding/looking up special PM domains
Make adding special PM domains to an array, and looking them up later, more generic, so it can be used for all special hardware blocks. The type of PM domain is also stored, so rmobile_setup_pm_domain() can use a switch() statement instead of a chain of if/else statements. Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be> Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
-rw-r--r--arch/arm/mach-shmobile/pm-rmobile.c102
1 files changed, 63 insertions, 39 deletions
diff --git a/arch/arm/mach-shmobile/pm-rmobile.c b/arch/arm/mach-shmobile/pm-rmobile.c
index e1be4b8919ef..e4c3f7de48e2 100644
--- a/arch/arm/mach-shmobile/pm-rmobile.c
+++ b/arch/arm/mach-shmobile/pm-rmobile.c
@@ -217,50 +217,67 @@ static int rmobile_pd_suspend_console(void)
217 return console_suspend_enabled ? 0 : -EBUSY; 217 return console_suspend_enabled ? 0 : -EBUSY;
218} 218}
219 219
220#define MAX_NUM_CPU_PDS 8 220enum pd_types {
221 PD_NORMAL,
222 PD_CPU,
223 PD_CONSOLE,
224 PD_DEBUG,
225};
221 226
222static unsigned int num_cpu_pds __initdata; 227#define MAX_NUM_SPECIAL_PDS 16
223static struct device_node *cpu_pds[MAX_NUM_CPU_PDS] __initdata;
224static struct device_node *console_pd __initdata;
225static struct device_node *debug_pd __initdata;
226 228
227static void __init get_special_pds(void) 229static struct special_pd {
228{ 230 struct device_node *pd;
229 struct device_node *np, *pd; 231 enum pd_types type;
230 unsigned int i; 232} special_pds[MAX_NUM_SPECIAL_PDS] __initdata;
231 233
232 /* PM domains containing CPUs */ 234static unsigned int num_special_pds __initdata;
233 for_each_node_by_type(np, "cpu") {
234 pd = of_parse_phandle(np, "power-domains", 0);
235 if (!pd)
236 continue;
237 235
238 for (i = 0; i < num_cpu_pds; i++) 236static void __init add_special_pd(struct device_node *np, enum pd_types type)
239 if (pd == cpu_pds[i]) 237{
240 break; 238 unsigned int i;
239 struct device_node *pd;
241 240
242 if (i < num_cpu_pds) { 241 pd = of_parse_phandle(np, "power-domains", 0);
243 of_node_put(pd); 242 if (!pd)
244 continue; 243 return;
245 }
246 244
247 if (num_cpu_pds == MAX_NUM_CPU_PDS) { 245 for (i = 0; i < num_special_pds; i++)
248 pr_warn("Too many CPU PM domains\n"); 246 if (pd == special_pds[i].pd && type == special_pds[i].type) {
249 of_node_put(pd); 247 of_node_put(pd);
250 continue; 248 return;
251 } 249 }
252 250
253 cpu_pds[num_cpu_pds++] = pd; 251 if (num_special_pds == ARRAY_SIZE(special_pds)) {
252 pr_warn("Too many special PM domains\n");
253 of_node_put(pd);
254 return;
254 } 255 }
255 256
257 pr_debug("Special PM domain %s type %d for %s\n", pd->name, type,
258 np->full_name);
259
260 special_pds[num_special_pds].pd = pd;
261 special_pds[num_special_pds].type = type;
262 num_special_pds++;
263}
264
265static void __init get_special_pds(void)
266{
267 struct device_node *np;
268
269 /* PM domains containing CPUs */
270 for_each_node_by_type(np, "cpu")
271 add_special_pd(np, PD_CPU);
272
256 /* PM domain containing console */ 273 /* PM domain containing console */
257 if (of_stdout) 274 if (of_stdout)
258 console_pd = of_parse_phandle(of_stdout, "power-domains", 0); 275 add_special_pd(of_stdout, PD_CONSOLE);
259 276
260 /* PM domain containing Coresight-ETM */ 277 /* PM domain containing Coresight-ETM */
261 np = of_find_compatible_node(NULL, NULL, "arm,coresight-etm3x"); 278 np = of_find_compatible_node(NULL, NULL, "arm,coresight-etm3x");
262 if (np) { 279 if (np) {
263 debug_pd = of_parse_phandle(np, "power-domains", 0); 280 add_special_pd(np, PD_DEBUG);
264 of_node_put(np); 281 of_node_put(np);
265 } 282 }
266} 283}
@@ -269,21 +286,19 @@ static void __init put_special_pds(void)
269{ 286{
270 unsigned int i; 287 unsigned int i;
271 288
272 for (i = 0; i < num_cpu_pds; i++) 289 for (i = 0; i < num_special_pds; i++)
273 of_node_put(cpu_pds[i]); 290 of_node_put(special_pds[i].pd);
274 of_node_put(console_pd);
275 of_node_put(debug_pd);
276} 291}
277 292
278static bool __init pd_contains_cpu(const struct device_node *pd) 293static enum pd_types __init pd_type(const struct device_node *pd)
279{ 294{
280 unsigned int i; 295 unsigned int i;
281 296
282 for (i = 0; i < num_cpu_pds; i++) 297 for (i = 0; i < num_special_pds; i++)
283 if (pd == cpu_pds[i]) 298 if (pd == special_pds[i].pd)
284 return true; 299 return special_pds[i].type;
285 300
286 return false; 301 return PD_NORMAL;
287} 302}
288 303
289static void __init rmobile_setup_pm_domain(struct device_node *np, 304static void __init rmobile_setup_pm_domain(struct device_node *np,
@@ -291,7 +306,8 @@ static void __init rmobile_setup_pm_domain(struct device_node *np,
291{ 306{
292 const char *name = pd->genpd.name; 307 const char *name = pd->genpd.name;
293 308
294 if (pd_contains_cpu(np)) { 309 switch (pd_type(np)) {
310 case PD_CPU:
295 /* 311 /*
296 * This domain contains the CPU core and therefore it should 312 * This domain contains the CPU core and therefore it should
297 * only be turned off if the CPU is not in use. 313 * only be turned off if the CPU is not in use.
@@ -299,11 +315,15 @@ static void __init rmobile_setup_pm_domain(struct device_node *np,
299 pr_debug("PM domain %s contains CPU\n", name); 315 pr_debug("PM domain %s contains CPU\n", name);
300 pd->gov = &pm_domain_always_on_gov; 316 pd->gov = &pm_domain_always_on_gov;
301 pd->suspend = rmobile_pd_suspend_busy; 317 pd->suspend = rmobile_pd_suspend_busy;
302 } else if (np == console_pd) { 318 break;
319
320 case PD_CONSOLE:
303 pr_debug("PM domain %s contains serial console\n", name); 321 pr_debug("PM domain %s contains serial console\n", name);
304 pd->gov = &pm_domain_always_on_gov; 322 pd->gov = &pm_domain_always_on_gov;
305 pd->suspend = rmobile_pd_suspend_console; 323 pd->suspend = rmobile_pd_suspend_console;
306 } else if (np == debug_pd) { 324 break;
325
326 case PD_DEBUG:
307 /* 327 /*
308 * This domain contains the Coresight-ETM hardware block and 328 * This domain contains the Coresight-ETM hardware block and
309 * therefore it should only be turned off if the debug module 329 * therefore it should only be turned off if the debug module
@@ -312,6 +332,10 @@ static void __init rmobile_setup_pm_domain(struct device_node *np,
312 pr_debug("PM domain %s contains Coresight-ETM\n", name); 332 pr_debug("PM domain %s contains Coresight-ETM\n", name);
313 pd->gov = &pm_domain_always_on_gov; 333 pd->gov = &pm_domain_always_on_gov;
314 pd->suspend = rmobile_pd_suspend_busy; 334 pd->suspend = rmobile_pd_suspend_busy;
335 break;
336
337 case PD_NORMAL:
338 break;
315 } 339 }
316 340
317 rmobile_init_pm_domain(pd); 341 rmobile_init_pm_domain(pd);