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

Commit 2aa40dfb authored by Ruchi Kandoi's avatar Ruchi Kandoi Committed by Amit Pundir
Browse files

power: Refactors the code which prints suspend time.



Time for which device suspended is no longer tied to the persistent
clocks. This is specially an issue for architecture which do not
implement read_persistent_clocks()

Bug: 22928771
Change-Id: Ibbaec51819ddad8d38a169237390077b4307022d
Signed-off-by: default avatarRuchi <Kandoi&lt;kandoiruchi@google.com>
parent 738d7bb8
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -11,7 +11,6 @@ obj-$(CONFIG_HIBERNATION) += hibernate.o snapshot.o swap.o user.o \
				   block_io.o
obj-$(CONFIG_PM_AUTOSLEEP)	+= autosleep.o
obj-$(CONFIG_PM_WAKELOCKS)	+= wakelock.o
obj-$(CONFIG_SUSPEND_TIME)	+= suspend_time.o

obj-$(CONFIG_MAGIC_SYSRQ)	+= poweroff.o

kernel/power/suspend_time.c

deleted100644 → 0
+0 −111
Original line number Diff line number Diff line
/*
 * debugfs file to track time spent in suspend
 *
 * Copyright (c) 2011, Google, Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 */

#include <linux/debugfs.h>
#include <linux/err.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/seq_file.h>
#include <linux/syscore_ops.h>
#include <linux/time.h>

static struct timespec suspend_time_before;
static unsigned int time_in_suspend_bins[32];

#ifdef CONFIG_DEBUG_FS
static int suspend_time_debug_show(struct seq_file *s, void *data)
{
	int bin;
	seq_printf(s, "time (secs)  count\n");
	seq_printf(s, "------------------\n");
	for (bin = 0; bin < 32; bin++) {
		if (time_in_suspend_bins[bin] == 0)
			continue;
		seq_printf(s, "%4d - %4d %4u\n",
			bin ? 1 << (bin - 1) : 0, 1 << bin,
				time_in_suspend_bins[bin]);
	}
	return 0;
}

static int suspend_time_debug_open(struct inode *inode, struct file *file)
{
	return single_open(file, suspend_time_debug_show, NULL);
}

static const struct file_operations suspend_time_debug_fops = {
	.open		= suspend_time_debug_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= single_release,
};

static int __init suspend_time_debug_init(void)
{
	struct dentry *d;

	d = debugfs_create_file("suspend_time", 0755, NULL, NULL,
		&suspend_time_debug_fops);
	if (!d) {
		pr_err("Failed to create suspend_time debug file\n");
		return -ENOMEM;
	}

	return 0;
}

late_initcall(suspend_time_debug_init);
#endif

static int suspend_time_syscore_suspend(void)
{
	read_persistent_clock(&suspend_time_before);

	return 0;
}

static void suspend_time_syscore_resume(void)
{
	struct timespec after;

	read_persistent_clock(&after);

	after = timespec_sub(after, suspend_time_before);

	time_in_suspend_bins[fls(after.tv_sec)]++;

	pr_info("Suspended for %lu.%03lu seconds\n", after.tv_sec,
		after.tv_nsec / NSEC_PER_MSEC);
}

static struct syscore_ops suspend_time_syscore_ops = {
	.suspend = suspend_time_syscore_suspend,
	.resume = suspend_time_syscore_resume,
};

static int suspend_time_syscore_init(void)
{
	register_syscore_ops(&suspend_time_syscore_ops);

	return 0;
}

static void suspend_time_syscore_exit(void)
{
	unregister_syscore_ops(&suspend_time_syscore_ops);
}
module_init(suspend_time_syscore_init);
module_exit(suspend_time_syscore_exit);
+63 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@
#include <linux/spinlock.h>
#include <linux/notifier.h>
#include <linux/suspend.h>
#include <linux/debugfs.h>


#define MAX_WAKEUP_REASON_IRQS 32
@@ -40,6 +41,9 @@ static ktime_t last_monotime; /* monotonic time before last suspend */
static ktime_t curr_monotime; /* monotonic time after last suspend */
static ktime_t last_stime; /* monotonic boottime offset before last suspend */
static ktime_t curr_stime; /* monotonic boottime offset after last suspend */
#if IS_ENABLED(CONFIG_SUSPEND_TIME)
static unsigned int time_in_suspend_bins[32];
#endif

static ssize_t last_resume_reason_show(struct kobject *kobj, struct kobj_attribute *attr,
		char *buf)
@@ -168,6 +172,11 @@ void log_suspend_abort_reason(const char *fmt, ...)
static int wakeup_reason_pm_event(struct notifier_block *notifier,
		unsigned long pm_event, void *unused)
{
#if IS_ENABLED(CONFIG_SUSPEND_TIME)
	ktime_t temp;
	struct timespec suspend_time;
#endif

	switch (pm_event) {
	case PM_SUSPEND_PREPARE:
		spin_lock(&resume_reason_lock);
@@ -184,6 +193,15 @@ static int wakeup_reason_pm_event(struct notifier_block *notifier,
		curr_monotime = ktime_get();
		/* monotonic time since boot including the time spent in suspend */
		curr_stime = ktime_get_boottime();

#if IS_ENABLED(CONFIG_SUSPEND_TIME)
		temp = ktime_sub(ktime_sub(curr_stime, last_stime),
				ktime_sub(curr_monotime, last_monotime));
		suspend_time = ktime_to_timespec(temp);
		time_in_suspend_bins[fls(suspend_time.tv_sec)]++;
		pr_info("Suspended for %lu.%03lu seconds\n", suspend_time.tv_sec,
			suspend_time.tv_nsec / NSEC_PER_MSEC);
#endif
		break;
	default:
		break;
@@ -195,6 +213,51 @@ static struct notifier_block wakeup_reason_pm_notifier_block = {
	.notifier_call = wakeup_reason_pm_event,
};

#if IS_ENABLED(CONFIG_DEBUG_FS) && IS_ENABLED(CONFIG_SUSPEND_TIME)
static int suspend_time_debug_show(struct seq_file *s, void *data)
{
	int bin;
	seq_printf(s, "time (secs)  count\n");
	seq_printf(s, "------------------\n");
	for (bin = 0; bin < 32; bin++) {
		if (time_in_suspend_bins[bin] == 0)
			continue;
		seq_printf(s, "%4d - %4d %4u\n",
			bin ? 1 << (bin - 1) : 0, 1 << bin,
				time_in_suspend_bins[bin]);
	}
	return 0;
}

static int suspend_time_debug_open(struct inode *inode, struct file *file)
{
	return single_open(file, suspend_time_debug_show, NULL);
}

static const struct file_operations suspend_time_debug_fops = {
	.open		= suspend_time_debug_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= single_release,
};

static int __init suspend_time_debug_init(void)
{
	struct dentry *d;

	d = debugfs_create_file("suspend_time", 0755, NULL, NULL,
		&suspend_time_debug_fops);
	if (!d) {
		pr_err("Failed to create suspend_time debug file\n");
		return -ENOMEM;
	}

	return 0;
}

late_initcall(suspend_time_debug_init);
#endif

/* Initializes the sysfs parameter
 * registers the pm_event notifier
 */