Skip to content

Commit 0cd3be6

Browse files
shesselbaMichael Turquette
authored andcommitted
clk: si5351: Do not pass struct clk in platform_data
When registering clk-si5351 by platform_data, we should not pass struct clk for the reference clocks. Drop struct clk from platform_data and rework the driver to use devm_clk_get of named clock references. While at it, check for at least one valid input clock and properly prepare/ enable valid reference clocks. Signed-off-by: Sebastian Hesselbarth <[email protected]> Reported-by: Michael Welling <[email protected]> Reported-by: Jean-Francois Moine <[email protected]> Reported-by: Russell King <[email protected]> Tested-by: Michael Welling <[email protected]> Tested-by: Jean-Francois Moine <[email protected]> Signed-off-by: Michael Turquette <[email protected]>
1 parent f94029d commit 0cd3be6

File tree

2 files changed

+45
-22
lines changed

2 files changed

+45
-22
lines changed

drivers/clk/clk-si5351.c

Lines changed: 45 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1128,13 +1128,6 @@ static int si5351_dt_parse(struct i2c_client *client,
11281128
if (!pdata)
11291129
return -ENOMEM;
11301130

1131-
pdata->clk_xtal = of_clk_get(np, 0);
1132-
if (!IS_ERR(pdata->clk_xtal))
1133-
clk_put(pdata->clk_xtal);
1134-
pdata->clk_clkin = of_clk_get(np, 1);
1135-
if (!IS_ERR(pdata->clk_clkin))
1136-
clk_put(pdata->clk_clkin);
1137-
11381131
/*
11391132
* property silabs,pll-source : <num src>, [<..>]
11401133
* allow to selectively set pll source
@@ -1328,8 +1321,22 @@ static int si5351_i2c_probe(struct i2c_client *client,
13281321
i2c_set_clientdata(client, drvdata);
13291322
drvdata->client = client;
13301323
drvdata->variant = variant;
1331-
drvdata->pxtal = pdata->clk_xtal;
1332-
drvdata->pclkin = pdata->clk_clkin;
1324+
drvdata->pxtal = devm_clk_get(&client->dev, "xtal");
1325+
drvdata->pclkin = devm_clk_get(&client->dev, "clkin");
1326+
1327+
if (PTR_ERR(drvdata->pxtal) == -EPROBE_DEFER ||
1328+
PTR_ERR(drvdata->pclkin) == -EPROBE_DEFER)
1329+
return -EPROBE_DEFER;
1330+
1331+
/*
1332+
* Check for valid parent clock: VARIANT_A and VARIANT_B need XTAL,
1333+
* VARIANT_C can have CLKIN instead.
1334+
*/
1335+
if (IS_ERR(drvdata->pxtal) &&
1336+
(drvdata->variant != SI5351_VARIANT_C || IS_ERR(drvdata->pclkin))) {
1337+
dev_err(&client->dev, "missing parent clock\n");
1338+
return -EINVAL;
1339+
}
13331340

13341341
drvdata->regmap = devm_regmap_init_i2c(client, &si5351_regmap_config);
13351342
if (IS_ERR(drvdata->regmap)) {
@@ -1393,6 +1400,11 @@ static int si5351_i2c_probe(struct i2c_client *client,
13931400
}
13941401
}
13951402

1403+
if (!IS_ERR(drvdata->pxtal))
1404+
clk_prepare_enable(drvdata->pxtal);
1405+
if (!IS_ERR(drvdata->pclkin))
1406+
clk_prepare_enable(drvdata->pclkin);
1407+
13961408
/* register xtal input clock gate */
13971409
memset(&init, 0, sizeof(init));
13981410
init.name = si5351_input_names[0];
@@ -1407,7 +1419,8 @@ static int si5351_i2c_probe(struct i2c_client *client,
14071419
clk = devm_clk_register(&client->dev, &drvdata->xtal);
14081420
if (IS_ERR(clk)) {
14091421
dev_err(&client->dev, "unable to register %s\n", init.name);
1410-
return PTR_ERR(clk);
1422+
ret = PTR_ERR(clk);
1423+
goto err_clk;
14111424
}
14121425

14131426
/* register clkin input clock gate */
@@ -1425,7 +1438,8 @@ static int si5351_i2c_probe(struct i2c_client *client,
14251438
if (IS_ERR(clk)) {
14261439
dev_err(&client->dev, "unable to register %s\n",
14271440
init.name);
1428-
return PTR_ERR(clk);
1441+
ret = PTR_ERR(clk);
1442+
goto err_clk;
14291443
}
14301444
}
14311445

@@ -1447,7 +1461,8 @@ static int si5351_i2c_probe(struct i2c_client *client,
14471461
clk = devm_clk_register(&client->dev, &drvdata->pll[0].hw);
14481462
if (IS_ERR(clk)) {
14491463
dev_err(&client->dev, "unable to register %s\n", init.name);
1450-
return -EINVAL;
1464+
ret = PTR_ERR(clk);
1465+
goto err_clk;
14511466
}
14521467

14531468
/* register PLLB or VXCO (Si5351B) */
@@ -1471,7 +1486,8 @@ static int si5351_i2c_probe(struct i2c_client *client,
14711486
clk = devm_clk_register(&client->dev, &drvdata->pll[1].hw);
14721487
if (IS_ERR(clk)) {
14731488
dev_err(&client->dev, "unable to register %s\n", init.name);
1474-
return -EINVAL;
1489+
ret = PTR_ERR(clk);
1490+
goto err_clk;
14751491
}
14761492

14771493
/* register clk multisync and clk out divider */
@@ -1492,8 +1508,10 @@ static int si5351_i2c_probe(struct i2c_client *client,
14921508
num_clocks * sizeof(*drvdata->onecell.clks), GFP_KERNEL);
14931509

14941510
if (WARN_ON(!drvdata->msynth || !drvdata->clkout ||
1495-
!drvdata->onecell.clks))
1496-
return -ENOMEM;
1511+
!drvdata->onecell.clks)) {
1512+
ret = -ENOMEM;
1513+
goto err_clk;
1514+
}
14971515

14981516
for (n = 0; n < num_clocks; n++) {
14991517
drvdata->msynth[n].num = n;
@@ -1511,7 +1529,8 @@ static int si5351_i2c_probe(struct i2c_client *client,
15111529
if (IS_ERR(clk)) {
15121530
dev_err(&client->dev, "unable to register %s\n",
15131531
init.name);
1514-
return -EINVAL;
1532+
ret = PTR_ERR(clk);
1533+
goto err_clk;
15151534
}
15161535
}
15171536

@@ -1538,7 +1557,8 @@ static int si5351_i2c_probe(struct i2c_client *client,
15381557
if (IS_ERR(clk)) {
15391558
dev_err(&client->dev, "unable to register %s\n",
15401559
init.name);
1541-
return -EINVAL;
1560+
ret = PTR_ERR(clk);
1561+
goto err_clk;
15421562
}
15431563
drvdata->onecell.clks[n] = clk;
15441564

@@ -1557,10 +1577,17 @@ static int si5351_i2c_probe(struct i2c_client *client,
15571577
&drvdata->onecell);
15581578
if (ret) {
15591579
dev_err(&client->dev, "unable to add clk provider\n");
1560-
return ret;
1580+
goto err_clk;
15611581
}
15621582

15631583
return 0;
1584+
1585+
err_clk:
1586+
if (!IS_ERR(drvdata->pxtal))
1587+
clk_disable_unprepare(drvdata->pxtal);
1588+
if (!IS_ERR(drvdata->pclkin))
1589+
clk_disable_unprepare(drvdata->pclkin);
1590+
return ret;
15641591
}
15651592

15661593
static const struct i2c_device_id si5351_i2c_ids[] = {

include/linux/platform_data/si5351.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55
#ifndef __LINUX_PLATFORM_DATA_SI5351_H__
66
#define __LINUX_PLATFORM_DATA_SI5351_H__
77

8-
struct clk;
9-
108
/**
119
* enum si5351_pll_src - Si5351 pll clock source
1210
* @SI5351_PLL_SRC_DEFAULT: default, do not change eeprom config
@@ -107,8 +105,6 @@ struct si5351_clkout_config {
107105
* @clkout: array of clkout configuration
108106
*/
109107
struct si5351_platform_data {
110-
struct clk *clk_xtal;
111-
struct clk *clk_clkin;
112108
enum si5351_pll_src pll_src[2];
113109
struct si5351_clkout_config clkout[8];
114110
};

0 commit comments

Comments
 (0)