diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index aa51756fd4d6..14460e87f508 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -66,6 +66,7 @@ struct clk_core {
 	unsigned long		flags;
 	bool			orphan;
 	bool			rpm_enabled;
+	bool			inherit_enabled; /* clock was enabled by bootloader */
 	unsigned int		enable_count;
 	unsigned int		prepare_count;
 	unsigned int		protect_count;
@@ -1166,6 +1167,9 @@ static void clk_unprepare_unused_subtree(struct clk_core *core)
 	hlist_for_each_entry(child, &core->children, child_node)
 		clk_unprepare_unused_subtree(child);
 
+	if (core->inherit_enabled)
+		return;
+
 	if (core->prepare_count)
 		return;
 
@@ -1197,6 +1201,9 @@ static void clk_disable_unused_subtree(struct clk_core *core)
 	hlist_for_each_entry(child, &core->children, child_node)
 		clk_disable_unused_subtree(child);
 
+	if (core->inherit_enabled)
+		return;
+
 	if (core->flags & CLK_OPS_PARENT_ENABLE)
 		clk_core_prepare_enable(core->parent);
 
@@ -1270,6 +1277,45 @@ static int clk_disable_unused(void)
 }
 late_initcall_sync(clk_disable_unused);
 
+/* Ignore CLK_INHERIT_BOOTLOADER clocks enabled by bootloader.  This
+ * gives a debug knob to disable inheriting clks from bootloader, so
+ * that drivers that used to work, when loaded as a module, thanks
+ * to disabling "unused" clocks at late_initcall(), can continue to
+ * work.
+ *
+ * The proper solution is to fix the drivers.
+ */
+static bool clk_ignore_inherited;
+static int __init clk_ignore_inherited_setup(char *__unused)
+{
+	clk_ignore_inherited = true;
+	return 1;
+}
+__setup("clk_ignore_inherited", clk_ignore_inherited_setup);
+
+/* clock and it's parents are already prepared/enabled from bootloader,
+ * so simply record the fact.
+ */
+static void __clk_inherit_enabled(struct clk_core *core)
+{
+	unsigned long parent_rate = 0;
+	core->inherit_enabled = true;
+	if (core->parent) {
+		__clk_inherit_enabled(core->parent);
+		parent_rate = core->parent->rate;
+	}
+	if (core->ops->recalc_rate)
+		core->rate = core->ops->recalc_rate(core->hw, parent_rate);
+}
+
+void clk_inherit_enabled(struct clk *clk)
+{
+	if (clk_ignore_inherited)
+		return;
+	__clk_inherit_enabled(clk->core);
+}
+EXPORT_SYMBOL_GPL(clk_inherit_enabled);
+
 static int clk_core_determine_round_nolock(struct clk_core *core,
 					   struct clk_rate_request *req)
 {
@@ -3302,6 +3348,8 @@ static int __clk_core_init(struct clk_core *core)
 		 * are enabled during init but might not have a parent yet.
 		 */
 		if (parent) {
+			if (orphan->inherit_enabled)
+				__clk_inherit_enabled(parent);
 			/* update the clk tree topology */
 			__clk_set_parent_before(orphan, parent);
 			__clk_set_parent_after(orphan, parent, NULL);
diff --git a/drivers/clk/qcom/common.c b/drivers/clk/qcom/common.c
index a6b2f86112d8..0d542eeef9aa 100644
--- a/drivers/clk/qcom/common.c
+++ b/drivers/clk/qcom/common.c
@@ -290,6 +290,31 @@ int qcom_cc_really_probe(struct platform_device *pdev,
 	if (ret)
 		return ret;
 
+	/*
+	 * Check which of clocks that we inherit state from bootloader
+	 * are enabled, and fixup enable/prepare state (as well as that
+	 * of it's parents).
+	 */
+	for (i = 0; i < num_clks; i++) {
+		struct clk_hw *hw;
+
+		if (!rclks[i])
+			continue;
+
+		hw = &rclks[i]->hw;
+
+		if (!(hw->init->flags & CLK_INHERIT_BOOTLOADER))
+			continue;
+
+		if (!clk_is_enabled_regmap(hw))
+			continue;
+
+		dev_dbg(dev, "%s is enabled from bootloader!\n",
+			hw->init->name);
+
+		clk_inherit_enabled(hw->clk);
+	}
+
 	return 0;
 }
 EXPORT_SYMBOL_GPL(qcom_cc_really_probe);
diff --git a/drivers/clk/qcom/dispcc-sdm845.c b/drivers/clk/qcom/dispcc-sdm845.c
index 0cc4909b5dbe..40d7e0ab4340 100644
--- a/drivers/clk/qcom/dispcc-sdm845.c
+++ b/drivers/clk/qcom/dispcc-sdm845.c
@@ -263,6 +263,7 @@ static struct clk_branch disp_cc_mdss_ahb_clk = {
 		.enable_mask = BIT(0),
 		.hw.init = &(struct clk_init_data){
 			.name = "disp_cc_mdss_ahb_clk",
+			.flags = CLK_INHERIT_BOOTLOADER,
 			.ops = &clk_branch2_ops,
 		},
 	},
@@ -276,6 +277,7 @@ static struct clk_branch disp_cc_mdss_axi_clk = {
 		.enable_mask = BIT(0),
 		.hw.init = &(struct clk_init_data){
 			.name = "disp_cc_mdss_axi_clk",
+			.flags = CLK_INHERIT_BOOTLOADER,
 			.ops = &clk_branch2_ops,
 		},
 	},
@@ -294,7 +296,7 @@ static struct clk_branch disp_cc_mdss_byte0_clk = {
 				"disp_cc_mdss_byte0_clk_src",
 			},
 			.num_parents = 1,
-			.flags = CLK_SET_RATE_PARENT,
+			.flags = CLK_SET_RATE_PARENT | CLK_INHERIT_BOOTLOADER,
 			.ops = &clk_branch2_ops,
 		},
 	},
