msm: clock: Support depends in toplevel

Two types of clocks support depends (branches and rcgs) and soon
we'll be adding a third (rpm). Support depends in the core so as
to avoid duplicating that logic all over.

Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
diff --git a/arch/arm/mach-msm/clock-7x30.c b/arch/arm/mach-msm/clock-7x30.c
index 0dc0cab..3793ba0 100644
--- a/arch/arm/mach-msm/clock-7x30.c
+++ b/arch/arm/mach-msm/clock-7x30.c
@@ -1159,7 +1159,6 @@
 	.root_en_mask = BIT(11),
 	.ns_reg = EMDH_NS_REG,
 	.ns_mask = F_MASK_BASIC,
-	.depends = &axi_li_adsp_a_clk.c,
 	.set_rate = set_rate_nop,
 	.freq_tbl = clk_tbl_mdh,
 	.current_freq = &local_dummy_freq,
@@ -1168,6 +1167,7 @@
 		.flags = CLKFLAG_MIN | CLKFLAG_MAX,
 		.ops = &soc_clk_ops_7x30,
 		CLK_INIT(emdh_clk.c),
+		.depends = &axi_li_adsp_a_clk.c,
 	},
 };
 
@@ -1180,7 +1180,6 @@
 	.root_en_mask = BIT(11),
 	.ns_reg = PMDH_NS_REG,
 	.ns_mask = F_MASK_BASIC,
-	.depends = &axi_li_adsp_a_clk.c,
 	.set_rate = set_rate_nop,
 	.freq_tbl = clk_tbl_mdh,
 	.current_freq = &local_dummy_freq,
@@ -1189,6 +1188,7 @@
 		.flags = CLKFLAG_MIN | CLKFLAG_MAX,
 		.ops = &soc_clk_ops_7x30,
 		CLK_INIT(pmdh_clk.c),
+		.depends = &axi_li_adsp_a_clk.c,
 	},
 };
 
@@ -1227,12 +1227,12 @@
 	.ns_mask = F_MASK_BASIC | (7 << 12),
 	.set_rate = set_rate_nop,
 	.freq_tbl = clk_tbl_grp,
-	.depends = &axi_grp_2d_clk.c,
 	.current_freq = &local_dummy_freq,
 	.c = {
 		.dbg_name = "grp_2d_clk",
 		.ops = &soc_clk_ops_7x30,
 		CLK_INIT(grp_2d_clk.c),
+		.depends = &axi_grp_2d_clk.c,
 	},
 };
 
@@ -1246,12 +1246,12 @@
 	.ns_mask = F_MASK_BASIC | (7 << 12),
 	.set_rate = set_rate_nop,
 	.freq_tbl = clk_tbl_grp,
-	.depends = &axi_li_grp_clk.c,
 	.current_freq = &local_dummy_freq,
 	.c = {
 		.dbg_name = "grp_3d_src_clk",
 		.ops = &soc_clk_ops_7x30,
 		CLK_INIT(grp_3d_src_clk.c),
+		.depends = &axi_li_grp_clk.c,
 	},
 };
 
@@ -1423,7 +1423,6 @@
 	.ns_reg = MDP_NS_REG,
 	.root_en_mask = BIT(11),
 	.ns_mask = F_MASK_BASIC,
-	.depends = &axi_mdp_clk.c,
 	.set_rate = set_rate_nop,
 	.freq_tbl = clk_tbl_mdp_core,
 	.current_freq = &local_dummy_freq,
@@ -1431,6 +1430,7 @@
 		.dbg_name = "mdp_clk",
 		.ops = &soc_clk_ops_7x30,
 		CLK_INIT(mdp_clk.c),
+		.depends = &axi_mdp_clk.c,
 	},
 };
 
@@ -1831,12 +1831,12 @@
 	.root_en_mask = BIT(11),
 	.freq_tbl = clk_tbl_usb,
 	.current_freq = &local_dummy_freq,
-	.depends = &axi_li_adsp_a_clk.c,
 	.set_rate = set_rate_mnd,
 	.c = {
 		.dbg_name = "usb_hs_src_clk",
 		.ops = &soc_clk_ops_7x30,
 		CLK_INIT(usb_hs_src_clk.c),
+		.depends = &axi_li_adsp_a_clk.c,
 	},
 };
 
