Skip to content

Commit 9b13ff4

Browse files
robhancocksedbebarino
authored andcommitted
clk: si5341: Add sysfs properties to allow checking/resetting device faults
Add sysfs property files to allow viewing the current and latched states of the input present and PLL lock bits, and allow resetting the latched fault state. This allows manual checks or automated userspace polling for faults occurring after initialization. Signed-off-by: Robert Hancock <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Stephen Boyd <[email protected]>
1 parent 2f02c5e commit 9b13ff4

File tree

1 file changed

+96
-0
lines changed

1 file changed

+96
-0
lines changed

drivers/clk/clk-si5341.c

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1457,6 +1457,94 @@ static int si5341_clk_select_active_input(struct clk_si5341 *data)
14571457
return res;
14581458
}
14591459

1460+
static ssize_t input_present_show(struct device *dev,
1461+
struct device_attribute *attr,
1462+
char *buf)
1463+
{
1464+
struct clk_si5341 *data = dev_get_drvdata(dev);
1465+
u32 status;
1466+
int res = regmap_read(data->regmap, SI5341_STATUS, &status);
1467+
1468+
if (res < 0)
1469+
return res;
1470+
res = !(status & SI5341_STATUS_LOSREF);
1471+
return snprintf(buf, PAGE_SIZE, "%d\n", res);
1472+
}
1473+
static DEVICE_ATTR_RO(input_present);
1474+
1475+
static ssize_t input_present_sticky_show(struct device *dev,
1476+
struct device_attribute *attr,
1477+
char *buf)
1478+
{
1479+
struct clk_si5341 *data = dev_get_drvdata(dev);
1480+
u32 status;
1481+
int res = regmap_read(data->regmap, SI5341_STATUS_STICKY, &status);
1482+
1483+
if (res < 0)
1484+
return res;
1485+
res = !(status & SI5341_STATUS_LOSREF);
1486+
return snprintf(buf, PAGE_SIZE, "%d\n", res);
1487+
}
1488+
static DEVICE_ATTR_RO(input_present_sticky);
1489+
1490+
static ssize_t pll_locked_show(struct device *dev,
1491+
struct device_attribute *attr,
1492+
char *buf)
1493+
{
1494+
struct clk_si5341 *data = dev_get_drvdata(dev);
1495+
u32 status;
1496+
int res = regmap_read(data->regmap, SI5341_STATUS, &status);
1497+
1498+
if (res < 0)
1499+
return res;
1500+
res = !(status & SI5341_STATUS_LOL);
1501+
return snprintf(buf, PAGE_SIZE, "%d\n", res);
1502+
}
1503+
static DEVICE_ATTR_RO(pll_locked);
1504+
1505+
static ssize_t pll_locked_sticky_show(struct device *dev,
1506+
struct device_attribute *attr,
1507+
char *buf)
1508+
{
1509+
struct clk_si5341 *data = dev_get_drvdata(dev);
1510+
u32 status;
1511+
int res = regmap_read(data->regmap, SI5341_STATUS_STICKY, &status);
1512+
1513+
if (res < 0)
1514+
return res;
1515+
res = !(status & SI5341_STATUS_LOL);
1516+
return snprintf(buf, PAGE_SIZE, "%d\n", res);
1517+
}
1518+
static DEVICE_ATTR_RO(pll_locked_sticky);
1519+
1520+
static ssize_t clear_sticky_store(struct device *dev,
1521+
struct device_attribute *attr,
1522+
const char *buf, size_t count)
1523+
{
1524+
struct clk_si5341 *data = dev_get_drvdata(dev);
1525+
long val;
1526+
1527+
if (kstrtol(buf, 10, &val))
1528+
return -EINVAL;
1529+
if (val) {
1530+
int res = regmap_write(data->regmap, SI5341_STATUS_STICKY, 0);
1531+
1532+
if (res < 0)
1533+
return res;
1534+
}
1535+
return count;
1536+
}
1537+
static DEVICE_ATTR_WO(clear_sticky);
1538+
1539+
static const struct attribute *si5341_attributes[] = {
1540+
&dev_attr_input_present.attr,
1541+
&dev_attr_input_present_sticky.attr,
1542+
&dev_attr_pll_locked.attr,
1543+
&dev_attr_pll_locked_sticky.attr,
1544+
&dev_attr_clear_sticky.attr,
1545+
NULL
1546+
};
1547+
14601548
static int si5341_probe(struct i2c_client *client,
14611549
const struct i2c_device_id *id)
14621550
{
@@ -1687,6 +1775,12 @@ static int si5341_probe(struct i2c_client *client,
16871775
goto cleanup;
16881776
}
16891777

1778+
err = sysfs_create_files(&client->dev.kobj, si5341_attributes);
1779+
if (err) {
1780+
dev_err(&client->dev, "unable to create sysfs files\n");
1781+
goto cleanup;
1782+
}
1783+
16901784
/* Free the names, clk framework makes copies */
16911785
for (i = 0; i < data->num_synth; ++i)
16921786
devm_kfree(&client->dev, (void *)synth_clock_names[i]);
@@ -1706,6 +1800,8 @@ static int si5341_remove(struct i2c_client *client)
17061800
struct clk_si5341 *data = i2c_get_clientdata(client);
17071801
int i;
17081802

1803+
sysfs_remove_files(&client->dev.kobj, si5341_attributes);
1804+
17091805
for (i = 0; i < SI5341_MAX_NUM_OUTPUTS; ++i) {
17101806
if (data->clk[i].vddo_reg)
17111807
regulator_disable(data->clk[i].vddo_reg);

0 commit comments

Comments
 (0)