On Thu, May 21, 2020 at 5:06 PM Weiyi Lu <weiyi.lu@xxxxxxxxxxxx> wrote: > > 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 <weiyi.lu@xxxxxxxxxxxx> > --- > 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