@@ -1966,12 +1966,12 @@
 	.freq_tbl = clk_tbl_vfe_jpeg,
 	.ns_mask = F_MASK_MND16,
 	.set_rate = set_rate_mnd,
-	.depends = &axi_li_jpeg_clk.c,
 	.current_freq = &local_dummy_freq,
 	.c = {
 		.dbg_name = "jpeg_clk",
 		.ops = &soc_clk_ops_7x30,
 		CLK_INIT(jpeg_clk.c),
+		.depends = &axi_li_jpeg_clk.c,
 	},
 };
 
@@ -1989,12 +1989,12 @@
 	.freq_tbl = clk_tbl_vfe_jpeg,
 	.ns_mask = F_MASK_MND16,
 	.set_rate = set_rate_mnd,
-	.depends = &axi_li_vfe_clk.c,
 	.current_freq = &local_dummy_freq,
 	.c = {
 		.dbg_name = "vfe_clk",
 		.ops = &soc_clk_ops_7x30,
 		CLK_INIT(vfe_clk.c),
+		.depends = &axi_li_vfe_clk.c,
 	},
 };
 
@@ -2105,12 +2105,12 @@
 	.root_en_mask = BIT(11),
 	.freq_tbl = clk_tbl_vpe,
 	.current_freq = &local_dummy_freq,
-	.depends = &axi_vpe_clk.c,
 	.set_rate = set_rate_mnd,
 	.c = {
 		.dbg_name = "vpe_clk",
 		.ops = &soc_clk_ops_7x30,
 		CLK_INIT(vpe_clk.c),
+		.depends = &axi_vpe_clk.c,
 	},
 };
 
@@ -2141,12 +2141,12 @@
 	.root_en_mask = BIT(11),
 	.freq_tbl = clk_tbl_mfc,
 	.current_freq = &local_dummy_freq,
-	.depends = &axi_mfc_clk.c,
 	.set_rate = set_rate_mnd,
 	.c = {
 		.dbg_name = "mfc_clk",
 		.ops = &soc_clk_ops_7x30,
 		CLK_INIT(mfc_clk.c),
+		.depends = &axi_mfc_clk.c,
 	},
 };
 
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index 23b34d2..187b331 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -544,11 +544,11 @@
 		.halt_reg = DBG_BUS_VEC_I_REG,
 		.halt_bit = 26,
 	},
-	.depends = &vcodec_axi_b_clk.c,
 	.c = {
 		.dbg_name = "vcodec_axi_a_clk",
 		.ops = &clk_ops_branch,
 		CLK_INIT(vcodec_axi_a_clk.c),
+		.depends = &vcodec_axi_b_clk.c,
 	},
 };
 
@@ -561,11 +561,11 @@
 		.halt_reg = DBG_BUS_VEC_E_REG,
 		.halt_bit = 3,
 	},
-	.depends = &vcodec_axi_a_clk.c,
 	.c = {
 		.dbg_name = "vcodec_axi_clk",
 		.ops = &clk_ops_branch,
 		CLK_INIT(vcodec_axi_clk.c),
+		.depends = &vcodec_axi_a_clk.c,
 	},
 };
 
@@ -2481,12 +2481,12 @@
 	.set_rate = set_rate_mnd_banked,
 	.freq_tbl = clk_tbl_gfx3d,
 	.bank_masks = &bmnd_info_gfx3d,
-	.depends = &gmem_axi_clk.c,
 	.current_freq = &local_dummy_freq,
 	.c = {
 		.dbg_name = "gfx3d_clk",
 		.ops = &soc_clk_ops_8960,
 		CLK_INIT(gfx3d_clk.c),
+		.depends = &gmem_axi_clk.c,
 	},
 };
 
@@ -2530,12 +2530,12 @@
 	.ctl_mask = BM(7, 6),
 	.set_rate = set_rate_mnd,
 	.freq_tbl = clk_tbl_ijpeg,
