Message ID | 1596705715-15320-7-git-send-email-weiyi.lu@mediatek.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Mediatek MT8183 scpsys support | expand |
On Thu, Aug 6, 2020 at 5:22 PM Weiyi Lu <weiyi.lu@mediatek.com> wrote: > > Try to list all the power domains of under power controller > node to show the dependency between each power domain directly > instead of filling the dependency in scp_soc_data. > And could be more clearly to group subsys clocks into power domain > sub node to introduce subsys clocks of bus protection in next patch. > > Signed-off-by: Weiyi Lu <weiyi.lu@mediatek.com> > --- [snip] > +static int traverse_scp(struct platform_device *pdev, struct scp *scp, > + const struct scp_domain_data *scp_domain_data) > +{ > + struct device *dev = &pdev->dev; > + struct device_node *np = dev->of_node; > + struct device_node *sub; > + int ret; > + > + INIT_LIST_HEAD(&scp->dep_links); > + > + for_each_available_child_of_node(np, sub) { > + ret = scpsys_get_domain(pdev, scp, sub, scp_domain_data); > + if (ret) { > + dev_err(&pdev->dev, "failed to handle node %pOFn: %d\n", sub, ret); minor comment: this error should not be printed if ret == -EPROBE_DEFER (use the new dev_err_probe?) > + goto err; > + } > + } > + > + return 0; > + > +err: > + of_node_put(sub); > + return ret; > +} [snip]
On Mon, 2020-09-28 at 15:14 +0800, Nicolas Boichat wrote: > On Thu, Aug 6, 2020 at 5:22 PM Weiyi Lu <weiyi.lu@mediatek.com> wrote: > > > > Try to list all the power domains of under power controller > > node to show the dependency between each power domain directly > > instead of filling the dependency in scp_soc_data. > > And could be more clearly to group subsys clocks into power domain > > sub node to introduce subsys clocks of bus protection in next patch. > > > > Signed-off-by: Weiyi Lu <weiyi.lu@mediatek.com> > > --- > [snip] > > +static int traverse_scp(struct platform_device *pdev, struct scp *scp, > > + const struct scp_domain_data *scp_domain_data) > > +{ > > + struct device *dev = &pdev->dev; > > + struct device_node *np = dev->of_node; > > + struct device_node *sub; > > + int ret; > > + > > + INIT_LIST_HEAD(&scp->dep_links); > > + > > + for_each_available_child_of_node(np, sub) { > > + ret = scpsys_get_domain(pdev, scp, sub, scp_domain_data); > > + if (ret) { > > + dev_err(&pdev->dev, "failed to handle node %pOFn: %d\n", sub, ret); > > minor comment: this error should not be printed if ret == > -EPROBE_DEFER (use the new dev_err_probe?) > You're right! I'll use dev_err_probe() instead if anyone is interested in this series. Thank you! > > + goto err; > > + } > > + } > > + > > + return 0; > > + > > +err: > > + of_node_put(sub); > > + return ret; > > +} > [snip]
On 30/09/2020 05:37, Weiyi Lu wrote: > On Mon, 2020-09-28 at 15:14 +0800, Nicolas Boichat wrote: >> On Thu, Aug 6, 2020 at 5:22 PM Weiyi Lu <weiyi.lu@mediatek.com> wrote: >>> >>> Try to list all the power domains of under power controller >>> node to show the dependency between each power domain directly >>> instead of filling the dependency in scp_soc_data. >>> And could be more clearly to group subsys clocks into power domain >>> sub node to introduce subsys clocks of bus protection in next patch. >>> >>> Signed-off-by: Weiyi Lu <weiyi.lu@mediatek.com> >>> --- >> [snip] >>> +static int traverse_scp(struct platform_device *pdev, struct scp *scp, >>> + const struct scp_domain_data *scp_domain_data) >>> +{ >>> + struct device *dev = &pdev->dev; >>> + struct device_node *np = dev->of_node; >>> + struct device_node *sub; >>> + int ret; >>> + >>> + INIT_LIST_HEAD(&scp->dep_links); >>> + >>> + for_each_available_child_of_node(np, sub) { >>> + ret = scpsys_get_domain(pdev, scp, sub, scp_domain_data); >>> + if (ret) { >>> + dev_err(&pdev->dev, "failed to handle node %pOFn: %d\n", sub, ret); >> >> minor comment: this error should not be printed if ret == >> -EPROBE_DEFER (use the new dev_err_probe?) >> > > You're right! I'll use dev_err_probe() instead if anyone is interested > in this series. Thank you! > I'd propose that we put all our effort of reviewing and testing into the series Enric send: https://lore.kernel.org/linux-mediatek/20200910172826.3074357-1-enric.balletbo@collabora.com/ Regards, Matthias >>> + goto err; >>> + } >>> + } >>> + >>> + return 0; >>> + >>> +err: >>> + of_node_put(sub); >>> + return ret; >>> +} >> [snip] >
diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c index 5a2c323..502b66f 100644 --- a/drivers/soc/mediatek/mtk-scpsys.c +++ b/drivers/soc/mediatek/mtk-scpsys.c @@ -182,11 +182,13 @@ struct scp { struct regmap *infracfg; struct regmap *smi_common; struct scp_ctrl_reg ctrl_reg; + struct list_head dep_links; }; struct scp_subdomain { int origin; int subdomain; + struct list_head list; }; struct scp_soc_data { @@ -513,6 +515,79 @@ static int init_basic_clks(struct platform_device *pdev, struct clk **clk, return 0; } +static int scpsys_get_domain_id(struct device_node *node, u32 *id) +{ + int ret; + + ret = of_property_read_u32(node, "reg", id); + if (ret) + pr_err("%pOFn: failed to retrieve domain id, ret=%d\n", node, ret); + + return ret; +} + +static int scpsys_get_domain(struct platform_device *pdev, struct scp *scp, + struct device_node *node, const struct scp_domain_data *data) +{ + struct scp_subdomain *dep_node; + struct device_node *sub; + u32 parent_id, child_id; + int ret; + + ret = scpsys_get_domain_id(node, &parent_id); + if (ret) + return ret; + + for_each_child_of_node(node, sub) { + ret = scpsys_get_domain_id(sub, &child_id); + if (ret) + goto out; + + dep_node = devm_kzalloc(&pdev->dev, sizeof(*dep_node), GFP_KERNEL); + if (!dep_node) { + ret = -ENOMEM; + goto out; + } + + dep_node->origin = parent_id; + dep_node->subdomain = child_id; + list_add(&dep_node->list, &scp->dep_links); + + scpsys_get_domain(pdev, scp, sub, data); + } + + return 0; + +out: + of_node_put(sub); + return ret; +} + +static int traverse_scp(struct platform_device *pdev, struct scp *scp, + const struct scp_domain_data *scp_domain_data) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct device_node *sub; + int ret; + + INIT_LIST_HEAD(&scp->dep_links); + + for_each_available_child_of_node(np, sub) { + ret = scpsys_get_domain(pdev, scp, sub, scp_domain_data); + if (ret) { + dev_err(&pdev->dev, "failed to handle node %pOFn: %d\n", sub, ret); + goto err; + } + } + + return 0; + +err: + of_node_put(sub); + return ret; +} + static struct scp *init_scp(struct platform_device *pdev, const struct scp_domain_data *scp_domain_data, int num, const struct scp_ctrl_reg *scp_ctrl_reg) @@ -582,6 +657,10 @@ static struct scp *init_scp(struct platform_device *pdev, pd_data->num_domains = num; + ret = traverse_scp(pdev, scp, scp_domain_data); + if (ret) + return ERR_PTR(ret); + for (i = 0; i < num; i++) { struct scp_domain *scpd = &scp->domains[i]; struct generic_pm_domain *genpd = &scpd->genpd; @@ -1208,7 +1287,7 @@ static int scpsys_probe(struct platform_device *pdev) const struct scp_soc_data *soc; struct scp *scp; struct genpd_onecell_data *pd_data; - int i, ret; + int i, ret = 0; soc = of_device_get_match_data(&pdev->dev); @@ -1220,15 +1299,23 @@ static int scpsys_probe(struct platform_device *pdev) pd_data = &scp->pd_data; - for (i = 0, sd = soc->subdomains; i < soc->num_subdomains; i++, sd++) { - ret = pm_genpd_add_subdomain(pd_data->domains[sd->origin], - pd_data->domains[sd->subdomain]); - if (ret && IS_ENABLED(CONFIG_PM)) - dev_err(&pdev->dev, "Failed to add subdomain: %d\n", - ret); + if (soc->subdomains && soc->num_subdomains) { + for (i = 0, sd = soc->subdomains; i < soc->num_subdomains; i++, sd++) { + ret = pm_genpd_add_subdomain(pd_data->domains[sd->origin], + pd_data->domains[sd->subdomain]); + if (ret && IS_ENABLED(CONFIG_PM)) + dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret); + } + } else { + list_for_each_entry(sd, &scp->dep_links, list) { + ret = pm_genpd_add_subdomain(pd_data->domains[sd->origin], + pd_data->domains[sd->subdomain]); + if (ret && IS_ENABLED(CONFIG_PM)) + dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret); + } } - return 0; + return ret; } static struct platform_driver scpsys_drv = {
Try to list all the power domains of under power controller node to show the dependency between each power domain directly instead of filling the dependency in scp_soc_data. And could be more clearly to group subsys clocks into power domain sub node to introduce subsys clocks of bus protection in next patch. Signed-off-by: Weiyi Lu <weiyi.lu@mediatek.com> --- drivers/soc/mediatek/mtk-scpsys.c | 103 +++++++++++++++++++++++++++++++++++--- 1 file changed, 95 insertions(+), 8 deletions(-)