From c21794d0eea0dad22cb659ca41b13464f0ee1212 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 1 Feb 2017 15:56:35 +0100 Subject: clk: Keep enable count consistent over reparent When reparenting a clock we have to make sure the new parent is enabled when the clock was enabled on the old parent. Also we have to decrease the old parents use counter when the clock was enabled. Signed-off-by: Sascha Hauer --- drivers/clk/clk.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 1566beabda..6f3053727c 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -173,14 +173,15 @@ struct clk *clk_lookup(const char *name) return ERR_PTR(-ENODEV); } -int clk_set_parent(struct clk *clk, struct clk *parent) +int clk_set_parent(struct clk *clk, struct clk *newparent) { - int i; + int i, ret; + struct clk *curparent = clk_get_parent(clk); if (IS_ERR(clk)) return PTR_ERR(clk); - if (IS_ERR(parent)) - return PTR_ERR(parent); + if (IS_ERR(newparent)) + return PTR_ERR(newparent); if (!clk->num_parents) return -EINVAL; @@ -192,14 +193,22 @@ int clk_set_parent(struct clk *clk, struct clk *parent) clk->parents[i] = clk_lookup(clk->parent_names[i]); if (!IS_ERR_OR_NULL(clk->parents[i])) - if (clk->parents[i] == parent) + if (clk->parents[i] == newparent) break; } if (i == clk->num_parents) return -EINVAL; - return clk->ops->set_parent(clk, i); + if (clk->enable_count) + clk_enable(newparent); + + ret = clk->ops->set_parent(clk, i); + + if (clk->enable_count) + clk_disable(curparent); + + return ret; } struct clk *clk_get_parent(struct clk *clk) -- cgit v1.2.3