return res;
 }
 
+static ssize_t input_present_show(struct device *dev,
+                                 struct device_attribute *attr,
+                                 char *buf)
+{
+       struct clk_si5341 *data = dev_get_drvdata(dev);
+       u32 status;
+       int res = regmap_read(data->regmap, SI5341_STATUS, &status);
+
+       if (res < 0)
+               return res;
+       res = !(status & SI5341_STATUS_LOSREF);
+       return snprintf(buf, PAGE_SIZE, "%d\n", res);
+}
+static DEVICE_ATTR_RO(input_present);
+
+static ssize_t input_present_sticky_show(struct device *dev,
+                                        struct device_attribute *attr,
+                                        char *buf)
+{
+       struct clk_si5341 *data = dev_get_drvdata(dev);
+       u32 status;
+       int res = regmap_read(data->regmap, SI5341_STATUS_STICKY, &status);
+
+       if (res < 0)
+               return res;
+       res = !(status & SI5341_STATUS_LOSREF);
+       return snprintf(buf, PAGE_SIZE, "%d\n", res);
+}
+static DEVICE_ATTR_RO(input_present_sticky);
+
+static ssize_t pll_locked_show(struct device *dev,
+                              struct device_attribute *attr,
+                              char *buf)
+{
+       struct clk_si5341 *data = dev_get_drvdata(dev);
+       u32 status;
+       int res = regmap_read(data->regmap, SI5341_STATUS, &status);
+
+       if (res < 0)
+               return res;
+       res = !(status & SI5341_STATUS_LOL);
+       return snprintf(buf, PAGE_SIZE, "%d\n", res);
+}
+static DEVICE_ATTR_RO(pll_locked);
+
+static ssize_t pll_locked_sticky_show(struct device *dev,
+                                     struct device_attribute *attr,
+                                     char *buf)
+{
+       struct clk_si5341 *data = dev_get_drvdata(dev);
+       u32 status;
+       int res = regmap_read(data->regmap, SI5341_STATUS_STICKY, &status);
+
+       if (res < 0)
+               return res;
+       res = !(status & SI5341_STATUS_LOL);
+       return snprintf(buf, PAGE_SIZE, "%d\n", res);
+}
+static DEVICE_ATTR_RO(pll_locked_sticky);
+
+static ssize_t clear_sticky_store(struct device *dev,
+                                 struct device_attribute *attr,
+                                 const char *buf, size_t count)
+{
+       struct clk_si5341 *data = dev_get_drvdata(dev);
+       long val;
+
+       if (kstrtol(buf, 10, &val))
+               return -EINVAL;
+       if (val) {
+               int res = regmap_write(data->regmap, SI5341_STATUS_STICKY, 0);
+
+               if (res < 0)
+                       return res;
+       }
+       return count;
+}
+static DEVICE_ATTR_WO(clear_sticky);
+
+static const struct attribute *si5341_attributes[] = {
+       &dev_attr_input_present.attr,
+       &dev_attr_input_present_sticky.attr,
+       &dev_attr_pll_locked.attr,
+       &dev_attr_pll_locked_sticky.attr,
+       &dev_attr_clear_sticky.attr,
+       NULL
+};
+
 static int si5341_probe(struct i2c_client *client,
                const struct i2c_device_id *id)
 {
                goto cleanup;
        }
 
+       err = sysfs_create_files(&client->dev.kobj, si5341_attributes);
+       if (err) {
+               dev_err(&client->dev, "unable to create sysfs files\n");
+               goto cleanup;
+       }
+
        /* Free the names, clk framework makes copies */
        for (i = 0; i < data->num_synth; ++i)
                 devm_kfree(&client->dev, (void *)synth_clock_names[i]);
        struct clk_si5341 *data = i2c_get_clientdata(client);
        int i;
 
+       sysfs_remove_files(&client->dev.kobj, si5341_attributes);
+
        for (i = 0; i < SI5341_MAX_NUM_OUTPUTS; ++i) {
                if (data->clk[i].vddo_reg)
                        regulator_disable(data->clk[i].vddo_reg);