BACKPORT: PM/sleep: Expose suspend stats in sysfs
Userspace can get suspend stats from the suspend stats debugfs node. Since debugfs doesn't have stable ABI, expose suspend stats in sysfs under /sys/power/suspend_stats. Signed-off-by: Kalesh Singh <kaleshsingh@google.com> Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> (cherry picked from commit 2c8db5bef9fb442a5a0d2fee28aed20100362ce3) [ fixed conflicts in Documentation ] Bug: 129087298 Change-Id: Ia8f0d8551ae693cb5f3e1abc609fb9bbfeb695f5 Signed-off-by: Tri Vo <trong@google.com>
This commit is contained in:
@@ -242,7 +242,6 @@ static ssize_t pm_test_store(struct kobject *kobj, struct kobj_attribute *attr,
|
||||
power_attr(pm_test);
|
||||
#endif /* CONFIG_PM_SLEEP_DEBUG */
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
static char *suspend_step_name(enum suspend_stat_step step)
|
||||
{
|
||||
switch (step) {
|
||||
@@ -263,6 +262,92 @@ static char *suspend_step_name(enum suspend_stat_step step)
|
||||
}
|
||||
}
|
||||
|
||||
#define suspend_attr(_name) \
|
||||
static ssize_t _name##_show(struct kobject *kobj, \
|
||||
struct kobj_attribute *attr, char *buf) \
|
||||
{ \
|
||||
return sprintf(buf, "%d\n", suspend_stats._name); \
|
||||
} \
|
||||
static struct kobj_attribute _name = __ATTR_RO(_name)
|
||||
|
||||
suspend_attr(success);
|
||||
suspend_attr(fail);
|
||||
suspend_attr(failed_freeze);
|
||||
suspend_attr(failed_prepare);
|
||||
suspend_attr(failed_suspend);
|
||||
suspend_attr(failed_suspend_late);
|
||||
suspend_attr(failed_suspend_noirq);
|
||||
suspend_attr(failed_resume);
|
||||
suspend_attr(failed_resume_early);
|
||||
suspend_attr(failed_resume_noirq);
|
||||
|
||||
static ssize_t last_failed_dev_show(struct kobject *kobj,
|
||||
struct kobj_attribute *attr, char *buf)
|
||||
{
|
||||
int index;
|
||||
char *last_failed_dev = NULL;
|
||||
|
||||
index = suspend_stats.last_failed_dev + REC_FAILED_NUM - 1;
|
||||
index %= REC_FAILED_NUM;
|
||||
last_failed_dev = suspend_stats.failed_devs[index];
|
||||
|
||||
return sprintf(buf, "%s\n", last_failed_dev);
|
||||
}
|
||||
static struct kobj_attribute last_failed_dev = __ATTR_RO(last_failed_dev);
|
||||
|
||||
static ssize_t last_failed_errno_show(struct kobject *kobj,
|
||||
struct kobj_attribute *attr, char *buf)
|
||||
{
|
||||
int index;
|
||||
int last_failed_errno;
|
||||
|
||||
index = suspend_stats.last_failed_errno + REC_FAILED_NUM - 1;
|
||||
index %= REC_FAILED_NUM;
|
||||
last_failed_errno = suspend_stats.errno[index];
|
||||
|
||||
return sprintf(buf, "%d\n", last_failed_errno);
|
||||
}
|
||||
static struct kobj_attribute last_failed_errno = __ATTR_RO(last_failed_errno);
|
||||
|
||||
static ssize_t last_failed_step_show(struct kobject *kobj,
|
||||
struct kobj_attribute *attr, char *buf)
|
||||
{
|
||||
int index;
|
||||
enum suspend_stat_step step;
|
||||
char *last_failed_step = NULL;
|
||||
|
||||
index = suspend_stats.last_failed_step + REC_FAILED_NUM - 1;
|
||||
index %= REC_FAILED_NUM;
|
||||
step = suspend_stats.failed_steps[index];
|
||||
last_failed_step = suspend_step_name(step);
|
||||
|
||||
return sprintf(buf, "%s\n", last_failed_step);
|
||||
}
|
||||
static struct kobj_attribute last_failed_step = __ATTR_RO(last_failed_step);
|
||||
|
||||
static struct attribute *suspend_attrs[] = {
|
||||
&success.attr,
|
||||
&fail.attr,
|
||||
&failed_freeze.attr,
|
||||
&failed_prepare.attr,
|
||||
&failed_suspend.attr,
|
||||
&failed_suspend_late.attr,
|
||||
&failed_suspend_noirq.attr,
|
||||
&failed_resume.attr,
|
||||
&failed_resume_early.attr,
|
||||
&failed_resume_noirq.attr,
|
||||
&last_failed_dev.attr,
|
||||
&last_failed_errno.attr,
|
||||
&last_failed_step.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static struct attribute_group suspend_attr_group = {
|
||||
.name = "suspend_stats",
|
||||
.attrs = suspend_attrs,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
static int suspend_stats_show(struct seq_file *s, void *unused)
|
||||
{
|
||||
int i, index, last_dev, last_errno, last_step;
|
||||
@@ -793,6 +878,14 @@ static const struct attribute_group attr_group = {
|
||||
.attrs = g,
|
||||
};
|
||||
|
||||
static const struct attribute_group *attr_groups[] = {
|
||||
&attr_group,
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
&suspend_attr_group,
|
||||
#endif
|
||||
NULL,
|
||||
};
|
||||
|
||||
struct workqueue_struct *pm_wq;
|
||||
EXPORT_SYMBOL_GPL(pm_wq);
|
||||
|
||||
@@ -814,7 +907,7 @@ static int __init pm_init(void)
|
||||
power_kobj = kobject_create_and_add("power", NULL);
|
||||
if (!power_kobj)
|
||||
return -ENOMEM;
|
||||
error = sysfs_create_group(power_kobj, &attr_group);
|
||||
error = sysfs_create_groups(power_kobj, attr_groups);
|
||||
if (error)
|
||||
return error;
|
||||
pm_print_times_init();
|
||||
|
||||
Reference in New Issue
Block a user