On Tue, Nov 26, 2024 at 11:44:29PM +0000, Bryan O'Donoghue wrote: > When a clock-controller has multiple power-domains we need to attach parent > GDSCs in that clock-controller as subdomains of each of the power-domains. > This is a bit sparse, in particular it would be nice to capture the open questions about whether every GDSC always should be parented by all defined power-domains, and if performance-state should be applied equally across all those power-domains (and/or if this actually happens). PS. Please drop "drivers: " and s/subdomain list/GDSC/ in subject. Regards, Bjorn > Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@xxxxxxxxxx> > --- > drivers/clk/qcom/common.c | 1 + > drivers/clk/qcom/gdsc.c | 35 +++++++++++++++++++++++++++++++++++ > drivers/clk/qcom/gdsc.h | 1 + > 3 files changed, 37 insertions(+) > > diff --git a/drivers/clk/qcom/common.c b/drivers/clk/qcom/common.c > index 7727295c57c8f6672d46d2380e1ff5ec2ac68d42..58a8397eefe51da237a4285d4e7cee967e19948f 100644 > --- a/drivers/clk/qcom/common.c > +++ b/drivers/clk/qcom/common.c > @@ -338,6 +338,7 @@ int qcom_cc_really_probe(struct device *dev, > scd->dev = dev; > scd->scs = desc->gdscs; > scd->num = desc->num_gdscs; > + scd->pd_list = cc->pd_list; > ret = gdsc_register(scd, &reset->rcdev, regmap); > if (ret) > return ret; > diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c > index 4fc6f957d0b846cc90e50ef243f23a7a27e66899..cb4afa6d584899f3dafa380d5e01be6de9711737 100644 > --- a/drivers/clk/qcom/gdsc.c > +++ b/drivers/clk/qcom/gdsc.c > @@ -506,6 +506,36 @@ static int gdsc_init(struct gdsc *sc) > return ret; > } > > +static int gdsc_add_subdomain_list(struct dev_pm_domain_list *pd_list, > + struct generic_pm_domain *subdomain) > +{ > + int i, ret; > + > + for (i = 0; i < pd_list->num_pds; i++) { > + struct device *dev = pd_list->pd_devs[i]; > + struct generic_pm_domain *genpd = pd_to_genpd(dev->pm_domain); > + > + ret = pm_genpd_add_subdomain(genpd, subdomain); > + if (ret) > + return ret; > + } > + > + return 0; > +} > + > +static void gdsc_remove_subdomain_list(struct dev_pm_domain_list *pd_list, > + struct generic_pm_domain *subdomain) > +{ > + int i; > + > + for (i = 0; i < pd_list->num_pds; i++) { > + struct device *dev = pd_list->pd_devs[i]; > + struct generic_pm_domain *genpd = pd_to_genpd(dev->pm_domain); > + > + pm_genpd_remove_subdomain(genpd, subdomain); > + } > +} > + > int gdsc_register(struct gdsc_desc *desc, > struct reset_controller_dev *rcdev, struct regmap *regmap) > { > @@ -558,6 +588,9 @@ int gdsc_register(struct gdsc_desc *desc, > ret = pm_genpd_add_subdomain(scs[i]->parent, &scs[i]->pd); > else if (!IS_ERR_OR_NULL(dev->pm_domain)) > ret = pm_genpd_add_subdomain(pd_to_genpd(dev->pm_domain), &scs[i]->pd); > + else if (desc->pd_list) > + ret = gdsc_add_subdomain_list(desc->pd_list, &scs[i]->pd); > + > if (ret) > return ret; > } > @@ -580,6 +613,8 @@ void gdsc_unregister(struct gdsc_desc *desc) > pm_genpd_remove_subdomain(scs[i]->parent, &scs[i]->pd); > else if (!IS_ERR_OR_NULL(dev->pm_domain)) > pm_genpd_remove_subdomain(pd_to_genpd(dev->pm_domain), &scs[i]->pd); > + else if (desc->pd_list) > + gdsc_remove_subdomain_list(desc->pd_list, &scs[i]->pd); > } > of_genpd_del_provider(dev->of_node); > } > diff --git a/drivers/clk/qcom/gdsc.h b/drivers/clk/qcom/gdsc.h > index 1e2779b823d1c8ca077c9b4cd0a0dbdf5f9457ef..dd843e86c05b2f30e6d9e978681580016333839d 100644 > --- a/drivers/clk/qcom/gdsc.h > +++ b/drivers/clk/qcom/gdsc.h > @@ -80,6 +80,7 @@ struct gdsc_desc { > struct device *dev; > struct gdsc **scs; > size_t num; > + struct dev_pm_domain_list *pd_list; > }; > > #ifdef CONFIG_QCOM_GDSC > > -- > 2.45.2 >