@@ -330,7 +332,7 @@ static struct clk_branch disp_cc_mdss_byte0_intf_clk = {
 				"disp_cc_mdss_byte0_div_clk_src",
 			},
 			.num_parents = 1,
-			.flags = CLK_SET_RATE_PARENT,
+			.flags = CLK_SET_RATE_PARENT | CLK_INHERIT_BOOTLOADER,
 			.ops = &clk_branch2_ops,
 		},
 	},
@@ -349,7 +351,7 @@ static struct clk_branch disp_cc_mdss_byte1_clk = {
 				"disp_cc_mdss_byte1_clk_src",
 			},
 			.num_parents = 1,
-			.flags = CLK_SET_RATE_PARENT,
+			.flags = CLK_SET_RATE_PARENT | CLK_INHERIT_BOOTLOADER,
 			.ops = &clk_branch2_ops,
 		},
 	},
@@ -385,7 +387,7 @@ static struct clk_branch disp_cc_mdss_byte1_intf_clk = {
 				"disp_cc_mdss_byte1_div_clk_src",
 			},
 			.num_parents = 1,
-			.flags = CLK_SET_RATE_PARENT,
+			.flags = CLK_SET_RATE_PARENT | CLK_INHERIT_BOOTLOADER,
 			.ops = &clk_branch2_ops,
 		},
 	},
@@ -403,7 +405,7 @@ static struct clk_branch disp_cc_mdss_esc0_clk = {
 				"disp_cc_mdss_esc0_clk_src",
 			},
 			.num_parents = 1,
-			.flags = CLK_SET_RATE_PARENT,
+			.flags = CLK_SET_RATE_PARENT | CLK_INHERIT_BOOTLOADER,
 			.ops = &clk_branch2_ops,
 		},
 	},
@@ -421,7 +423,7 @@ static struct clk_branch disp_cc_mdss_esc1_clk = {
 				"disp_cc_mdss_esc1_clk_src",
 			},
 			.num_parents = 1,
