Skip to content

Commit c41336f

Browse files
ehristevstorulf
authored andcommitted
pmdomain: mediatek: fix race conditions with genpd
If the power domains are registered first with genpd and *after that* the driver attempts to power them on in the probe sequence, then it is possible that a race condition occurs if genpd tries to power them on in the same time. The same is valid for powering them off before unregistering them from genpd. Attempt to fix race conditions by first removing the domains from genpd and *after that* powering down domains. Also first power up the domains and *after that* register them to genpd. Fixes: 59b644b ("soc: mediatek: Add MediaTek SCPSYS power domains") Signed-off-by: Eugen Hristev <[email protected]> Cc: [email protected] Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Ulf Hansson <[email protected]>
1 parent f0e4a13 commit c41336f

File tree

1 file changed

+7
-8
lines changed

1 file changed

+7
-8
lines changed

drivers/pmdomain/mediatek/mtk-pm-domains.c

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -561,6 +561,11 @@ static int scpsys_add_subdomain(struct scpsys *scpsys, struct device_node *paren
561561
goto err_put_node;
562562
}
563563

564+
/* recursive call to add all subdomains */
565+
ret = scpsys_add_subdomain(scpsys, child);
566+
if (ret)
567+
goto err_put_node;
568+
564569
ret = pm_genpd_add_subdomain(parent_pd, child_pd);
565570
if (ret) {
566571
dev_err(scpsys->dev, "failed to add %s subdomain to parent %s\n",
@@ -570,11 +575,6 @@ static int scpsys_add_subdomain(struct scpsys *scpsys, struct device_node *paren
570575
dev_dbg(scpsys->dev, "%s add subdomain: %s\n", parent_pd->name,
571576
child_pd->name);
572577
}
573-
574-
/* recursive call to add all subdomains */
575-
ret = scpsys_add_subdomain(scpsys, child);
576-
if (ret)
577-
goto err_put_node;
578578
}
579579

580580
return 0;
@@ -588,9 +588,6 @@ static void scpsys_remove_one_domain(struct scpsys_domain *pd)
588588
{
589589
int ret;
590590

591-
if (scpsys_domain_is_on(pd))
592-
scpsys_power_off(&pd->genpd);
593-
594591
/*
595592
* We're in the error cleanup already, so we only complain,
596593
* but won't emit another error on top of the original one.
@@ -600,6 +597,8 @@ static void scpsys_remove_one_domain(struct scpsys_domain *pd)
600597
dev_err(pd->scpsys->dev,
601598
"failed to remove domain '%s' : %d - state may be inconsistent\n",
602599
pd->genpd.name, ret);
600+
if (scpsys_domain_is_on(pd))
601+
scpsys_power_off(&pd->genpd);
603602

604603
clk_bulk_put(pd->num_clks, pd->clks);
605604
clk_bulk_put(pd->num_subsys_clks, pd->subsys_clks);

0 commit comments

Comments
 (0)