diff options
Diffstat (limited to 'drivers/clk/clk.c')
-rw-r--r-- | drivers/clk/clk.c | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 53b28e63deae..91bb1ea0e147 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -1765,6 +1765,23 @@ static void clk_core_update_orphan_status(struct clk_core *core, bool is_orphan) clk_core_update_orphan_status(child, is_orphan); } +/* + * Update the orphan rate and req_rate of @core and all its children. + */ +static void clk_core_update_orphan_child_rates(struct clk_core *core) +{ + struct clk_core *child; + unsigned long parent_rate = 0; + + if (core->parent) + parent_rate = core->parent->rate; + + core->rate = core->req_rate = clk_recalc(core, parent_rate); + + hlist_for_each_entry(child, &core->children, child_node) + clk_core_update_orphan_child_rates(child); +} + static void clk_reparent(struct clk_core *core, struct clk_core *new_parent) { bool was_orphan = core->orphan; @@ -1834,6 +1851,8 @@ static struct clk_core *__clk_set_parent_before(struct clk_core *core, clk_reparent(core, parent); clk_enable_unlock(flags); + clk_core_update_orphan_child_rates(core); + return old_parent; } @@ -1878,6 +1897,8 @@ static int __clk_set_parent(struct clk_core *core, struct clk_core *parent, flags = clk_enable_lock(); clk_reparent(core, old_parent); clk_enable_unlock(flags); + + clk_core_update_orphan_child_rates(core); __clk_set_parent_after(core, old_parent, parent); return ret; @@ -2506,6 +2527,7 @@ static void clk_core_reparent(struct clk_core *core, struct clk_core *new_parent) { clk_reparent(core, new_parent); + clk_core_update_orphan_child_rates(core); __clk_recalc_accuracies(core); __clk_recalc_rates(core, POST_RATE_CHANGE); } |