diff options
author | Olof Johansson <[email protected]> | 2015-01-21 17:19:05 -0800 |
---|---|---|
committer | Olof Johansson <[email protected]> | 2015-01-21 17:19:05 -0800 |
commit | f50f7070e5de59a168e45831c1e667f04583f563 (patch) | |
tree | d8116eb25aebc6f1ffd3fb043142252bf708c269 | |
parent | a71596933cf792dacc3c5080df298c0fccef1d94 (diff) | |
parent | 1632ff162f305f38667632c465e4bfaab8ef87a2 (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 <[email protected]>
-rw-r--r-- | arch/arm/mach-shmobile/pm-rmobile.c | 155 |
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[], #else /* !CONFIG_ARCH_SHMOBILE_LEGACY */ -static int rmobile_pd_suspend_cpu(void) +static int rmobile_pd_suspend_busy(void) { /* - * This domain contains the CPU core and therefore it should - * only be turned off if the CPU is not in use. + * This domain should not be turned off. */ return -EBUSY; } @@ -218,83 +217,95 @@ static int rmobile_pd_suspend_console(void) return console_suspend_enabled ? 0 : -EBUSY; } -static int rmobile_pd_suspend_debug(void) -{ - /* - * This domain contains the Coresight-ETM hardware block and - * therefore it should only be turned off if the debug module is - * not in use. - */ - return -EBUSY; -} +enum pd_types { + PD_NORMAL, + PD_CPU, + PD_CONSOLE, + PD_DEBUG, + PD_MEMCTL, +}; -#define MAX_NUM_CPU_PDS 8 +#define MAX_NUM_SPECIAL_PDS 16 -static unsigned int num_cpu_pds __initdata; -static struct device_node *cpu_pds[MAX_NUM_CPU_PDS] __initdata; -static struct device_node *console_pd __initdata; -static struct device_node *debug_pd __initdata; +static struct special_pd { + struct device_node *pd; + enum pd_types type; +} special_pds[MAX_NUM_SPECIAL_PDS] __initdata; -static void __init get_special_pds(void) +static unsigned int num_special_pds __initdata; + +static const struct of_device_id special_ids[] __initconst = { + { .compatible = "arm,coresight-etm3x", .data = (void *)PD_DEBUG }, + { .compatible = "renesas,dbsc-r8a73a4", .data = (void *)PD_MEMCTL, }, + { .compatible = "renesas,dbsc3-r8a7740", .data = (void *)PD_MEMCTL, }, + { .compatible = "renesas,sbsc-sh73a0", .data = (void *)PD_MEMCTL, }, + { /* sentinel */ }, +}; + +static void __init add_special_pd(struct device_node *np, enum pd_types type) { - struct device_node *np, *pd; unsigned int i; + struct device_node *pd; - /* PM domains containing CPUs */ - for_each_node_by_type(np, "cpu") { - pd = of_parse_phandle(np, "power-domains", 0); - if (!pd) - continue; - - for (i = 0; i < num_cpu_pds; i++) - if (pd == cpu_pds[i]) - break; + pd = of_parse_phandle(np, "power-domains", 0); + if (!pd) + return; - if (i < num_cpu_pds) { + for (i = 0; i < num_special_pds; i++) + if (pd == special_pds[i].pd && type == special_pds[i].type) { of_node_put(pd); - continue; + return; } - if (num_cpu_pds == MAX_NUM_CPU_PDS) { - pr_warn("Too many CPU PM domains\n"); - of_node_put(pd); - continue; - } - - cpu_pds[num_cpu_pds++] = pd; + if (num_special_pds == ARRAY_SIZE(special_pds)) { + pr_warn("Too many special PM domains\n"); + of_node_put(pd); + return; } + pr_debug("Special PM domain %s type %d for %s\n", pd->name, type, + np->full_name); + + special_pds[num_special_pds].pd = pd; + special_pds[num_special_pds].type = type; + num_special_pds++; +} + +static void __init get_special_pds(void) +{ + struct device_node *np; + const struct of_device_id *id; + + /* PM domains containing CPUs */ + for_each_node_by_type(np, "cpu") + add_special_pd(np, PD_CPU); + /* PM domain containing console */ if (of_stdout) - console_pd = of_parse_phandle(of_stdout, "power-domains", 0); + add_special_pd(of_stdout, PD_CONSOLE); - /* PM domain containing Coresight-ETM */ - np = of_find_compatible_node(NULL, NULL, "arm,coresight-etm3x"); - if (np) { - debug_pd = of_parse_phandle(np, "power-domains", 0); - of_node_put(np); - } + /* PM domains containing other special devices */ + for_each_matching_node_and_match(np, special_ids, &id) + add_special_pd(np, (enum pd_types)id->data); } static void __init put_special_pds(void) { unsigned int i; - for (i = 0; i < num_cpu_pds; i++) - of_node_put(cpu_pds[i]); - of_node_put(console_pd); - of_node_put(debug_pd); + for (i = 0; i < num_special_pds; i++) + of_node_put(special_pds[i].pd); } -static bool __init pd_contains_cpu(const struct device_node *pd) +static enum pd_types __init pd_type(const struct device_node *pd) { unsigned int i; - for (i = 0; i < num_cpu_pds; i++) - if (pd == cpu_pds[i]) - return true; + for (i = 0; i < num_special_pds; i++) + if (pd == special_pds[i].pd) + return special_pds[i].type; - return false; + return PD_NORMAL; } static 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, { const char *name = pd->genpd.name; - if (pd_contains_cpu(np)) { + switch (pd_type(np)) { + case PD_CPU: + /* + * This domain contains the CPU core and therefore it should + * only be turned off if the CPU is not in use. + */ pr_debug("PM domain %s contains CPU\n", name); pd->gov = &pm_domain_always_on_gov; - pd->suspend = rmobile_pd_suspend_cpu; - } else if (np == console_pd) { + pd->suspend = rmobile_pd_suspend_busy; + break; + + case PD_CONSOLE: pr_debug("PM domain %s contains serial console\n", name); pd->gov = &pm_domain_always_on_gov; pd->suspend = rmobile_pd_suspend_console; - } else if (np == debug_pd) { + break; + + case PD_DEBUG: + /* + * This domain contains the Coresight-ETM hardware block and + * therefore it should only be turned off if the debug module + * is not in use. + */ pr_debug("PM domain %s contains Coresight-ETM\n", name); pd->gov = &pm_domain_always_on_gov; - pd->suspend = rmobile_pd_suspend_debug; + pd->suspend = rmobile_pd_suspend_busy; + break; + + case PD_MEMCTL: + /* + * This domain contains a memory-controller and therefore it + * should only be turned off if memory is not in use. + */ + pr_debug("PM domain %s contains MEMCTL\n", name); + pd->gov = &pm_domain_always_on_gov; + pd->suspend = rmobile_pd_suspend_busy; + break; + + case PD_NORMAL: + break; } rmobile_init_pm_domain(pd); |