summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2016-12-23 03:55:08 -0800
committerGerrit - the friendly Code Review server <code-review@localhost>2016-12-23 03:55:07 -0800
commit7b5675f4ed08e52dacae75906e637811a80597ff (patch)
tree9f4a90e4b593c3ec0953a225a37964c2bd178aac
parent85a244de8769e5f8dc0a5c516d5a53765a6d07cb (diff)
parent44aa223a3e4ab5c3ea59e916899a3695b0dac06d (diff)
Merge "clk: move check for CLK_ENABLE_HAND_OFF at unused tree"
-rw-r--r--drivers/clk/clk.c78
1 files changed, 42 insertions, 36 deletions
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 55b44559bae4..ac815c6dbac0 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -197,6 +197,19 @@ static void clk_unprepare_unused_subtree(struct clk_core *core)
hlist_for_each_entry(child, &core->children, child_node)
clk_unprepare_unused_subtree(child);
+ /*
+ * setting CLK_ENABLE_HAND_OFF flag triggers this conditional
+ *
+ * need_handoff_prepare implies this clk was already prepared by
+ * __clk_init. now we have a proper user, so unset the flag in our
+ * internal bookkeeping. See CLK_ENABLE_HAND_OFF flag in clk-provider.h
+ * for details.
+ */
+ if (core->need_handoff_prepare) {
+ core->need_handoff_prepare = false;
+ core->prepare_count--;
+ }
+
if (core->prepare_count)
return;
@@ -223,6 +236,19 @@ static void clk_disable_unused_subtree(struct clk_core *core)
hlist_for_each_entry(child, &core->children, child_node)
clk_disable_unused_subtree(child);
+ /*
+ * setting CLK_ENABLE_HAND_OFF flag triggers this conditional
+ *
+ * need_handoff_enable implies this clk was already enabled by
+ * __clk_init. now we have a proper user, so unset the flag in our
+ * internal bookkeeping. See CLK_ENABLE_HAND_OFF flag in clk-provider.h
+ * for details.
+ */
+ if (core->need_handoff_enable) {
+ core->need_handoff_enable = false;
+ core->enable_count--;
+ }
+
flags = clk_enable_lock();
if (core->enable_count)
@@ -932,24 +958,10 @@ int clk_prepare(struct clk *clk)
if (!clk)
return 0;
- /*
- * setting CLK_ENABLE_HAND_OFF flag triggers this conditional
- *
- * need_handoff_prepare implies this clk was already prepared by
- * __clk_init. now we have a proper user, so unset the flag in our
- * internal bookkeeping. See CLK_ENABLE_HAND_OFF flag in clk-provider.h
- * for details.
- */
- if (clk->core->need_handoff_prepare) {
- clk->core->need_handoff_prepare = false;
- goto out;
- }
-
clk_prepare_lock();
ret = clk_core_prepare(clk->core);
clk_prepare_unlock();
-out:
return ret;
}
EXPORT_SYMBOL_GPL(clk_prepare);
@@ -1061,24 +1073,10 @@ int clk_enable(struct clk *clk)
if (!clk)
return 0;
- /*
- * setting CLK_ENABLE_HAND_OFF flag triggers this conditional
- *
- * need_handoff_enable implies this clk was already enabled by
- * __clk_init. now we have a proper user, so unset the flag in our
- * internal bookkeeping. See CLK_ENABLE_HAND_OFF flag in clk-provider.h
- * for details.
- */
- if (clk->core->need_handoff_enable) {
- clk->core->need_handoff_enable = false;
- goto out;
- }
-
flags = clk_enable_lock();
ret = clk_core_enable(clk->core);
clk_enable_unlock(flags);
-out:
return ret;
}
EXPORT_SYMBOL_GPL(clk_enable);
@@ -3189,14 +3187,22 @@ static int __clk_init(struct device *dev, struct clk *clk_user)
if (core->flags & CLK_ENABLE_HAND_OFF) {
unsigned long flags;
- core->need_handoff_prepare = true;
- core->need_handoff_enable = true;
- ret = clk_core_prepare(core);
- if (ret)
- goto out;
- flags = clk_enable_lock();
- clk_core_enable(core);
- clk_enable_unlock(flags);
+ /*
+ * Few clocks might have hardware gating which would be required
+ * to be ON before prepare/enabling the clocks. So check if the
+ * clock has been turned ON earlier and we should
+ * prepare/enable those clocks.
+ */
+ if (clk_core_is_enabled(core)) {
+ core->need_handoff_prepare = true;
+ core->need_handoff_enable = true;
+ ret = clk_core_prepare(core);
+ if (ret)
+ goto out;
+ flags = clk_enable_lock();
+ clk_core_enable(core);
+ clk_enable_unlock(flags);
+ }
}
kref_init(&core->ref);