Messages in this thread Patch in this message | | | From | Thierry Reding <> | Subject | [PATCH 2/2] clocksource: Add suspend clocksource sysfs attribute | Date | Fri, 14 Jun 2019 12:45:10 +0200 |
| |
From: Thierry Reding <treding@nvidia.com>
Allow the currently selected suspend clocksource to be inspected via sysfs. The suspend clocksource can also be set using this attribute, which can be useful for debugging.
Signed-off-by: Thierry Reding <treding@nvidia.com> --- kernel/time/clocksource.c | 53 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-)
diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c index 467b36d2f9f8..d963bcecbc96 100644 --- a/kernel/time/clocksource.c +++ b/kernel/time/clocksource.c @@ -489,7 +489,8 @@ static void __clocksource_suspend_select(struct clocksource *cs) } /* Pick the best rating. */ - if (!suspend_clocksource || cs->rating > suspend_clocksource->rating) + if (!suspend_clocksource || cs->rating > suspend_clocksource->rating || + (suspend_clocksource->flags & CLOCK_SOURCE_SUSPEND_NONSTOP) == 0) suspend_clocksource = cs; } @@ -1172,10 +1173,60 @@ static ssize_t available_clocksource_show(struct device *dev, } static DEVICE_ATTR_RO(available_clocksource); +static ssize_t suspend_clocksource_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct clocksource *clksrc = suspend_clocksource; + ssize_t count = 0; + + if (clksrc) + count += snprintf(buf, PAGE_SIZE, "%s\n", clksrc->name); + + return count; +} + +static ssize_t suspend_clocksource_store(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; + + mutex_lock(&clocksource_mutex); + + if (strlen(name) > 0) { + cs = clocksource_lookup(name); + if (cs) { + if (!(cs->flags & CLOCK_SOURCE_SUSPEND_NONSTOP)) + pr_warn("using non-persistent clocksource %s for suspend\n", + cs->name); + + suspend_clocksource = cs; + } else { + ret = -ENODEV; + } + } else { + clocksource_suspend_select(false); + } + + mutex_unlock(&clocksource_mutex); + + return ret ? ret : count; +} + +static DEVICE_ATTR_RW(suspend_clocksource); + static struct attribute *clocksource_attrs[] = { &dev_attr_current_clocksource.attr, &dev_attr_unbind_clocksource.attr, &dev_attr_available_clocksource.attr, + &dev_attr_suspend_clocksource.attr, NULL }; ATTRIBUTE_GROUPS(clocksource); -- 2.21.0
| |