ANDROID: power: wakeup_reason: Report suspend times from last_suspend_time
This node epxorts two values separated by space. From left to right: 1. time spent in suspend/resume process 2. time spent sleep in suspend state Change-Id: I2cb9a9408a5fd12166aaec11b935a0fd6a408c63
This commit is contained in:
parent
ba32dd1412
commit
acccb4cc66
2 changed files with 52 additions and 0 deletions
16
Documentation/ABI/testing/sysfs-kernel-wakeup_reasons
Normal file
16
Documentation/ABI/testing/sysfs-kernel-wakeup_reasons
Normal file
|
@ -0,0 +1,16 @@
|
|||
What: /sys/kernel/wakeup_reasons/last_resume_reason
|
||||
Date: February 2014
|
||||
Contact: Ruchi Kandoi <kandoiruchi@google.com>
|
||||
Description:
|
||||
The /sys/kernel/wakeup_reasons/last_resume_reason is
|
||||
used to report wakeup reasons after system exited suspend.
|
||||
|
||||
What: /sys/kernel/wakeup_reasons/last_suspend_time
|
||||
Date: March 2015
|
||||
Contact: jinqian <jinqian@google.com>
|
||||
Description:
|
||||
The /sys/kernel/wakeup_reasons/last_suspend_time is
|
||||
used to report time spent in last suspend cycle. It contains
|
||||
two numbers (in seconds) separated by space. First number is
|
||||
the time spent in suspend and resume processes. Second number
|
||||
is the time spent in sleep state.
|
|
@ -36,6 +36,11 @@ static char abort_reason[MAX_SUSPEND_ABORT_LEN];
|
|||
static struct kobject *wakeup_reason;
|
||||
static spinlock_t resume_reason_lock;
|
||||
|
||||
static struct timespec last_xtime; /* wall time before last suspend */
|
||||
static struct timespec curr_xtime; /* wall time after last suspend */
|
||||
static struct timespec last_stime; /* total_sleep_time before last suspend */
|
||||
static struct timespec curr_stime; /* total_sleep_time after last suspend */
|
||||
|
||||
static ssize_t last_resume_reason_show(struct kobject *kobj, struct kobj_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
|
@ -59,10 +64,32 @@ static ssize_t last_resume_reason_show(struct kobject *kobj, struct kobj_attribu
|
|||
return buf_offset;
|
||||
}
|
||||
|
||||
static ssize_t last_suspend_time_show(struct kobject *kobj,
|
||||
struct kobj_attribute *attr, char *buf)
|
||||
{
|
||||
struct timespec sleep_time;
|
||||
struct timespec total_time;
|
||||
struct timespec suspend_resume_time;
|
||||
|
||||
sleep_time = timespec_sub(curr_stime, last_stime);
|
||||
total_time = timespec_sub(curr_xtime, last_xtime);
|
||||
suspend_resume_time = timespec_sub(total_time, sleep_time);
|
||||
|
||||
/*
|
||||
* suspend_resume_time is calculated from sleep_time. Userspace would
|
||||
* always need both. Export them in pair here.
|
||||
*/
|
||||
return sprintf(buf, "%lu.%09lu %lu.%09lu\n",
|
||||
suspend_resume_time.tv_sec, suspend_resume_time.tv_nsec,
|
||||
sleep_time.tv_sec, sleep_time.tv_nsec);
|
||||
}
|
||||
|
||||
static struct kobj_attribute resume_reason = __ATTR_RO(last_resume_reason);
|
||||
static struct kobj_attribute suspend_time = __ATTR_RO(last_suspend_time);
|
||||
|
||||
static struct attribute *attrs[] = {
|
||||
&resume_reason.attr,
|
||||
&suspend_time.attr,
|
||||
NULL,
|
||||
};
|
||||
static struct attribute_group attr_group = {
|
||||
|
@ -118,12 +145,21 @@ void log_suspend_abort_reason(const char *fmt, ...)
|
|||
static int wakeup_reason_pm_event(struct notifier_block *notifier,
|
||||
unsigned long pm_event, void *unused)
|
||||
{
|
||||
struct timespec xtom; /* wall_to_monotonic, ignored */
|
||||
|
||||
switch (pm_event) {
|
||||
case PM_SUSPEND_PREPARE:
|
||||
spin_lock(&resume_reason_lock);
|
||||
irqcount = 0;
|
||||
suspend_abort = false;
|
||||
spin_unlock(&resume_reason_lock);
|
||||
|
||||
get_xtime_and_monotonic_and_sleep_offset(&last_xtime, &xtom,
|
||||
&last_stime);
|
||||
break;
|
||||
case PM_POST_SUSPEND:
|
||||
get_xtime_and_monotonic_and_sleep_offset(&curr_xtime, &xtom,
|
||||
&curr_stime);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
Loading…
Reference in a new issue