]> www.infradead.org Git - users/hch/misc.git/commitdiff
clk: loongson2: Avoid hardcoding firmware name of the reference clock
authorYao Zi <ziyao@disroot.org>
Fri, 19 Sep 2025 14:26:46 +0000 (14:26 +0000)
committerStephen Boyd <sboyd@kernel.org>
Sun, 21 Sep 2025 19:48:49 +0000 (12:48 -0700)
Loongson-2K0300 requires a reference clock with a frequency different
from previous SoCs (120MHz v.s. 100MHz), thus hardcoding the firmware
name of the reference clock as ref_100m isn't a good idea.

This patch retrives the clock name of the reference clock dynamically
during probe, avoiding the hardcoded pdata structure and preparing for
support of future SoCs.

Signed-off-by: Yao Zi <ziyao@disroot.org>
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
drivers/clk/clk-loongson2.c

index 7a916c7d2718a0c69d644b61c742eeecfc64a9cf..52a9f1c2794a9d9dfab4d1cab64a8c16fe2bd923 100644 (file)
 #include <linux/io-64-nonatomic-lo-hi.h>
 #include <dt-bindings/clock/loongson,ls2k-clk.h>
 
-static const struct clk_parent_data pdata[] = {
-       { .fw_name = "ref_100m", },
-};
-
 enum loongson2_clk_type {
        CLK_TYPE_PLL,
        CLK_TYPE_SCALE,
@@ -275,7 +271,8 @@ static const struct clk_ops loongson2_freqscale_recalc_ops = {
        .recalc_rate = loongson2_freqscale_recalc_rate,
 };
 
-static struct clk_hw *loongson2_clk_register(struct loongson2_clk_provider *clp,
+static struct clk_hw *loongson2_clk_register(const char *parent,
+                                            struct loongson2_clk_provider *clp,
                                             const struct loongson2_clk_board_info *cld,
                                             const struct clk_ops *ops)
 {
@@ -292,11 +289,7 @@ static struct clk_hw *loongson2_clk_register(struct loongson2_clk_provider *clp,
        init.ops   = ops;
        init.flags = 0;
        init.num_parents = 1;
-
-       if (!cld->parent_name)
-               init.parent_data = pdata;
-       else
-               init.parent_names = &cld->parent_name;
+       init.parent_names = &parent;
 
        clk->reg        = clp->base + cld->reg_offset;
        clk->div_shift  = cld->div_shift;
@@ -321,11 +314,17 @@ static int loongson2_clk_probe(struct platform_device *pdev)
        struct device *dev = &pdev->dev;
        struct loongson2_clk_provider *clp;
        const struct loongson2_clk_board_info *p, *data;
+       const char *refclk_name, *parent_name;
 
        data = device_get_match_data(dev);
        if (!data)
                return -EINVAL;
 
+       refclk_name = of_clk_get_parent_name(dev->of_node, 0);
+       if (IS_ERR(refclk_name))
+               return dev_err_probe(dev, PTR_ERR(refclk_name),
+                                    "failed to get refclk name\n");
+
        for (p = data; p->name; p++)
                clks_num = max(clks_num, p->id + 1);
 
@@ -347,18 +346,20 @@ static int loongson2_clk_probe(struct platform_device *pdev)
 
        for (i = 0; i < clks_num; i++) {
                p = &data[i];
+               parent_name = p->parent_name ? p->parent_name : refclk_name;
+
                switch (p->type) {
                case CLK_TYPE_PLL:
-                       hw = loongson2_clk_register(clp, p,
+                       hw = loongson2_clk_register(parent_name, clp, p,
                                                    &loongson2_pll_recalc_ops);
                        break;
                case CLK_TYPE_SCALE:
-                       hw = loongson2_clk_register(clp, p,
+                       hw = loongson2_clk_register(parent_name, clp, p,
                                                    &loongson2_freqscale_recalc_ops);
                        break;
                case CLK_TYPE_DIVIDER:
                        hw = devm_clk_hw_register_divider(dev, p->name,
-                                                         p->parent_name, 0,
+                                                         parent_name, 0,
                                                          clp->base + p->reg_offset,
                                                          p->div_shift, p->div_width,
                                                          CLK_DIVIDER_ONE_BASED |
@@ -366,15 +367,15 @@ static int loongson2_clk_probe(struct platform_device *pdev)
                                                          &clp->clk_lock);
                        break;
                case CLK_TYPE_GATE:
-                       hw = devm_clk_hw_register_gate(dev, p->name, p->parent_name,
+                       hw = devm_clk_hw_register_gate(dev, p->name, parent_name,
                                                       p->flags,
                                                       clp->base + p->reg_offset,
                                                       p->bit_idx, 0,
                                                       &clp->clk_lock);
                        break;
                case CLK_TYPE_FIXED:
-                       hw = devm_clk_hw_register_fixed_rate_parent_data(dev, p->name, pdata,
-                                                                        0, p->fixed_rate);
+                       hw = devm_clk_hw_register_fixed_rate(dev, p->name, parent_name,
+                                                            0, p->fixed_rate);
                        break;
                default:
                        return dev_err_probe(dev, -EINVAL, "Invalid clk type\n");