#ifdef CONFIG_SYSFS
/**
 * sysfs_show_current_clocksources - sysfs interface for current clocksource
 * @dev: unused
 * @attr: unused
 * @buf: char buffer to be filled with clocksource list
 *
 * Provides sysfs interface for listing current clocksource.
 */
static ssize_t
sysfs_show_current_clocksources(struct device *dev,
    struct device_attribute *attr, char *buf)
{
 ssize_t count = 0;
 mutex_lock(&clocksource_mutex);
 count = snprintf(buf, PAGE_SIZE, "%s\n", curr_clocksource->name);
 mutex_unlock(&clocksource_mutex);
 return count;
}
ssize_t sysfs_get_uname(const char *buf, char *dst, size_t cnt)
{
 size_t ret = cnt;
 /* strings from sysfs write are not 0 terminated! */
 if (!cnt || cnt >= CS_NAME_LEN)
  return -EINVAL;
 /* strip of \n: */
 if (buf[cnt-1] == '\n')
  cnt--;
 if (cnt > 0)
  memcpy(dst, buf, cnt);
 dst[cnt] = 0;
 return ret;
}
/**
 * sysfs_override_clocksource - interface for manually overriding clocksource
 * @dev: unused
 * @attr: unused
 * @buf: name of override clocksource
 * @count: length of buffer
 *
 * Takes input from sysfs interface for manually overriding the default
 * clocksource selection.
 */
static ssize_t sysfs_override_clocksource(struct device *dev,
       struct device_attribute *attr,
       const char *buf, size_t count)
{
 ssize_t ret;
 mutex_lock(&clocksource_mutex);
 ret = sysfs_get_uname(buf, override_name, count);
 if (ret >= 0)
  clocksource_select();
 mutex_unlock(&clocksource_mutex);
 return ret;
}
/**
 * sysfs_unbind_current_clocksource - interface for manually unbinding clocksource
 * @dev: unused
 * @attr: unused
 * @buf: unused
 * @count: length of buffer
 *
 * Takes input from sysfs interface for manually unbinding a clocksource.
 */
static ssize_t sysfs_unbind_clocksource(struct device *dev,
     struct device_attribute *attr,
     const char *buf, size_t count)
{
 struct clocksource *cs;
 char name[CS_NAME_LEN];
 ssize_t ret;
 ret = sysfs_get_uname(buf, name, count);
 if (ret < 0)
  return ret;
 ret = -ENODEV;
 mutex_lock(&clocksource_mutex);
 list_for_each_entry(cs, &clocksource_list, list) {
  if (strcmp(cs->name, name))
   continue;
  ret = clocksource_unbind(cs);
  break;
 }
 mutex_unlock(&clocksource_mutex);
 return ret ? ret : count;
}
/**
 * sysfs_show_available_clocksources - sysfs interface for listing clocksource
 * @dev: unused
 * @attr: unused
 * @buf: char buffer to be filled with clocksource list
 *
 * Provides sysfs interface for listing registered clocksources
 */
static ssize_t
sysfs_show_available_clocksources(struct device *dev,
      struct device_attribute *attr,
      char *buf)
{
 struct clocksource *src;
 ssize_t count = 0;
 mutex_lock(&clocksource_mutex);
 list_for_each_entry(src, &clocksource_list, list) {
  /*
   * Don't show non-HRES clocksource if the tick code is
   * in one shot mode (highres=on or nohz=on)
   */
  if (!tick_oneshot_mode_active() ||
      (src->flags & CLOCK_SOURCE_VALID_FOR_HRES))
   count += snprintf(buf + count,
      max((ssize_t)PAGE_SIZE - count, (ssize_t)0),
      "%s ", src->name);
 }
 mutex_unlock(&clocksource_mutex);
 count += snprintf(buf + count,
     max((ssize_t)PAGE_SIZE - count, (ssize_t)0), "\n");
 return count;
}
/*
 * Sysfs setup bits:
 */
static DEVICE_ATTR(current_clocksource, 0644, sysfs_show_current_clocksources,
     sysfs_override_clocksource);
static DEVICE_ATTR(unbind_clocksource, 0200, NULL, sysfs_unbind_clocksource);
static DEVICE_ATTR(available_clocksource, 0444,
     sysfs_show_available_clocksources, NULL);
static struct bus_type clocksource_subsys = {
 .name = "clocksource",
 .dev_name = "clocksource",
};
static struct device device_clocksource = {
 .id = 0,
 .bus = &clocksource_subsys,
};
static int __init init_clocksource_sysfs(void)
{
 int error = subsys_system_register(&clocksource_subsys, NULL);
 if (!error)
  error = device_register(&device_clocksource);
 if (!error)
  error = device_create_file(
    &device_clocksource,
    &dev_attr_current_clocksource);
 if (!error)
  error = device_create_file(&device_clocksource,
        &dev_attr_unbind_clocksource);
 if (!error)
  error = device_create_file(
    &device_clocksource,
    &dev_attr_available_clocksource);
 return error;
}
device_initcall(init_clocksource_sysfs);
#endif /* CONFIG_SYSFS */

 

:/sys/bus/clocksource # ls
ls
devices
drivers
drivers_autoprobe
drivers_probe
uevent
 

/sys/bus/clocksource/devices/clocksource0 # ls
ls
available_clocksource
current_clocksource
power
subsystem
uevent