|
@@ -183,7 +183,6 @@ void wakeup_source_add(struct wakeup_source *ws)
|
|
|
spin_lock_init(&ws->lock);
|
|
|
timer_setup(&ws->timer, pm_wakeup_timer_fn, 0);
|
|
|
ws->active = false;
|
|
|
- ws->last_time = ktime_get();
|
|
|
|
|
|
spin_lock_irqsave(&events_lock, flags);
|
|
|
list_add_rcu(&ws->entry, &wakeup_sources);
|
|
@@ -854,7 +853,7 @@ bool pm_wakeup_pending(void)
|
|
|
spin_unlock_irqrestore(&events_lock, flags);
|
|
|
|
|
|
if (ret) {
|
|
|
- pr_info("PM: Wakeup pending, aborting suspend\n");
|
|
|
+ pr_debug("PM: Wakeup pending, aborting suspend\n");
|
|
|
pm_print_active_wakeup_sources();
|
|
|
}
|
|
|
|
|
@@ -1029,32 +1028,75 @@ static int print_wakeup_source_stats(struct seq_file *m,
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-/**
|
|
|
- * wakeup_sources_stats_show - Print wakeup sources statistics information.
|
|
|
- * @m: seq_file to print the statistics into.
|
|
|
- */
|
|
|
-static int wakeup_sources_stats_show(struct seq_file *m, void *unused)
|
|
|
+static void *wakeup_sources_stats_seq_start(struct seq_file *m,
|
|
|
+ loff_t *pos)
|
|
|
{
|
|
|
struct wakeup_source *ws;
|
|
|
- int srcuidx;
|
|
|
+ loff_t n = *pos;
|
|
|
+ int *srcuidx = m->private;
|
|
|
|
|
|
- seq_puts(m, "name\t\tactive_count\tevent_count\twakeup_count\t"
|
|
|
- "expire_count\tactive_since\ttotal_time\tmax_time\t"
|
|
|
- "last_change\tprevent_suspend_time\n");
|
|
|
+ if (n == 0) {
|
|
|
+ seq_puts(m, "name\t\tactive_count\tevent_count\twakeup_count\t"
|
|
|
+ "expire_count\tactive_since\ttotal_time\tmax_time\t"
|
|
|
+ "last_change\tprevent_suspend_time\n");
|
|
|
+ }
|
|
|
|
|
|
- srcuidx = srcu_read_lock(&wakeup_srcu);
|
|
|
- list_for_each_entry_rcu(ws, &wakeup_sources, entry)
|
|
|
- print_wakeup_source_stats(m, ws);
|
|
|
- srcu_read_unlock(&wakeup_srcu, srcuidx);
|
|
|
+ *srcuidx = srcu_read_lock(&wakeup_srcu);
|
|
|
+ list_for_each_entry_rcu(ws, &wakeup_sources, entry) {
|
|
|
+ if (n-- <= 0)
|
|
|
+ return ws;
|
|
|
+ }
|
|
|
+
|
|
|
+ return NULL;
|
|
|
+}
|
|
|
+
|
|
|
+static void *wakeup_sources_stats_seq_next(struct seq_file *m,
|
|
|
+ void *v, loff_t *pos)
|
|
|
+{
|
|
|
+ struct wakeup_source *ws = v;
|
|
|
+ struct wakeup_source *next_ws = NULL;
|
|
|
|
|
|
- print_wakeup_source_stats(m, &deleted_ws);
|
|
|
+ ++(*pos);
|
|
|
+
|
|
|
+ list_for_each_entry_continue_rcu(ws, &wakeup_sources, entry) {
|
|
|
+ next_ws = ws;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ return next_ws;
|
|
|
+}
|
|
|
+
|
|
|
+static void wakeup_sources_stats_seq_stop(struct seq_file *m, void *v)
|
|
|
+{
|
|
|
+ int *srcuidx = m->private;
|
|
|
+
|
|
|
+ srcu_read_unlock(&wakeup_srcu, *srcuidx);
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * wakeup_sources_stats_seq_show - Print wakeup sources statistics information.
|
|
|
+ * @m: seq_file to print the statistics into.
|
|
|
+ * @v: wakeup_source of each iteration
|
|
|
+ */
|
|
|
+static int wakeup_sources_stats_seq_show(struct seq_file *m, void *v)
|
|
|
+{
|
|
|
+ struct wakeup_source *ws = v;
|
|
|
+
|
|
|
+ print_wakeup_source_stats(m, ws);
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static const struct seq_operations wakeup_sources_stats_seq_ops = {
|
|
|
+ .start = wakeup_sources_stats_seq_start,
|
|
|
+ .next = wakeup_sources_stats_seq_next,
|
|
|
+ .stop = wakeup_sources_stats_seq_stop,
|
|
|
+ .show = wakeup_sources_stats_seq_show,
|
|
|
+};
|
|
|
+
|
|
|
static int wakeup_sources_stats_open(struct inode *inode, struct file *file)
|
|
|
{
|
|
|
- return single_open(file, wakeup_sources_stats_show, NULL);
|
|
|
+ return seq_open_private(file, &wakeup_sources_stats_seq_ops, sizeof(int));
|
|
|
}
|
|
|
|
|
|
static const struct file_operations wakeup_sources_stats_fops = {
|
|
@@ -1062,7 +1104,7 @@ static const struct file_operations wakeup_sources_stats_fops = {
|
|
|
.open = wakeup_sources_stats_open,
|
|
|
.read = seq_read,
|
|
|
.llseek = seq_lseek,
|
|
|
- .release = single_release,
|
|
|
+ .release = seq_release_private,
|
|
|
};
|
|
|
|
|
|
static int __init wakeup_sources_debugfs_init(void)
|