-			.flags = CLK_SET_RATE_PARENT,
+			.flags = CLK_SET_RATE_PARENT | CLK_INHERIT_BOOTLOADER,
 			.ops = &clk_branch2_ops,
 		},
 	},
@@ -439,7 +441,7 @@ static struct clk_branch disp_cc_mdss_mdp_clk = {
 				"disp_cc_mdss_mdp_clk_src",
 			},
 			.num_parents = 1,
-			.flags = CLK_SET_RATE_PARENT,
+			.flags = CLK_SET_RATE_PARENT | CLK_INHERIT_BOOTLOADER,
 			.ops = &clk_branch2_ops,
 		},
 	},
@@ -475,7 +477,7 @@ static struct clk_branch disp_cc_mdss_pclk0_clk = {
 				"disp_cc_mdss_pclk0_clk_src",
 			},
 			.num_parents = 1,
-			.flags = CLK_SET_RATE_PARENT,
+			.flags = CLK_SET_RATE_PARENT | CLK_INHERIT_BOOTLOADER,
 			.ops = &clk_branch2_ops,
 		},
 	},
@@ -494,7 +496,7 @@ static struct clk_branch disp_cc_mdss_pclk1_clk = {
 				"disp_cc_mdss_pclk1_clk_src",
 			},
 			.num_parents = 1,
-			.flags = CLK_SET_RATE_PARENT,
+			.flags = CLK_SET_RATE_PARENT | CLK_INHERIT_BOOTLOADER,
 			.ops = &clk_branch2_ops,
 		},
 	},
@@ -561,7 +563,7 @@ static struct clk_branch disp_cc_mdss_vsync_clk = {
 				"disp_cc_mdss_vsync_clk_src",
 			},
 			.num_parents = 1,
-			.flags = CLK_SET_RATE_PARENT,
+			.flags = CLK_SET_RATE_PARENT | CLK_INHERIT_BOOTLOADER,
 			.ops = &clk_branch2_ops,
 		},
 	},
diff --git a/drivers/clk/qcom/gcc-sdm845.c b/drivers/clk/qcom/gcc-sdm845.c
index 7131dcf9b060..fe2498be7bc7 100644
--- a/drivers/clk/qcom/gcc-sdm845.c
+++ b/drivers/clk/qcom/gcc-sdm845.c
@@ -1314,7 +1314,7 @@ static struct clk_branch gcc_disp_ahb_clk = {
 		.enable_mask = BIT(0),
 		.hw.init = &(struct clk_init_data){
 			.name = "gcc_disp_ahb_clk",
-			.flags = CLK_IS_CRITICAL,
+			.flags = CLK_IS_CRITICAL | CLK_INHERIT_BOOTLOADER,
 			.ops = &clk_branch2_ops,
 		},
 	},
@@ -1328,6 +1328,7 @@ static struct clk_branch gcc_disp_axi_clk = {
 		.enable_mask = BIT(0),
 		.hw.init = &(struct clk_init_data){
 			.name = "gcc_disp_axi_clk",
+			.flags = CLK_INHERIT_BOOTLOADER,
 			.ops = &clk_branch2_ops,
 		},
 	},
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index bb6118f79784..41b951c8b92b 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -34,6 +34,7 @@
 #define CLK_OPS_PARENT_ENABLE	BIT(12)
 /* duty cycle call may be forwarded to the parent clock */
 #define CLK_DUTY_CYCLE_PARENT	BIT(13)
+#define CLK_INHERIT_BOOTLOADER	BIT(14) /* clk may be enabled from bootloader */
 
 struct clk;
 struct clk_hw;
@@ -349,6 +350,15 @@ void clk_hw_unregister_fixed_rate(struct clk_hw *hw);
 
 void of_fixed_clk_setup(struct device_node *np);
 
+/**
+ * clk_inherit_enabled - update the enable/prepare count of a clock and it's
+ * parents for clock enabled by bootloader.
+ *
+ * Intended to be used by clock drivers to inform the clk core of a clock
+ * that is already running.
+ */
+void clk_inherit_enabled(struct clk *clk);
+
 /**
  * struct clk_gate - gating clock
  *
