Thread (16 messages) 16 messages, 3 authors, 2020-06-17

Re: [PATCH v15 06/11] soc: mediatek: Add subsys clock control for bus protection

flat view

From: Nicolas Boichat <hidden>
Date: 2020-06-04 02:29:35
Also in: linux-devicetree, linux-mediatek, lkml

On Thu, May 21, 2020 at 5:06 PM Weiyi Lu [off-list ref] wrote:
quoted hunk ↗ jump to hunk
For the bus protection operations, some subsys clocks need to be enabled
before releasing the protection, and vice versa.
But those subsys clocks could only be controlled once its corresponding
power domain is turned on first.
In this patch, we add the subsys clock control into its relevant steps.

Signed-off-by: Weiyi Lu <redacted>
---
 drivers/soc/mediatek/mtk-scpsys.c | 62 +++++++++++++++++++++++++++++++++++++--
 1 file changed, 60 insertions(+), 2 deletions(-)
diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c
index 59a525a..ef2c668 100644
--- a/drivers/soc/mediatek/mtk-scpsys.c
+++ b/drivers/soc/mediatek/mtk-scpsys.c
[snip]
        val |= PWR_ISO_BIT;
@@ -498,6 +511,39 @@ static int scpsys_power_off(struct generic_pm_domain *genpd)
        return ret;
 }

+static int init_subsys_clks(struct platform_device *pdev,
+               const char *prefix, struct clk **clk)
+{
+       struct device_node *node = pdev->dev.of_node;
+       u32 prefix_len, sub_clk_cnt = 0;
+       struct property *prop;
+       const char *clk_name;
+
+       prefix_len = strlen(prefix);
+
+       of_property_for_each_string(node, "clock-names", prop, clk_name) {
+               if (!strncmp(clk_name, prefix, prefix_len) &&
+                               (clk_name[prefix_len] == '-')) {
+                       if (sub_clk_cnt >= MAX_SUBSYS_CLKS) {
+                               dev_err(&pdev->dev,
+                                       "subsys clk out of range %d\n",
+                                       sub_clk_cnt);
+                               return -EINVAL;
+                       }
+
+                       clk[sub_clk_cnt] = devm_clk_get(&pdev->dev,
+                                               clk_name);
+
+                       if (IS_ERR(clk[sub_clk_cnt]))
+                               return PTR_ERR(clk[sub_clk_cnt]);
+
+                       sub_clk_cnt++;
+               }
+       }
+
+       return sub_clk_cnt;
+}
+
 static int init_basic_clks(struct platform_device *pdev, struct clk **clk,
                        const char * const *name)
 {
@@ -596,6 +642,18 @@ static struct scp *init_scp(struct platform_device *pdev,
                if (ret)
                        return ERR_PTR(ret);

+               if (data->subsys_clk_prefix) {
+                       ret = init_subsys_clks(pdev,
+                                       data->subsys_clk_prefix,
+                                       scpd->subsys_clk);
+                       if (ret < 0) {
+                               dev_err(&pdev->dev,
+                                       "%s: subsys clk unavailable\n",
+                                       data->name);
init_subsys_clks should already have printed an error (directly or
indirectly), so this is not needed.
+                               return ERR_PTR(ret);
+                       }
+               }
+
                genpd->name = data->name;
                genpd->power_off = scpsys_power_off;
                genpd->power_on = scpsys_power_on;
--
1.8.1.1.dirty
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help