-	.depends = &ijpeg_axi_clk.c,
 	.current_freq = &local_dummy_freq,
 	.c = {
 		.dbg_name = "ijpeg_clk",
 		.ops = &soc_clk_ops_8960,
 		CLK_INIT(ijpeg_clk.c),
+		.depends = &ijpeg_axi_clk.c,
 	},
 };
 
@@ -2570,12 +2570,12 @@
 	.ns_mask =  (BM(15, 12) | BM(2, 0)),
 	.set_rate = set_rate_nop,
 	.freq_tbl = clk_tbl_jpegd,
-	.depends = &jpegd_axi_clk.c,
 	.current_freq = &local_dummy_freq,
 	.c = {
 		.dbg_name = "jpegd_clk",
 		.ops = &soc_clk_ops_8960,
 		CLK_INIT(jpegd_clk.c),
+		.depends = &jpegd_axi_clk.c,
 	},
 };
 
@@ -2640,12 +2640,12 @@
 	.set_rate = set_rate_mnd_banked,
 	.freq_tbl = clk_tbl_mdp,
 	.bank_masks = &bmnd_info_mdp,
-	.depends = &mdp_axi_clk.c,
 	.current_freq = &local_dummy_freq,
 	.c = {
 		.dbg_name = "mdp_clk",
 		.ops = &soc_clk_ops_8960,
 		CLK_INIT(mdp_clk.c),
+		.depends = &mdp_axi_clk.c,
 	},
 };
 
@@ -2748,11 +2748,11 @@
 	.freq_tbl = clk_tbl_rot,
 	.bank_masks = &bdiv_info_rot,
 	.current_freq = &local_dummy_freq,
-	.depends = &rot_axi_clk.c,
 	.c = {
 		.dbg_name = "rot_clk",
 		.ops = &soc_clk_ops_8960,
 		CLK_INIT(rot_clk.c),
+		.depends = &rot_axi_clk.c,
 	},
 };
 
@@ -2992,12 +2992,12 @@
 	.set_rate = set_rate_mnd_banked,
 	.bank_masks = &bmnd_info_vcodec,
 	.freq_tbl = clk_tbl_vcodec,
-	.depends = &vcodec_axi_clk.c,
 	.current_freq = &local_dummy_freq,
 	.c = {
 		.dbg_name = "vcodec_clk",
 		.ops = &soc_clk_ops_8960,
 		CLK_INIT(vcodec_clk.c),
+		.depends = &vcodec_axi_clk.c,
 	},
 };
 
@@ -3036,11 +3036,11 @@
 	.set_rate = set_rate_nop,
 	.freq_tbl = clk_tbl_vpe,
 	.current_freq = &local_dummy_freq,
-	.depends = &vpe_axi_clk.c,
 	.c = {
 		.dbg_name = "vpe_clk",
 		.ops = &soc_clk_ops_8960,
 		CLK_INIT(vpe_clk.c),
+		.depends = &vpe_axi_clk.c,
 	},
 };
 
@@ -3092,12 +3092,12 @@
 	.ctl_mask = BM(7, 6),
 	.set_rate = set_rate_mnd,
 	.freq_tbl = clk_tbl_vfe,
-	.depends = &vfe_axi_clk.c,
 	.current_freq = &local_dummy_freq,
 	.c = {
 		.dbg_name = "vfe_clk",
 		.ops = &soc_clk_ops_8960,
 		CLK_INIT(vfe_clk.c),
+		.depends = &vfe_axi_clk.c,
 	},
 };
 
diff --git a/arch/arm/mach-msm/clock-8x60.c b/arch/arm/mach-msm/clock-8x60.c
index 44276d8..fe56dd9 100644
--- a/arch/arm/mach-msm/clock-8x60.c
+++ b/arch/arm/mach-msm/clock-8x60.c
@@ -2299,12 +2299,12 @@
 	.set_rate = set_rate_mnd_banked,
 	.freq_tbl = clk_tbl_gfx3d,
 	.bank_masks = &bmnd_info_gfx3d,
-	.depends = &gmem_axi_clk.c,
 	.current_freq = &local_dummy_freq,
 	.c = {
 		.dbg_name = "gfx3d_clk",
 		.ops = &soc_clk_ops_8x60,
 		CLK_INIT(gfx3d_clk.c),
+		.depends = &gmem_axi_clk.c,
 	},
 };
 
