diff options
| author | Thierry Reding <treding@nvidia.com> | 2025-02-03 14:51:18 +0100 |
|---|---|---|
| committer | Thierry Reding <treding@nvidia.com> | 2026-01-18 08:48:29 +0100 |
| commit | bb946b0e118dc95160d2313474b2ca4de771f82b (patch) | |
| tree | 0da919f52517b5947154c6fb87e639254625df2b | |
| parent | b2a3e8200056480219d4bc44c3403cacf0125495 (diff) | |
soc/tegra: pmc: Use PMC context embedded in powergates
The powergates exposed by the PMC have a pointer to the PMC context
embedded. Use that embedded reference instead of relying on a global
variable.
For the core power domain a new structure needs to be introduced to wrap
the generic PM domain and store the PMC context.
Signed-off-by: Thierry Reding <treding@nvidia.com>
| -rw-r--r-- | drivers/soc/tegra/pmc.c | 34 |
1 files changed, 24 insertions, 10 deletions
diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c index f215396206f1..da8890520fc8 100644 --- a/drivers/soc/tegra/pmc.c +++ b/drivers/soc/tegra/pmc.c @@ -268,6 +268,17 @@ static const struct pmc_clk_init_data tegra_pmc_clks_data[] = { }, }; +struct tegra_pmc_core_pd { + struct generic_pm_domain genpd; + struct tegra_pmc *pmc; +}; + +static inline struct tegra_pmc_core_pd * +to_core_pd(struct generic_pm_domain *genpd) +{ + return container_of(genpd, struct tegra_pmc_core_pd, genpd); +} + struct tegra_powergate { struct generic_pm_domain genpd; struct tegra_pmc *pmc; @@ -1387,6 +1398,8 @@ static int tegra_pmc_core_pd_set_performance_state(struct generic_pm_domain *genpd, unsigned int level) { + struct tegra_pmc_core_pd *pd = to_core_pd(genpd); + struct tegra_pmc *pmc = pd->pmc; struct dev_pm_opp *opp; int err; @@ -1414,30 +1427,31 @@ tegra_pmc_core_pd_set_performance_state(struct generic_pm_domain *genpd, static int tegra_pmc_core_pd_add(struct tegra_pmc *pmc, struct device_node *np) { - struct generic_pm_domain *genpd; const char *rname[] = { "core", NULL}; + struct tegra_pmc_core_pd *pd; int err; - genpd = devm_kzalloc(pmc->dev, sizeof(*genpd), GFP_KERNEL); - if (!genpd) + pd = devm_kzalloc(pmc->dev, sizeof(*pd), GFP_KERNEL); + if (!pd) return -ENOMEM; - genpd->name = "core"; - genpd->flags = GENPD_FLAG_NO_SYNC_STATE; - genpd->set_performance_state = tegra_pmc_core_pd_set_performance_state; + pd->genpd.name = "core"; + pd->genpd.flags = GENPD_FLAG_NO_SYNC_STATE; + pd->genpd.set_performance_state = tegra_pmc_core_pd_set_performance_state; + pd->pmc = pmc; err = devm_pm_opp_set_regulators(pmc->dev, rname); if (err) return dev_err_probe(pmc->dev, err, "failed to set core OPP regulator\n"); - err = pm_genpd_init(genpd, NULL, false); + err = pm_genpd_init(&pd->genpd, NULL, false); if (err) { dev_err(pmc->dev, "failed to init core genpd: %d\n", err); return err; } - err = of_genpd_add_provider_simple(np, genpd); + err = of_genpd_add_provider_simple(np, &pd->genpd); if (err) { dev_err(pmc->dev, "failed to add core genpd: %d\n", err); goto remove_genpd; @@ -1446,7 +1460,7 @@ static int tegra_pmc_core_pd_add(struct tegra_pmc *pmc, struct device_node *np) return 0; remove_genpd: - pm_genpd_remove(genpd); + pm_genpd_remove(&pd->genpd); return err; } @@ -1509,7 +1523,7 @@ static void tegra_powergate_remove(struct generic_pm_domain *genpd) kfree(pg->clks); - set_bit(pg->id, pmc->powergates_available); + set_bit(pg->id, pg->pmc->powergates_available); kfree(pg); } |
