From patchwork Thu Aug 6 09:21:49 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Weiyi Lu X-Patchwork-Id: 254056 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-11.4 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, MIME_BASE64_TEXT, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, UNPARSEABLE_RELAY,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A55A8C433FB for ; Thu, 6 Aug 2020 11:13:29 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D905222DFA for ; Thu, 6 Aug 2020 11:13:28 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=mediatek.com header.i=@mediatek.com header.b="Y3H2sHxr" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729098AbgHFJcG (ORCPT ); Thu, 6 Aug 2020 05:32:06 -0400 Received: from mailgw01.mediatek.com ([210.61.82.183]:51591 "EHLO mailgw01.mediatek.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1729008AbgHFJWr (ORCPT ); Thu, 6 Aug 2020 05:22:47 -0400 X-UUID: ca487f489f414c2db250a778624f327c-20200806 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; bh=WTzfa/t8bk8sxGScWdoKmOhtLiKTTktmTscE+vpAf7A=; b=Y3H2sHxrdbxhUsv7i6HYTKbS3X042OhpO2CCpu0wA9AMhC712bvUHe2uc5i+i2OK1Jak8EZ2chZgeufiJLiBCTjuWEveiiFqyrWwTquyUkHCUqB5P22LB5JpKT3G4McQLnougvVnp7mo+vmM3VysHW15UqhJ2pF6N7H2UMY+RVM=; X-UUID: ca487f489f414c2db250a778624f327c-20200806 Received: from mtkcas07.mediatek.inc [(172.21.101.84)] by mailgw01.mediatek.com (envelope-from ) (Cellopoint E-mail Firewall v4.1.10 Build 0809 with TLS) with ESMTP id 1798099553; Thu, 06 Aug 2020 17:22:01 +0800 Received: from mtkcas08.mediatek.inc (172.21.101.126) by mtkmbs07n2.mediatek.inc (172.21.101.141) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Thu, 6 Aug 2020 17:21:59 +0800 Received: from mtksdccf07.mediatek.inc (172.21.84.99) by mtkcas08.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Thu, 6 Aug 2020 17:21:59 +0800 From: Weiyi Lu To: Enric Balletbo Serra , Matthias Brugger , Nicolas Boichat , Rob Herring , Sascha Hauer CC: James Liao , Fan Chen , , , , , , Weiyi Lu Subject: [PATCH v17 06/12] soc: mediatek: Add support for hierarchical scpsys device node Date: Thu, 6 Aug 2020 17:21:49 +0800 Message-ID: <1596705715-15320-7-git-send-email-weiyi.lu@mediatek.com> X-Mailer: git-send-email 1.8.1.1.dirty In-Reply-To: <1596705715-15320-1-git-send-email-weiyi.lu@mediatek.com> References: <1596705715-15320-1-git-send-email-weiyi.lu@mediatek.com> MIME-Version: 1.0 X-MTK: N Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org 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 --- drivers/soc/mediatek/mtk-scpsys.c | 103 +++++++++++++++++++++++++++++++++++--- 1 file changed, 95 insertions(+), 8 deletions(-) -- 1.8.1.1.dirty 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 = {