diff options
Diffstat (limited to 'target/linux/ipq806x/patches/0126-clk-Add-safe-switch-hook.patch')
-rw-r--r-- | target/linux/ipq806x/patches/0126-clk-Add-safe-switch-hook.patch | 146 |
1 files changed, 0 insertions, 146 deletions
diff --git a/target/linux/ipq806x/patches/0126-clk-Add-safe-switch-hook.patch b/target/linux/ipq806x/patches/0126-clk-Add-safe-switch-hook.patch deleted file mode 100644 index a78319f..0000000 --- a/target/linux/ipq806x/patches/0126-clk-Add-safe-switch-hook.patch +++ /dev/null @@ -1,146 +0,0 @@ -From b7b3ceec506179d59e46e3a8ea8b370872cc7fcb Mon Sep 17 00:00:00 2001 -From: Stephen Boyd <sboyd@codeaurora.org> -Date: Mon, 31 Mar 2014 16:52:29 -0700 -Subject: [PATCH 126/182] clk: Add safe switch hook - -Sometimes clocks can't accept their parent source turning off -while the source is reprogrammed to a different rate. Most -notably CPU clocks require a way to switch away from the current -PLL they're running on, reprogram that PLL to a new rate, and -then switch back to the PLL with the new rate once they're done. -Add a hook that drivers can implement allowing them to return a -'safe parent' that they can switch their parent to while the -upstream source is reprogrammed to support this. - -Signed-off-by: Stephen Boyd <sboyd@codeaurora.org> ---- - drivers/clk/clk.c | 53 ++++++++++++++++++++++++++++++++++++------ - include/linux/clk-private.h | 2 ++ - include/linux/clk-provider.h | 1 + - 3 files changed, 49 insertions(+), 7 deletions(-) - ---- a/drivers/clk/clk.c -+++ b/drivers/clk/clk.c -@@ -1356,6 +1356,7 @@ static void clk_calc_subtree(struct clk - struct clk *new_parent, u8 p_index) - { - struct clk *child; -+ struct clk *parent; - - clk->new_rate = new_rate; - clk->new_parent = new_parent; -@@ -1365,6 +1366,17 @@ static void clk_calc_subtree(struct clk - if (new_parent && new_parent != clk->parent) - new_parent->new_child = clk; - -+ if (clk->ops->get_safe_parent) { -+ parent = clk->ops->get_safe_parent(clk->hw); -+ if (parent) { -+ p_index = clk_fetch_parent_index(clk, parent); -+ clk->safe_parent_index = p_index; -+ clk->safe_parent = parent; -+ } -+ } else { -+ clk->safe_parent = NULL; -+ } -+ - hlist_for_each_entry(child, &clk->children, child_node) { - if (child->ops->recalc_rate) - child->new_rate = child->ops->recalc_rate(child->hw, new_rate); -@@ -1450,14 +1462,42 @@ out: - static struct clk *clk_propagate_rate_change(struct clk *clk, unsigned long event) - { - struct clk *child, *tmp_clk, *fail_clk = NULL; -+ struct clk *old_parent; - int ret = NOTIFY_DONE; - -- if (clk->rate == clk->new_rate) -+ if (clk->rate == clk->new_rate && event != POST_RATE_CHANGE) - return NULL; - -+ switch (event) { -+ case PRE_RATE_CHANGE: -+ if (clk->safe_parent) -+ clk->ops->set_parent(clk->hw, clk->safe_parent_index); -+ break; -+ case POST_RATE_CHANGE: -+ if (clk->safe_parent) { -+ old_parent = __clk_set_parent_before(clk, -+ clk->new_parent); -+ if (clk->ops->set_rate_and_parent) { -+ clk->ops->set_rate_and_parent(clk->hw, -+ clk->new_rate, -+ clk->new_parent ? -+ clk->new_parent->rate : 0, -+ clk->new_parent_index); -+ } else if (clk->ops->set_parent) { -+ clk->ops->set_parent(clk->hw, -+ clk->new_parent_index); -+ } -+ __clk_set_parent_after(clk, clk->new_parent, -+ old_parent); -+ } -+ break; -+ } -+ - if (clk->notifier_count) { -- ret = __clk_notify(clk, event, clk->rate, clk->new_rate); -- if (ret & NOTIFY_STOP_MASK) -+ if (event != POST_RATE_CHANGE) -+ ret = __clk_notify(clk, event, clk->rate, -+ clk->new_rate); -+ if (ret & NOTIFY_STOP_MASK && event != POST_RATE_CHANGE) - fail_clk = clk; - } - -@@ -1500,7 +1540,8 @@ static void clk_change_rate(struct clk * - else if (clk->parent) - best_parent_rate = clk->parent->rate; - -- if (clk->new_parent && clk->new_parent != clk->parent) { -+ if (clk->new_parent && clk->new_parent != clk->parent && -+ !clk->safe_parent) { - old_parent = __clk_set_parent_before(clk, clk->new_parent); - - if (clk->ops->set_rate_and_parent) { -@@ -1523,9 +1564,6 @@ static void clk_change_rate(struct clk * - else - clk->rate = best_parent_rate; - -- if (clk->notifier_count && old_rate != clk->rate) -- __clk_notify(clk, POST_RATE_CHANGE, old_rate, clk->rate); -- - /* - * Use safe iteration, as change_rate can actually swap parents - * for certain clock types. -@@ -1603,6 +1641,7 @@ int clk_set_rate(struct clk *clk, unsign - /* change the rates */ - clk_change_rate(top); - -+ clk_propagate_rate_change(top, POST_RATE_CHANGE); - out: - clk_prepare_unlock(); - ---- a/include/linux/clk-private.h -+++ b/include/linux/clk-private.h -@@ -38,8 +38,10 @@ struct clk { - struct clk **parents; - u8 num_parents; - u8 new_parent_index; -+ u8 safe_parent_index; - unsigned long rate; - unsigned long new_rate; -+ struct clk *safe_parent; - struct clk *new_parent; - struct clk *new_child; - unsigned long flags; ---- a/include/linux/clk-provider.h -+++ b/include/linux/clk-provider.h -@@ -157,6 +157,7 @@ struct clk_ops { - struct clk **best_parent_clk); - int (*set_parent)(struct clk_hw *hw, u8 index); - u8 (*get_parent)(struct clk_hw *hw); -+ struct clk *(*get_safe_parent)(struct clk_hw *hw); - int (*set_rate)(struct clk_hw *hw, unsigned long, - unsigned long); - int (*set_rate_and_parent)(struct clk_hw *hw, |