msm: clock: Add hardware gating support to branch clocks

Add support for hardware clock gating on branch clocks. Do this
in a few steps:

 o At clock registration time, check to see if the branch is not
   in hardware gated mode and fix up the branch data structure
   as appropriate

 o When a clk_reset() is asserted take the branch out of
   hardware control so the reset can propagate if the clock
   is enabled

 o When a clk_reset() is deasserted put the branch back into
   hardware control

Add three new ops to the clk_ops structure to support the above.

	void (*enable_hwcg)(struct clk *clk);
	void (*disable_hwcg)(struct clk *clk);
	int (*in_hwcg_mode)(struct clk *clk);

{enable,disable}_hwcg() should enable and disable hardware clock
gating if possible. in_hwcg_mode() should return either a
non-zero value or a zero indicating whether the clock is
currently in hardware gating mode or not in hardware gating mode
respectively.

Use in_hwcg_mode() to detect when to skip the halt checks for a
branch and when to disable/enable hardware gating mode while
measuring clocks. This is particularly important for measurement
because we don't want to put a clock into hardware gating mode
accidentally after we measure the clock if the clock wasn't in
hardware gating mode to begin with.

Also expose a debugfs node indicating whether or not this clock
supports hardware gating. This should aid in debugging problems
due to hardware gating.

Change-Id: Id9b2d83adcc6dabe2544f48ef0b4d752d9a5c5c1
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
diff --git a/arch/arm/mach-msm/clock.h b/arch/arm/mach-msm/clock.h
index ec8ff6c..91121e6 100644
--- a/arch/arm/mach-msm/clock.h
+++ b/arch/arm/mach-msm/clock.h
@@ -29,6 +29,7 @@
 #define CLKFLAG_NONEST			0x00000004
 #define CLKFLAG_NORESET			0x00000008
 #define CLKFLAG_HANDOFF_RATE		0x00000010
+#define CLKFLAG_HWCG			0x00000020
 #define CLKFLAG_SKIP_AUTO_OFF		0x00000200
 #define CLKFLAG_MIN			0x00000400
 #define CLKFLAG_MAX			0x00000800
@@ -63,6 +64,9 @@
 	int (*enable)(struct clk *clk);
 	void (*disable)(struct clk *clk);
 	void (*auto_off)(struct clk *clk);
+	void (*enable_hwcg)(struct clk *clk);
+	void (*disable_hwcg)(struct clk *clk);
+	int (*in_hwcg_mode)(struct clk *clk);
 	int (*handoff)(struct clk *clk);
 	int (*reset)(struct clk *clk, enum clk_reset_action action);
 	int (*set_rate)(struct clk *clk, unsigned long rate);