aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Hesselbarth <sebastian.hesselbarth@gmail.com>2015-05-04 17:04:16 -0400
committerMichael Turquette <mturquette@linaro.org>2015-05-08 14:22:30 -0400
commit0cd3be6e9a46f84ef7a42e1a5645d32ad547b12e (patch)
treebae0942e47885b7ddf6b6ea1897a53abf649b6e4
parentf94029d8801d7c27a94a3ea6c4967aa33c49c34b (diff)
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 <sebastian.hesselbarth@gmail.com> Reported-by: Michael Welling <mwelling@ieee.org> Reported-by: Jean-Francois Moine <moinejf@free.fr> Reported-by: Russell King <rmk+linux@arm.linux.org.uk> Tested-by: Michael Welling <mwelling@ieee.org> Tested-by: Jean-Francois Moine <moinejf@free.fr> Signed-off-by: Michael Turquette <mturquette@linaro.org>
-rw-r--r--drivers/clk/clk-si5351.c63
-rw-r--r--include/linux/platform_data/si5351.h4
2 files changed, 45 insertions, 22 deletions
diff --git a/drivers/clk/clk-si5351.c b/drivers/clk/clk-si5351.c
index 44ea107cfc67..30335d3b99af 100644
--- a/drivers/clk/clk-si5351.c
+++ b/drivers/clk/clk-si5351.c
@@ -1128,13 +1128,6 @@ static int si5351_dt_parse(struct i2c_client *client,
1128 if (!pdata) 1128 if (!pdata)
1129 return -ENOMEM; 1129 return -ENOMEM;
1130 1130
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
1138 /* 1131 /*
1139 * property silabs,pll-source : <num src>, [<..>] 1132 * property silabs,pll-source : <num src>, [<..>]
1140 * allow to selectively set pll source 1133 * allow to selectively set pll source
@@ -1328,8 +1321,22 @@ static int si5351_i2c_probe(struct i2c_client *client,
1328 i2c_set_clientdata(client, drvdata); 1321 i2c_set_clientdata(client, drvdata);
1329 drvdata->client = client; 1322 drvdata->client = client;
1330 drvdata->variant = variant; 1323 drvdata->variant = variant;
1331 drvdata->pxtal = pdata->clk_xtal; 1324 drvdata->pxtal = devm_clk_get(&client->dev, "xtal");
1332 drvdata->pclkin = pdata->clk_clkin; 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 }
1333 1340
1334 drvdata->regmap = devm_regmap_init_i2c(client, &si5351_regmap_config); 1341 drvdata->regmap = devm_regmap_init_i2c(client, &si5351_regmap_config);
1335 if (IS_ERR(drvdata->regmap)) { 1342 if (IS_ERR(drvdata->regmap)) {
@@ -1393,6 +1400,11 @@ static int si5351_i2c_probe(struct i2c_client *client,
1393 } 1400 }
1394 } 1401 }
1395 1402
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
1396 /* register xtal input clock gate */ 1408 /* register xtal input clock gate */
1397 memset(&init, 0, sizeof(init)); 1409 memset(&init, 0, sizeof(init));
1398 init.name = si5351_input_names[0]; 1410 init.name = si5351_input_names[0];
@@ -1407,7 +1419,8 @@ static int si5351_i2c_probe(struct i2c_client *client,
1407 clk = devm_clk_register(&client->dev, &drvdata->xtal); 1419 clk = devm_clk_register(&client->dev, &drvdata->xtal);
1408 if (IS_ERR(clk)) { 1420 if (IS_ERR(clk)) {
1409 dev_err(&client->dev, "unable to register %s\n", init.name); 1421 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;
1411 } 1424 }
1412 1425
1413 /* register clkin input clock gate */ 1426 /* register clkin input clock gate */
@@ -1425,7 +1438,8 @@ static int si5351_i2c_probe(struct i2c_client *client,
1425 if (IS_ERR(clk)) { 1438 if (IS_ERR(clk)) {
1426 dev_err(&client->dev, "unable to register %s\n", 1439 dev_err(&client->dev, "unable to register %s\n",
1427 init.name); 1440 init.name);
1428 return PTR_ERR(clk); 1441 ret = PTR_ERR(clk);
1442 goto err_clk;
1429 } 1443 }
1430 } 1444 }
1431 1445
@@ -1447,7 +1461,8 @@ static int si5351_i2c_probe(struct i2c_client *client,
1447 clk = devm_clk_register(&client->dev, &drvdata->pll[0].hw); 1461 clk = devm_clk_register(&client->dev, &drvdata->pll[0].hw);
1448 if (IS_ERR(clk)) { 1462 if (IS_ERR(clk)) {
1449 dev_err(&client->dev, "unable to register %s\n", init.name); 1463 dev_err(&client->dev, "unable to register %s\n", init.name);
1450 return -EINVAL; 1464 ret = PTR_ERR(clk);
1465 goto err_clk;
1451 } 1466 }
1452 1467
1453 /* register PLLB or VXCO (Si5351B) */ 1468 /* register PLLB or VXCO (Si5351B) */
@@ -1471,7 +1486,8 @@ static int si5351_i2c_probe(struct i2c_client *client,
1471 clk = devm_clk_register(&client->dev, &drvdata->pll[1].hw); 1486 clk = devm_clk_register(&client->dev, &drvdata->pll[1].hw);
1472 if (IS_ERR(clk)) { 1487 if (IS_ERR(clk)) {
1473 dev_err(&client->dev, "unable to register %s\n", init.name); 1488 dev_err(&client->dev, "unable to register %s\n", init.name);
1474 return -EINVAL; 1489 ret = PTR_ERR(clk);
1490 goto err_clk;
1475 } 1491 }
1476 1492
1477 /* register clk multisync and clk out divider */ 1493 /* register clk multisync and clk out divider */
@@ -1492,8 +1508,10 @@ static int si5351_i2c_probe(struct i2c_client *client,
1492 num_clocks * sizeof(*drvdata->onecell.clks), GFP_KERNEL); 1508 num_clocks * sizeof(*drvdata->onecell.clks), GFP_KERNEL);
1493 1509
1494 if (WARN_ON(!drvdata->msynth || !drvdata->clkout || 1510 if (WARN_ON(!drvdata->msynth || !drvdata->clkout ||
1495 !drvdata->onecell.clks)) 1511 !drvdata->onecell.clks)) {
1496 return -ENOMEM; 1512 ret = -ENOMEM;
1513 goto err_clk;
1514 }
1497 1515
1498 for (n = 0; n < num_clocks; n++) { 1516 for (n = 0; n < num_clocks; n++) {
1499 drvdata->msynth[n].num = n; 1517 drvdata->msynth[n].num = n;
@@ -1511,7 +1529,8 @@ static int si5351_i2c_probe(struct i2c_client *client,
1511 if (IS_ERR(clk)) { 1529 if (IS_ERR(clk)) {
1512 dev_err(&client->dev, "unable to register %s\n", 1530 dev_err(&client->dev, "unable to register %s\n",
1513 init.name); 1531 init.name);
1514 return -EINVAL; 1532 ret = PTR_ERR(clk);
1533 goto err_clk;
1515 } 1534 }
1516 } 1535 }
1517 1536
@@ -1538,7 +1557,8 @@ static int si5351_i2c_probe(struct i2c_client *client,
1538 if (IS_ERR(clk)) { 1557 if (IS_ERR(clk)) {
1539 dev_err(&client->dev, "unable to register %s\n", 1558 dev_err(&client->dev, "unable to register %s\n",
1540 init.name); 1559 init.name);
1541 return -EINVAL; 1560 ret = PTR_ERR(clk);
1561 goto err_clk;
1542 } 1562 }
1543 drvdata->onecell.clks[n] = clk; 1563 drvdata->onecell.clks[n] = clk;
1544 1564
@@ -1557,10 +1577,17 @@ static int si5351_i2c_probe(struct i2c_client *client,
1557 &drvdata->onecell); 1577 &drvdata->onecell);
1558 if (ret) { 1578 if (ret) {
1559 dev_err(&client->dev, "unable to add clk provider\n"); 1579 dev_err(&client->dev, "unable to add clk provider\n");
1560 return ret; 1580 goto err_clk;
1561 } 1581 }
1562 1582
1563 return 0; 1583 return 0;
1584
1585err_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;
1564} 1591}
1565 1592
1566static const struct i2c_device_id si5351_i2c_ids[] = { 1593static const struct i2c_device_id si5351_i2c_ids[] = {
diff --git a/include/linux/platform_data/si5351.h b/include/linux/platform_data/si5351.h
index a947ab8b441a..533d9807e543 100644
--- a/include/linux/platform_data/si5351.h
+++ b/include/linux/platform_data/si5351.h
@@ -5,8 +5,6 @@
5#ifndef __LINUX_PLATFORM_DATA_SI5351_H__ 5#ifndef __LINUX_PLATFORM_DATA_SI5351_H__
6#define __LINUX_PLATFORM_DATA_SI5351_H__ 6#define __LINUX_PLATFORM_DATA_SI5351_H__
7 7
8struct clk;
9
10/** 8/**
11 * enum si5351_pll_src - Si5351 pll clock source 9 * enum si5351_pll_src - Si5351 pll clock source
12 * @SI5351_PLL_SRC_DEFAULT: default, do not change eeprom config 10 * @SI5351_PLL_SRC_DEFAULT: default, do not change eeprom config
@@ -107,8 +105,6 @@ struct si5351_clkout_config {
107 * @clkout: array of clkout configuration 105 * @clkout: array of clkout configuration
108 */ 106 */
109struct si5351_platform_data { 107struct si5351_platform_data {
110 struct clk *clk_xtal;
111 struct clk *clk_clkin;
112 enum si5351_pll_src pll_src[2]; 108 enum si5351_pll_src pll_src[2];
113 struct si5351_clkout_config clkout[8]; 109 struct si5351_clkout_config clkout[8];
114}; 110};