Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e2cc63fd authored by jinqian's avatar jinqian Committed by Dmitry Shmidt
Browse files

ANDROID: Power: 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
parent 00a83e61
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
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.
 No newline at end of file
+36 −0
Original line number Diff line number Diff line
@@ -36,6 +36,11 @@ static char abort_reason[MAX_SUSPEND_ABORT_LEN];
static struct kobject *wakeup_reason;
static DEFINE_SPINLOCK(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 = {
@@ -133,12 +160,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;