@@ -2348,12 +2348,12 @@
 	.ctl_mask = BM(7, 6),
 	.set_rate = set_rate_mnd,
 	.freq_tbl = clk_tbl_ijpeg,
-	.depends = &ijpeg_axi_clk.c,
 	.current_freq = &local_dummy_freq,
 	.c = {
 		.dbg_name = "ijpeg_clk",
 		.ops = &soc_clk_ops_8x60,
 		CLK_INIT(ijpeg_clk.c),
+		.depends = &ijpeg_axi_clk.c,
 	},
 };
 
@@ -2388,12 +2388,12 @@
 	.ns_mask =  (BM(15, 12) | BM(2, 0)),
 	.set_rate = set_rate_nop,
 	.freq_tbl = clk_tbl_jpegd,
-	.depends = &jpegd_axi_clk.c,
 	.current_freq = &local_dummy_freq,
 	.c = {
 		.dbg_name = "jpegd_clk",
 		.ops = &soc_clk_ops_8x60,
 		CLK_INIT(jpegd_clk.c),
+		.depends = &jpegd_axi_clk.c,
 	},
 };
 
@@ -2458,12 +2458,12 @@
 	.set_rate = set_rate_mnd_banked,
 	.freq_tbl = clk_tbl_mdp,
 	.bank_masks = &bmnd_info_mdp,
-	.depends = &mdp_axi_clk.c,
 	.current_freq = &local_dummy_freq,
 	.c = {
 		.dbg_name = "mdp_clk",
 		.ops = &soc_clk_ops_8x60,
 		CLK_INIT(mdp_clk.c),
+		.depends = &mdp_axi_clk.c,
 	},
 };
 
@@ -2615,12 +2615,12 @@
 	.set_rate = set_rate_div_banked,
 	.freq_tbl = clk_tbl_rot,
 	.bank_masks = &bdiv_info_rot,
-	.depends = &rot_axi_clk.c,
 	.current_freq = &local_dummy_freq,
 	.c = {
 		.dbg_name = "rot_clk",
 		.ops = &soc_clk_ops_8x60,
 		CLK_INIT(rot_clk.c),
+		.depends = &rot_axi_clk.c,
 	},
 };
 
@@ -2794,12 +2794,12 @@
 	.ctl_mask = BM(7, 6),
 	.set_rate = set_rate_mnd,
 	.freq_tbl = clk_tbl_vcodec,
-	.depends = &vcodec_axi_clk.c,
 	.current_freq = &local_dummy_freq,
 	.c = {
 		.dbg_name = "vcodec_clk",
 		.ops = &soc_clk_ops_8x60,
 		CLK_INIT(vcodec_clk.c),
+		.depends = &vcodec_axi_clk.c,
 	},
 };
 
@@ -2838,12 +2838,12 @@
 	.ns_mask = (BM(15, 12) | BM(2, 0)),
 	.set_rate = set_rate_nop,
 	.freq_tbl = clk_tbl_vpe,
-	.depends = &vpe_axi_clk.c,
 	.current_freq = &local_dummy_freq,
 	.c = {
 		.dbg_name = "vpe_clk",
 		.ops = &soc_clk_ops_8x60,
 		CLK_INIT(vpe_clk.c),
+		.depends = &vpe_axi_clk.c,
 	},
 };
 
@@ -2894,12 +2894,12 @@
 	.ctl_mask = BM(7, 6),
 	.set_rate = set_rate_mnd,
 	.freq_tbl = clk_tbl_vfe,
-	.depends = &vfe_axi_clk.c,
 	.current_freq = &local_dummy_freq,
 	.c = {
 		.dbg_name = "vfe_clk",
 		.ops = &soc_clk_ops_8x60,
 		CLK_INIT(vfe_clk.c),
+		.depends = &vfe_axi_clk.c,
 	},
 };
 
diff --git a/arch/arm/mach-msm/clock-local.c b/arch/arm/mach-msm/clock-local.c
index 6f29803..b7542c8 100644
--- a/arch/arm/mach-msm/clock-local.c
+++ b/arch/arm/mach-msm/clock-local.c
@@ -514,17 +514,9 @@
 
 	rc = local_vote_sys_vdd(clk->current_freq->sys_vdd);
 	if (rc)
