diff options
Diffstat (limited to 'drivers/base')
-rw-r--r-- | drivers/base/power/wakeup.c | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c index 03751a01dbad..71c5528e1c35 100644 --- a/drivers/base/power/wakeup.c +++ b/drivers/base/power/wakeup.c | |||
@@ -11,6 +11,8 @@ | |||
11 | #include <linux/sched.h> | 11 | #include <linux/sched.h> |
12 | #include <linux/capability.h> | 12 | #include <linux/capability.h> |
13 | #include <linux/suspend.h> | 13 | #include <linux/suspend.h> |
14 | #include <linux/seq_file.h> | ||
15 | #include <linux/debugfs.h> | ||
14 | 16 | ||
15 | #include "power.h" | 17 | #include "power.h" |
16 | 18 | ||
@@ -617,3 +619,86 @@ bool pm_save_wakeup_count(unsigned int count) | |||
617 | pm_wakeup_update_hit_counts(); | 619 | pm_wakeup_update_hit_counts(); |
618 | return ret; | 620 | return ret; |
619 | } | 621 | } |
622 | |||
623 | static struct dentry *wakeup_sources_stats_dentry; | ||
624 | |||
625 | /** | ||
626 | * print_wakeup_source_stats - Print wakeup source statistics information. | ||
627 | * @m: seq_file to print the statistics into. | ||
628 | * @ws: Wakeup source object to print the statistics for. | ||
629 | */ | ||
630 | static int print_wakeup_source_stats(struct seq_file *m, | ||
631 | struct wakeup_source *ws) | ||
632 | { | ||
633 | unsigned long flags; | ||
634 | ktime_t total_time; | ||
635 | ktime_t max_time; | ||
636 | unsigned long active_count; | ||
637 | ktime_t active_time; | ||
638 | int ret; | ||
639 | |||
640 | spin_lock_irqsave(&ws->lock, flags); | ||
641 | |||
642 | total_time = ws->total_time; | ||
643 | max_time = ws->max_time; | ||
644 | active_count = ws->active_count; | ||
645 | if (ws->active) { | ||
646 | active_time = ktime_sub(ktime_get(), ws->last_time); | ||
647 | total_time = ktime_add(total_time, active_time); | ||
648 | if (active_time.tv64 > max_time.tv64) | ||
649 | max_time = active_time; | ||
650 | } else { | ||
651 | active_time = ktime_set(0, 0); | ||
652 | } | ||
653 | |||
654 | ret = seq_printf(m, "%-12s\t%lu\t\t%lu\t\t%lu\t\t" | ||
655 | "%lld\t\t%lld\t\t%lld\t\t%lld\n", | ||
656 | ws->name, active_count, ws->event_count, ws->hit_count, | ||
657 | ktime_to_ms(active_time), ktime_to_ms(total_time), | ||
658 | ktime_to_ms(max_time), ktime_to_ms(ws->last_time)); | ||
659 | |||
660 | spin_unlock_irqrestore(&ws->lock, flags); | ||
661 | |||
662 | return ret; | ||
663 | } | ||
664 | |||
665 | /** | ||
666 | * wakeup_sources_stats_show - Print wakeup sources statistics information. | ||
667 | * @m: seq_file to print the statistics into. | ||
668 | */ | ||
669 | static int wakeup_sources_stats_show(struct seq_file *m, void *unused) | ||
670 | { | ||
671 | struct wakeup_source *ws; | ||
672 | |||
673 | seq_puts(m, "name\t\tactive_count\tevent_count\thit_count\t" | ||
674 | "active_since\ttotal_time\tmax_time\tlast_change\n"); | ||
675 | |||
676 | rcu_read_lock(); | ||
677 | list_for_each_entry_rcu(ws, &wakeup_sources, entry) | ||
678 | print_wakeup_source_stats(m, ws); | ||
679 | rcu_read_unlock(); | ||
680 | |||
681 | return 0; | ||
682 | } | ||
683 | |||
684 | static int wakeup_sources_stats_open(struct inode *inode, struct file *file) | ||
685 | { | ||
686 | return single_open(file, wakeup_sources_stats_show, NULL); | ||
687 | } | ||
688 | |||
689 | static const struct file_operations wakeup_sources_stats_fops = { | ||
690 | .owner = THIS_MODULE, | ||
691 | .open = wakeup_sources_stats_open, | ||
692 | .read = seq_read, | ||
693 | .llseek = seq_lseek, | ||
694 | .release = single_release, | ||
695 | }; | ||
696 | |||
697 | static int __init wakeup_sources_debugfs_init(void) | ||
698 | { | ||
699 | wakeup_sources_stats_dentry = debugfs_create_file("wakeup_sources", | ||
700 | S_IRUGO, NULL, NULL, &wakeup_sources_stats_fops); | ||
701 | return 0; | ||
702 | } | ||
703 | |||
704 | postcore_initcall(wakeup_sources_debugfs_init); | ||