1
0

clk: loongson2: Avoid hardcoding firmware name of the reference clock

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>
This commit is contained in:
Yao Zi
2025-09-19 14:26:46 +00:00
committed by Stephen Boyd
parent 1ba5395c6a
commit 158ddb87b1

View File

@@ -13,10 +13,6 @@
#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");