-		goto err_vdd;
-	rc = clk_enable(clk->depends);
-	if (rc)
-		goto err_dep;
+		return rc;
 	_rcg_clk_enable(clk);
 	return rc;
-
-err_dep:
-	local_unvote_sys_vdd(clk->current_freq->sys_vdd);
-err_vdd:
-	return rc;
 }
 
 /* Disable a clock and any related power rail. */
@@ -533,11 +525,10 @@
 	struct rcg_clk *clk = to_rcg_clk(c);
 
 	_rcg_clk_disable(clk);
-	clk_disable(clk->depends);
 	local_unvote_sys_vdd(clk->current_freq->sys_vdd);
 }
 
-/* Turn off a clock at boot, without checking refcounts or disabling depends. */
+/* Turn off a clock at boot, without checking refcounts. */
 void rcg_clk_auto_off(struct clk *c)
 {
 	_rcg_clk_disable(to_rcg_clk(c));
@@ -911,14 +902,9 @@
 
 int branch_clk_enable(struct clk *clk)
 {
-	int rc;
 	unsigned long flags;
 	struct branch_clk *branch = to_branch_clk(clk);
 
-	rc = clk_enable(branch->depends);
-	if (rc)
-		return rc;
-
 	spin_lock_irqsave(&local_clock_reg_lock, flags);
 	__branch_clk_enable_reg(&branch->b, branch->c.dbg_name);
 	branch->enabled = true;
@@ -936,8 +922,6 @@
 	__branch_clk_disable_reg(&branch->b, branch->c.dbg_name);
 	branch->enabled = false;
 	spin_unlock_irqrestore(&local_clock_reg_lock, flags);
-
-	clk_disable(branch->depends);
 }
 
 struct clk *branch_clk_get_parent(struct clk *clk)
diff --git a/arch/arm/mach-msm/clock-local.h b/arch/arm/mach-msm/clock-local.h
index 2455fbf..7367f6e 100644
--- a/arch/arm/mach-msm/clock-local.h
+++ b/arch/arm/mach-msm/clock-local.h
@@ -132,7 +132,6 @@
 	struct clk_freq_tbl *const freq_tbl;
 	struct clk_freq_tbl *current_freq;
 
-	struct clk *depends;
 	struct branch	b;
 	struct clk	c;
 };
@@ -251,7 +250,6 @@
 	bool enabled;
 	struct branch b;
 	struct clk *parent;
-	struct clk *depends;
 	struct clk c;
 };
 
diff --git a/arch/arm/mach-msm/clock.c b/arch/arm/mach-msm/clock.c
index a29e9cd..fa84906 100644
--- a/arch/arm/mach-msm/clock.c
+++ b/arch/arm/mach-msm/clock.c
@@ -42,10 +42,16 @@
 		ret = clk_enable(parent);
 		if (ret)
 			goto out;
+		ret = clk_enable(clk->depends);
+		if (ret) {
+			clk_disable(parent);
+			goto out;
+		}
 
 		if (clk->ops->enable)
 			ret = clk->ops->enable(clk);
 		if (ret) {
+			clk_disable(clk->depends);
 			clk_disable(parent);
 			goto out;
 		}
@@ -81,6 +87,7 @@
 	if (clk->count == 1) {
 		if (clk->ops->disable)
 			clk->ops->disable(clk);
+		clk_disable(clk->depends);
 		parent = clk_get_parent(clk);
 		clk_disable(parent);
 	}
diff --git a/arch/arm/mach-msm/clock.h b/arch/arm/mach-msm/clock.h
index db49133..89775b4 100644
--- a/arch/arm/mach-msm/clock.h
+++ b/arch/arm/mach-msm/clock.h
@@ -56,11 +56,13 @@
  * struct clk
  * @count: enable refcount
  * @lock: protects clk_enable()/clk_disable() path and @count
+ * @depends: non-direct parent of clock to enable when this clock is enabled
  */
 struct clk {
 	uint32_t flags;
 	struct clk_ops *ops;
 	const char *dbg_name;
+	struct clk *depends;
 
 	struct list_head children;
 	struct list_head siblings;