提交 f957b8de 编写于 作者: R Robert Hancock 提交者: Zheng Zengkai

clk: si5341: Check for input clock presence and PLL lock on startup

stable inclusion
from stable-5.10.50
commit 55aaba36d7188a1aae5052fccecac976f55d1d56
bugzilla: 174522 https://gitee.com/openeuler/kernel/issues/I4DNFY

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=55aaba36d7188a1aae5052fccecac976f55d1d56

--------------------------------

[ Upstream commit 71dcc4d1 ]

After initializing the device, wait for it to report that the input
clock is present and the PLL has locked before declaring success.

Fixes: 3044a860 ("clk: Add Si5341/Si5340 driver")
Signed-off-by: NRobert Hancock <robert.hancock@calian.com>
Link: https://lore.kernel.org/r/20210325192643.2190069-5-robert.hancock@calian.comSigned-off-by: NStephen Boyd <sboyd@kernel.org>
Signed-off-by: NSasha Levin <sashal@kernel.org>
Signed-off-by: NChen Jun <chenjun102@huawei.com>
Acked-by: NWeilong Chen <chenweilong@huawei.com>
Signed-off-by: NChen Jun <chenjun102@huawei.com>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
上级 5e2b6917
......@@ -92,6 +92,9 @@ struct clk_si5341_output_config {
#define SI5341_PN_BASE 0x0002
#define SI5341_DEVICE_REV 0x0005
#define SI5341_STATUS 0x000C
#define SI5341_LOS 0x000D
#define SI5341_STATUS_STICKY 0x0011
#define SI5341_LOS_STICKY 0x0012
#define SI5341_SOFT_RST 0x001C
#define SI5341_IN_SEL 0x0021
#define SI5341_DEVICE_READY 0x00FE
......@@ -99,6 +102,12 @@ struct clk_si5341_output_config {
#define SI5341_IN_EN 0x0949
#define SI5341_INX_TO_PFD_EN 0x094A
/* Status bits */
#define SI5341_STATUS_SYSINCAL BIT(0)
#define SI5341_STATUS_LOSXAXB BIT(1)
#define SI5341_STATUS_LOSREF BIT(2)
#define SI5341_STATUS_LOL BIT(3)
/* Input selection */
#define SI5341_IN_SEL_MASK 0x06
#define SI5341_IN_SEL_SHIFT 1
......@@ -1416,6 +1425,7 @@ static int si5341_probe(struct i2c_client *client,
unsigned int i;
struct clk_si5341_output_config config[SI5341_MAX_NUM_OUTPUTS];
bool initialization_required;
u32 status;
data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
if (!data)
......@@ -1583,6 +1593,22 @@ static int si5341_probe(struct i2c_client *client,
return err;
}
/* wait for device to report input clock present and PLL lock */
err = regmap_read_poll_timeout(data->regmap, SI5341_STATUS, status,
!(status & (SI5341_STATUS_LOSREF | SI5341_STATUS_LOL)),
10000, 250000);
if (err) {
dev_err(&client->dev, "Error waiting for input clock or PLL lock\n");
return err;
}
/* clear sticky alarm bits from initialization */
err = regmap_write(data->regmap, SI5341_STATUS_STICKY, 0);
if (err) {
dev_err(&client->dev, "unable to clear sticky status\n");
return err;
}
/* Free the names, clk framework makes copies */
for (i = 0; i < data->num_synth; ++i)
devm_kfree(&client->dev, (void *)synth_clock_names[i]);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册