0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/debugfs.h>
0009 #include <linux/err.h>
0010 #include <linux/init.h>
0011 #include <linux/kernel.h>
0012 #include <linux/seq_file.h>
0013 #include <linux/suspend.h>
0014 #include <linux/time.h>
0015
0016 #include "timekeeping_internal.h"
0017
0018 #define NUM_BINS 32
0019
0020 static unsigned int sleep_time_bin[NUM_BINS] = {0};
0021
0022 static int tk_debug_sleep_time_show(struct seq_file *s, void *data)
0023 {
0024 unsigned int bin;
0025 seq_puts(s, " time (secs) count\n");
0026 seq_puts(s, "------------------------------\n");
0027 for (bin = 0; bin < 32; bin++) {
0028 if (sleep_time_bin[bin] == 0)
0029 continue;
0030 seq_printf(s, "%10u - %-10u %4u\n",
0031 bin ? 1 << (bin - 1) : 0, 1 << bin,
0032 sleep_time_bin[bin]);
0033 }
0034 return 0;
0035 }
0036 DEFINE_SHOW_ATTRIBUTE(tk_debug_sleep_time);
0037
0038 static int __init tk_debug_sleep_time_init(void)
0039 {
0040 debugfs_create_file("sleep_time", 0444, NULL, NULL,
0041 &tk_debug_sleep_time_fops);
0042 return 0;
0043 }
0044 late_initcall(tk_debug_sleep_time_init);
0045
0046 void tk_debug_account_sleep_time(const struct timespec64 *t)
0047 {
0048
0049 int bin = min(fls(t->tv_sec), NUM_BINS-1);
0050
0051 sleep_time_bin[bin]++;
0052 pm_deferred_pr_dbg("Timekeeping suspended for %lld.%03lu seconds\n",
0053 (s64)t->tv_sec, t->tv_nsec / NSEC_PER_MSEC);
0054 }
0055