clk: Add tracepoints for hardware operations

It's useful to have tracepoints around operations that change the
hardware state so that we can debug clock hardware performance
and operations. Four basic types of events are supported: on/off
events for enable, disable, prepare, unprepare that only record
an event and a clock name, rate changing events for
clk_set_{min_,max_}rate{_range}(), phase changing events for
clk_set_phase() and parent changing events for clk_set_parent().

Cc: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Michael Turquette <mturquette@linaro.org>
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 0b3f39c..42064ce 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -77,6 +77,9 @@
 	struct kref		ref;
 };
 
+#define CREATE_TRACE_POINTS
+#include <trace/events/clk.h>
+
 struct clk {
 	struct clk_core	*core;
 	const char *dev_id;
@@ -492,10 +495,12 @@
 		return;
 
 	if (clk_core_is_prepared(clk)) {
+		trace_clk_unprepare(clk);
 		if (clk->ops->unprepare_unused)
 			clk->ops->unprepare_unused(clk->hw);
 		else if (clk->ops->unprepare)
 			clk->ops->unprepare(clk->hw);
+		trace_clk_unprepare_complete(clk);
 	}
 }
 
@@ -524,10 +529,12 @@
 	 * back to .disable
 	 */
 	if (clk_core_is_enabled(clk)) {
+		trace_clk_disable(clk);
 		if (clk->ops->disable_unused)
 			clk->ops->disable_unused(clk->hw);
 		else if (clk->ops->disable)
 			clk->ops->disable(clk->hw);
+		trace_clk_disable_complete(clk);
 	}
 
 unlock_out:
@@ -907,9 +914,12 @@
 
 	WARN_ON(clk->enable_count > 0);
 
+	trace_clk_unprepare(clk);
+
 	if (clk->ops->unprepare)
 		clk->ops->unprepare(clk->hw);
 
+	trace_clk_unprepare_complete(clk);
 	clk_core_unprepare(clk->parent);
 }
 
@@ -947,12 +957,16 @@
 		if (ret)
 			return ret;
 
-		if (clk->ops->prepare) {
+		trace_clk_prepare(clk);
+
+		if (clk->ops->prepare)
 			ret = clk->ops->prepare(clk->hw);
-			if (ret) {
-				clk_core_unprepare(clk->parent);
-				return ret;
-			}
+
+		trace_clk_prepare_complete(clk);
+
+		if (ret) {
+			clk_core_unprepare(clk->parent);
+			return ret;
 		}
 	}
 
@@ -999,9 +1013,13 @@
 	if (--clk->enable_count > 0)
 		return;
 
+	trace_clk_disable(clk);
+
 	if (clk->ops->disable)
 		clk->ops->disable(clk->hw);
 
+	trace_clk_disable_complete(clk);
+
 	clk_core_disable(clk->parent);
 }
 
@@ -1054,12 +1072,16 @@
 		if (ret)
 			return ret;
 
-		if (clk->ops->enable) {
+		trace_clk_enable(clk);
+
+		if (clk->ops->enable)
 			ret = clk->ops->enable(clk->hw);
-			if (ret) {
-				clk_core_disable(clk->parent);
-				return ret;
-			}
+
+		trace_clk_enable_complete(clk);
+
+		if (ret) {
+			clk_core_disable(clk->parent);
+			return ret;
 		}
 	}
 
@@ -1490,10 +1512,14 @@
 
 	old_parent = __clk_set_parent_before(clk, parent);
 
+	trace_clk_set_parent(clk, parent);
+
 	/* change clock input source */
 	if (parent && clk->ops->set_parent)
 		ret = clk->ops->set_parent(clk->hw, p_index);
 
+	trace_clk_set_parent_complete(clk, parent);
+
 	if (ret) {
 		flags = clk_enable_lock();
 		clk_reparent(clk, old_parent);
@@ -1719,6 +1745,7 @@
 
 	if (clk->new_parent && clk->new_parent != clk->parent) {
 		old_parent = __clk_set_parent_before(clk, clk->new_parent);
+		trace_clk_set_parent(clk, clk->new_parent);
 
 		if (clk->ops->set_rate_and_parent) {
 			skip_set_rate = true;
@@ -1729,12 +1756,17 @@
 			clk->ops->set_parent(clk->hw, clk->new_parent_index);
 		}
 
+		trace_clk_set_parent_complete(clk, clk->new_parent);
 		__clk_set_parent_after(clk, clk->new_parent, old_parent);
 	}
 
+	trace_clk_set_rate(clk, clk->new_rate);
+
 	if (!skip_set_rate && clk->ops->set_rate)
 		clk->ops->set_rate(clk->hw, clk->new_rate, best_parent_rate);
 
+	trace_clk_set_rate_complete(clk, clk->new_rate);
+
 	clk->rate = clk_recalc(clk, best_parent_rate);
 
 	if (clk->notifier_count && old_rate != clk->rate)
@@ -2135,9 +2167,13 @@
 
 	clk_prepare_lock();
 
+	trace_clk_set_phase(clk->core, degrees);
+
 	if (clk->core->ops->set_phase)
 		ret = clk->core->ops->set_phase(clk->core->hw, degrees);
 
+	trace_clk_set_phase_complete(clk->core, degrees);
+
 	if (!ret)
 		clk->core->phase = degrees;