mirror of
https://github.com/followmsi/android_kernel_google_msm.git
synced 2024-11-06 23:17:41 +00:00
Power: Report total suspend times from boot in suspend_since_boot
This node exports five values separated by space. From left to right: 1. Amount of suspend/resume cycles 2. Amount of suspend abort cycles 3. Total time spent in suspend/resume process 4. Total time in suspend abort process 5. Total time spent sleep in suspend state Change-Id: Ife188fd8386dce35f95fa7ba09fbc9d7e152db62 Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
This commit is contained in:
parent
953a4840dd
commit
563e031bd3
1 changed files with 48 additions and 7 deletions
|
@ -44,8 +44,14 @@ struct completion wakeups_completion;
|
|||
|
||||
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 struct timespec last_stime; /* sleep time before last suspend */
|
||||
static struct timespec curr_stime; /* sleep time after last suspend */
|
||||
|
||||
static struct timespec total_xtime; /* total suspend time since boot */
|
||||
static struct timespec total_stime; /* total sleep time since boot */
|
||||
static struct timespec total_atime; /* total suspend abort time since boot */
|
||||
static unsigned long suspend_count; /* total amount of resumes */
|
||||
static unsigned long abort_count; /* total amount of suspend abort */
|
||||
|
||||
static void init_wakeup_irq_node(struct wakeup_irq_node *p, int irq)
|
||||
{
|
||||
|
@ -269,12 +275,28 @@ static ssize_t last_suspend_time_show(struct kobject *kobj,
|
|||
sleep_time.tv_sec, sleep_time.tv_nsec);
|
||||
}
|
||||
|
||||
|
||||
static ssize_t suspend_since_boot_show(struct kobject *kobj,
|
||||
struct kobj_attribute *attr, char *buf)
|
||||
{
|
||||
struct timespec xtime;
|
||||
|
||||
xtime = timespec_sub(total_xtime, total_stime);
|
||||
return sprintf(buf, "%lu %lu %lu.%09lu %lu.%09lu %lu.%09lu\n",
|
||||
suspend_count, abort_count,
|
||||
xtime.tv_sec, xtime.tv_nsec,
|
||||
total_atime.tv_sec, total_atime.tv_nsec,
|
||||
total_stime.tv_sec, total_stime.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 kobj_attribute suspend_since_boot = __ATTR_RO(suspend_since_boot);
|
||||
|
||||
static struct attribute *attrs[] = {
|
||||
&resume_reason.attr,
|
||||
&suspend_time.attr,
|
||||
&suspend_since_boot.attr,
|
||||
NULL,
|
||||
};
|
||||
static struct attribute_group attr_group = {
|
||||
|
@ -496,11 +518,8 @@ static bool delete_node(struct wakeup_irq_node *n, void *unused)
|
|||
return true;
|
||||
}
|
||||
|
||||
void clear_wakeup_reasons(void)
|
||||
static void clear_wakeup_reasons_nolock(void)
|
||||
{
|
||||
unsigned long flags;
|
||||
spin_lock_irqsave(&resume_reason_lock, flags);
|
||||
|
||||
BUG_ON(logging_wakeup_reasons());
|
||||
walk_irq_node_tree(base_irq_nodes, delete_node, NULL);
|
||||
base_irq_nodes = NULL;
|
||||
|
@ -508,7 +527,14 @@ void clear_wakeup_reasons(void)
|
|||
cur_irq_tree_depth = 0;
|
||||
INIT_LIST_HEAD(&wakeup_irqs);
|
||||
suspend_abort = false;
|
||||
}
|
||||
|
||||
void clear_wakeup_reasons(void)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&resume_reason_lock, flags);
|
||||
clear_wakeup_reasons_nolock();
|
||||
spin_unlock_irqrestore(&resume_reason_lock, flags);
|
||||
}
|
||||
|
||||
|
@ -517,10 +543,12 @@ static int wakeup_reason_pm_event(struct notifier_block *notifier,
|
|||
unsigned long pm_event, void *unused)
|
||||
{
|
||||
struct timespec xtom; /* wall_to_monotonic, ignored */
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&resume_reason_lock, flags);
|
||||
switch (pm_event) {
|
||||
case PM_SUSPEND_PREPARE:
|
||||
clear_wakeup_reasons();
|
||||
clear_wakeup_reasons_nolock();
|
||||
|
||||
get_xtime_and_monotonic_and_sleep_offset(&last_xtime, &xtom,
|
||||
&last_stime);
|
||||
|
@ -529,6 +557,18 @@ static int wakeup_reason_pm_event(struct notifier_block *notifier,
|
|||
get_xtime_and_monotonic_and_sleep_offset(&curr_xtime, &xtom,
|
||||
&curr_stime);
|
||||
|
||||
if (!suspend_abort) {
|
||||
suspend_count++;
|
||||
total_xtime = timespec_add(total_xtime,
|
||||
timespec_sub(curr_xtime, last_xtime));
|
||||
total_stime = timespec_add(total_stime,
|
||||
timespec_sub(curr_stime, last_stime));
|
||||
} else {
|
||||
abort_count++;
|
||||
total_atime = timespec_add(total_atime,
|
||||
timespec_sub(curr_xtime, last_xtime));
|
||||
}
|
||||
|
||||
/* log_wakeups should have been cleared by now. */
|
||||
if (WARN_ON(logging_wakeup_reasons())) {
|
||||
stop_logging_wakeup_reasons();
|
||||
|
@ -539,6 +579,7 @@ static int wakeup_reason_pm_event(struct notifier_block *notifier,
|
|||
default:
|
||||
break;
|
||||
}
|
||||
spin_unlock_irqrestore(&resume_reason_lock, flags);
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue