aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOlof Johansson <olof@lixom.net>2015-01-21 20:19:05 -0500
committerOlof Johansson <olof@lixom.net>2015-01-21 20:19:05 -0500
commitf50f7070e5de59a168e45831c1e667f04583f563 (patch)
treed8116eb25aebc6f1ffd3fb043142252bf708c269
parenta71596933cf792dacc3c5080df298c0fccef1d94 (diff)
parent1632ff162f305f38667632c465e4bfaab8ef87a2 (diff)
Merge tag 'renesas-soc3-for-v3.20' of git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas into next/soc
Merge "Third Round of Renesas ARM Based SoC Updates for v3.20" from Simon Horman: * Special-case PM domains with memory-controllers * tag 'renesas-soc3-for-v3.20' of git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas: ARM: shmobile: R-Mobile: Special-case PM domains with memory-controllers ARM: shmobile: R-Mobile: Generalize adding/looking up special PM domains ARM: shmobile: R-Mobile: Consolidate rmobile_pd_suspend_*() Signed-off-by: Olof Johansson <olof@lixom.net>
-rw-r--r--arch/arm/mach-shmobile/pm-rmobile.c155
1 files changed, 97 insertions, 58 deletions
diff --git a/arch/arm/mach-shmobile/pm-rmobile.c b/arch/arm/mach-shmobile/pm-rmobile.c
index 85a7fdd9823b..95018209ff0b 100644
--- a/arch/arm/mach-shmobile/pm-rmobile.c
+++ b/arch/arm/mach-shmobile/pm-rmobile.c
@@ -200,11 +200,10 @@ void rmobile_add_devices_to_domains(struct pm_domain_device data[],
200 200
201#else /* !CONFIG_ARCH_SHMOBILE_LEGACY */ 201#else /* !CONFIG_ARCH_SHMOBILE_LEGACY */
202 202
203static int rmobile_pd_suspend_cpu(void) 203static int rmobile_pd_suspend_busy(void)
204{ 204{
205 /* 205 /*
206 * This domain contains the CPU core and therefore it should 206 * This domain should not be turned off.
207 * only be turned off if the CPU is not in use.
208 */ 207 */
209 return -EBUSY; 208 return -EBUSY;
210} 209}
@@ -218,83 +217,95 @@ static int rmobile_pd_suspend_console(void)
218 return console_suspend_enabled ? 0 : -EBUSY; 217 return console_suspend_enabled ? 0 : -EBUSY;
219} 218}
220 219
221static int rmobile_pd_suspend_debug(void) 220enum pd_types {
222{ 221 PD_NORMAL,
223 /* 222 PD_CPU,
224 * This domain contains the Coresight-ETM hardware block and 223 PD_CONSOLE,
225 * therefore it should only be turned off if the debug module is 224 PD_DEBUG,
226 * not in use. 225 PD_MEMCTL,
227 */ 226};
228 return -EBUSY;
229}
230 227
231#define MAX_NUM_CPU_PDS 8 228#define MAX_NUM_SPECIAL_PDS 16
232 229
233static unsigned int num_cpu_pds __initdata; 230static struct special_pd {
234static struct device_node *cpu_pds[MAX_NUM_CPU_PDS] __initdata; 231 struct device_node *pd;
235static struct device_node *console_pd __initdata; 232 enum pd_types type;
236static struct device_node *debug_pd __initdata; 233} special_pds[MAX_NUM_SPECIAL_PDS] __initdata;
237 234
238static void __init get_special_pds(void) 235static unsigned int num_special_pds __initdata;
236
237static const struct of_device_id special_ids[] __initconst = {
238 { .compatible = "arm,coresight-etm3x", .data = (void *)PD_DEBUG },
239 { .compatible = "renesas,dbsc-r8a73a4", .data = (void *)PD_MEMCTL, },
240 { .compatible = "renesas,dbsc3-r8a7740", .data = (void *)PD_MEMCTL, },
241 { .compatible = "renesas,sbsc-sh73a0", .data = (void *)PD_MEMCTL, },
242 { /* sentinel */ },
243};
244
245static void __init add_special_pd(struct device_node *np, enum pd_types type)
239{ 246{
240 struct device_node *np, *pd;
241 unsigned int i; 247 unsigned int i;
248 struct device_node *pd;
242 249
243 /* PM domains containing CPUs */ 250 pd = of_parse_phandle(np, "power-domains", 0);
244 for_each_node_by_type(np, "cpu") { 251 if (!pd)
245 pd = of_parse_phandle(np, "power-domains", 0); 252 return;
246 if (!pd)
247 continue;
248
249 for (i = 0; i < num_cpu_pds; i++)
250 if (pd == cpu_pds[i])
251 break;
252 253
253 if (i < num_cpu_pds) { 254 for (i = 0; i < num_special_pds; i++)
255 if (pd == special_pds[i].pd && type == special_pds[i].type) {
254 of_node_put(pd); 256 of_node_put(pd);
255 continue; 257 return;
256 } 258 }
257 259
258 if (num_cpu_pds == MAX_NUM_CPU_PDS) { 260 if (num_special_pds == ARRAY_SIZE(special_pds)) {
259 pr_warn("Too many CPU PM domains\n"); 261 pr_warn("Too many special PM domains\n");
260 of_node_put(pd); 262 of_node_put(pd);
261 continue; 263 return;
262 }
263
264 cpu_pds[num_cpu_pds++] = pd;
265 } 264 }
266 265
266 pr_debug("Special PM domain %s type %d for %s\n", pd->name, type,
267 np->full_name);
268
269 special_pds[num_special_pds].pd = pd;
270 special_pds[num_special_pds].type = type;
271 num_special_pds++;
272}
273
274static void __init get_special_pds(void)
275{
276 struct device_node *np;
277 const struct of_device_id *id;
278
279 /* PM domains containing CPUs */
280 for_each_node_by_type(np, "cpu")
281 add_special_pd(np, PD_CPU);
282
267 /* PM domain containing console */ 283 /* PM domain containing console */
268 if (of_stdout) 284 if (of_stdout)
269 console_pd = of_parse_phandle(of_stdout, "power-domains", 0); 285 add_special_pd(of_stdout, PD_CONSOLE);
270 286
271 /* PM domain containing Coresight-ETM */ 287 /* PM domains containing other special devices */
272 np = of_find_compatible_node(NULL, NULL, "arm,coresight-etm3x"); 288 for_each_matching_node_and_match(np, special_ids, &id)
273 if (np) { 289 add_special_pd(np, (enum pd_types)id->data);
274 debug_pd = of_parse_phandle(np, "power-domains", 0);
275 of_node_put(np);
276 }
277} 290}
278 291
279static void __init put_special_pds(void) 292static void __init put_special_pds(void)
280{ 293{
281 unsigned int i; 294 unsigned int i;
282 295
283 for (i = 0; i < num_cpu_pds; i++) 296 for (i = 0; i < num_special_pds; i++)
284 of_node_put(cpu_pds[i]); 297 of_node_put(special_pds[i].pd);
285 of_node_put(console_pd);
286 of_node_put(debug_pd);
287} 298}
288 299
289static bool __init pd_contains_cpu(const struct device_node *pd) 300static enum pd_types __init pd_type(const struct device_node *pd)
290{ 301{
291 unsigned int i; 302 unsigned int i;
292 303
293 for (i = 0; i < num_cpu_pds; i++) 304 for (i = 0; i < num_special_pds; i++)
294 if (pd == cpu_pds[i]) 305 if (pd == special_pds[i].pd)
295 return true; 306 return special_pds[i].type;
296 307
297 return false; 308 return PD_NORMAL;
298} 309}
299 310
300static void __init rmobile_setup_pm_domain(struct device_node *np, 311static void __init rmobile_setup_pm_domain(struct device_node *np,
@@ -302,18 +313,46 @@ static void __init rmobile_setup_pm_domain(struct device_node *np,
302{ 313{
303 const char *name = pd->genpd.name; 314 const char *name = pd->genpd.name;
304 315
305 if (pd_contains_cpu(np)) { 316 switch (pd_type(np)) {
317 case PD_CPU:
318 /*
319 * This domain contains the CPU core and therefore it should
320 * only be turned off if the CPU is not in use.
321 */
306 pr_debug("PM domain %s contains CPU\n", name); 322 pr_debug("PM domain %s contains CPU\n", name);
307 pd->gov = &pm_domain_always_on_gov; 323 pd->gov = &pm_domain_always_on_gov;
308 pd->suspend = rmobile_pd_suspend_cpu; 324 pd->suspend = rmobile_pd_suspend_busy;
309 } else if (np == console_pd) { 325 break;
326
327 case PD_CONSOLE:
310 pr_debug("PM domain %s contains serial console\n", name); 328 pr_debug("PM domain %s contains serial console\n", name);
311 pd->gov = &pm_domain_always_on_gov; 329 pd->gov = &pm_domain_always_on_gov;
312 pd->suspend = rmobile_pd_suspend_console; 330 pd->suspend = rmobile_pd_suspend_console;
313 } else if (np == debug_pd) { 331 break;
332
333 case PD_DEBUG:
334 /*
335 * This domain contains the Coresight-ETM hardware block and
336 * therefore it should only be turned off if the debug module
337 * is not in use.
338 */
314 pr_debug("PM domain %s contains Coresight-ETM\n", name); 339 pr_debug("PM domain %s contains Coresight-ETM\n", name);
315 pd->gov = &pm_domain_always_on_gov; 340 pd->gov = &pm_domain_always_on_gov;
316 pd->suspend = rmobile_pd_suspend_debug; 341 pd->suspend = rmobile_pd_suspend_busy;
342 break;
343
344 case PD_MEMCTL:
345 /*
346 * This domain contains a memory-controller and therefore it
347 * should only be turned off if memory is not in use.
348 */
349 pr_debug("PM domain %s contains MEMCTL\n", name);
350 pd->gov = &pm_domain_always_on_gov;
351 pd->suspend = rmobile_pd_suspend_busy;
352 break;
353
354 case PD_NORMAL:
355 break;
317 } 356 }
318 357
319 rmobile_init_pm_domain(pd); 358 rmobile_init_pm_domain(pd);