clk: debugfs: Support frequency stats accounting

Added frequency statistics accounting to common
clk debug framework. This change tracks the
frequency of the clocks which don't have the
CLK_GET_RATE_NOCACHE flag set. This is done by
monitoring the calls to  clk_set_rate, clk_enable
and then clk_disable.

There is a new node called frequency_stats_table
created under DEBUG_FS/clk/<clk_debug_name>/ to
report the collected statistics. In addition,
the stats also gets printed as a part of the
clk_summary. Frequency gets reported in HZ and
the time_spent gets reported in msec units.

sample output of clk_summary:

   clock                         enable_cnt  prepare_cnt        rate   accuracy   phase
----------------------------------------------------------------------------------------
 clk24mhz                                 2            3    24000000          0 0
 *[        default_freq                                   48188]
 *         400000000                                         54

default_freq accounts the time for which the
clk was on without an explicit call to the
clk_set_rate API. The [] braces highlight the
latest frequency set through clk_set_rate API.

Frequency accounting can be started(or)stopped
by writing 1(or)0 to /d/clk/freq_stats_on.
Writing 1 also causes the counters to reset.

Enabling CONFIG_FREQ_STATS_ACCOUNTING includes
the feature.

Enabling CONFIG_BEGIN_ACCOUNTING_FROM_BOOT
starts accounting right from boot.

Change-Id: I7333d6afd1494c9a7288c5da70877a734d3a64af
Signed-off-by: Badhri Jagan Sridharan <Badhri@google.com>
diff --git a/include/linux/clk-private.h b/include/linux/clk-private.h
index 0ca5f60..228a987 100644
--- a/include/linux/clk-private.h
+++ b/include/linux/clk-private.h
@@ -13,7 +13,9 @@
 
 #include <linux/clk-provider.h>
 #include <linux/kref.h>
+#include <linux/ktime.h>
 #include <linux/list.h>
+#include <linux/rbtree.h>
 
 /*
  * WARNING: Do not include clk-private.h from any file that implements struct
@@ -28,6 +30,14 @@
 
 struct module;
 
+#ifdef CONFIG_COMMON_CLK_FREQ_STATS_ACCOUNTING
+struct freq_stats {
+	ktime_t time_spent;
+	unsigned long rate;
+	struct rb_node node;
+};
+#endif /*CONFIG_COMMON_CLK_FREQ_STATS_ACCOUNTING*/
+
 struct clk {
 	const char		*name;
 	const struct clk_ops	*ops;
@@ -53,6 +63,13 @@
 	unsigned int		notifier_count;
 #ifdef CONFIG_DEBUG_FS
 	struct dentry		*dentry;
+#ifdef CONFIG_COMMON_CLK_FREQ_STATS_ACCOUNTING
+	struct rb_root freq_stats_table;
+	struct freq_stats *current_freq_stats;
+	ktime_t default_freq_time;
+	ktime_t start_time;
+#endif /* CONFIG_COMMON_CLK_FREQ_STATS_ACCOUNTING*/
+
 #endif
 	struct kref		ref;
 };