soc: renesas: rcar-sysc: Make PM domain initialization more robust
The quirk for R-Car E3 ES1.0 added in commit086b399965
("soc: renesas: r8a77990-sysc: Add workaround for 3DG-{A,B}") makes the 3DG-A PM domain a subdomain of the 3DG-B PM domain. However, registering 3DG-A with its parent fails silently, as the 3DG-B PM domain hasn't been registered yet, and such failures are never reported. Fix this by: 1. Splitting PM Domain initialization in two steps, so all PM domains are registered before any child-parent links are established, 2. Reporting any failures in establishing child-parent relations. Check for and report pm_genpd_init() failures, too, as that function gained a return value in commit7eb231c337
("PM / Domains: Convert pm_genpd_init() to return an error code"). Fixes:086b399965
("soc: renesas: r8a77990-sysc: Add workaround for 3DG-{A,B}") Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be> Tested-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org> Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
This commit is contained in:
parent
086b399965
commit
977d5ba450
|
@ -194,11 +194,12 @@ static int rcar_sysc_pd_power_on(struct generic_pm_domain *genpd)
|
|||
|
||||
static bool has_cpg_mstp;
|
||||
|
||||
static void __init rcar_sysc_pd_setup(struct rcar_sysc_pd *pd)
|
||||
static int __init rcar_sysc_pd_setup(struct rcar_sysc_pd *pd)
|
||||
{
|
||||
struct generic_pm_domain *genpd = &pd->genpd;
|
||||
const char *name = pd->genpd.name;
|
||||
struct dev_power_governor *gov = &simple_qos_governor;
|
||||
int error;
|
||||
|
||||
if (pd->flags & PD_CPU) {
|
||||
/*
|
||||
|
@ -251,7 +252,11 @@ static void __init rcar_sysc_pd_setup(struct rcar_sysc_pd *pd)
|
|||
rcar_sysc_power_up(&pd->ch);
|
||||
|
||||
finalize:
|
||||
pm_genpd_init(genpd, gov, false);
|
||||
error = pm_genpd_init(genpd, gov, false);
|
||||
if (error)
|
||||
pr_err("Failed to init PM domain %s: %d\n", name, error);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static const struct of_device_id rcar_sysc_matches[] __initconst = {
|
||||
|
@ -375,6 +380,9 @@ static int __init rcar_sysc_pd_init(void)
|
|||
pr_debug("%pOF: syscier = 0x%08x\n", np, syscier);
|
||||
iowrite32(syscier, base + SYSCIER);
|
||||
|
||||
/*
|
||||
* First, create all PM domains
|
||||
*/
|
||||
for (i = 0; i < info->num_areas; i++) {
|
||||
const struct rcar_sysc_area *area = &info->areas[i];
|
||||
struct rcar_sysc_pd *pd;
|
||||
|
@ -397,14 +405,29 @@ static int __init rcar_sysc_pd_init(void)
|
|||
pd->ch.isr_bit = area->isr_bit;
|
||||
pd->flags = area->flags;
|
||||
|
||||
rcar_sysc_pd_setup(pd);
|
||||
if (area->parent >= 0)
|
||||
pm_genpd_add_subdomain(domains->domains[area->parent],
|
||||
&pd->genpd);
|
||||
error = rcar_sysc_pd_setup(pd);
|
||||
if (error)
|
||||
goto out_put;
|
||||
|
||||
domains->domains[area->isr_bit] = &pd->genpd;
|
||||
}
|
||||
|
||||
/*
|
||||
* Second, link all PM domains to their parents
|
||||
*/
|
||||
for (i = 0; i < info->num_areas; i++) {
|
||||
const struct rcar_sysc_area *area = &info->areas[i];
|
||||
|
||||
if (!area->name || area->parent < 0)
|
||||
continue;
|
||||
|
||||
error = pm_genpd_add_subdomain(domains->domains[area->parent],
|
||||
domains->domains[area->isr_bit]);
|
||||
if (error)
|
||||
pr_warn("Failed to add PM subdomain %s to parent %u\n",
|
||||
area->name, area->parent);
|
||||
}
|
||||
|
||||
error = of_genpd_add_provider_onecell(np, &domains->onecell_data);
|
||||
|
||||
out_put:
|
||||
|
|
Loading…
Reference in New Issue