diff options
Diffstat (limited to 'drivers/clk/clk.c')
-rw-r--r-- | drivers/clk/clk.c | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index b76fa69b44cb..bacc06ff939b 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c | |||
@@ -1467,6 +1467,7 @@ static struct clk *clk_propagate_rate_change(struct clk *clk, unsigned long even | |||
1467 | static void clk_change_rate(struct clk *clk) | 1467 | static void clk_change_rate(struct clk *clk) |
1468 | { | 1468 | { |
1469 | struct clk *child; | 1469 | struct clk *child; |
1470 | struct hlist_node *tmp; | ||
1470 | unsigned long old_rate; | 1471 | unsigned long old_rate; |
1471 | unsigned long best_parent_rate = 0; | 1472 | unsigned long best_parent_rate = 0; |
1472 | bool skip_set_rate = false; | 1473 | bool skip_set_rate = false; |
@@ -1502,7 +1503,11 @@ static void clk_change_rate(struct clk *clk) | |||
1502 | if (clk->notifier_count && old_rate != clk->rate) | 1503 | if (clk->notifier_count && old_rate != clk->rate) |
1503 | __clk_notify(clk, POST_RATE_CHANGE, old_rate, clk->rate); | 1504 | __clk_notify(clk, POST_RATE_CHANGE, old_rate, clk->rate); |
1504 | 1505 | ||
1505 | hlist_for_each_entry(child, &clk->children, child_node) { | 1506 | /* |
1507 | * Use safe iteration, as change_rate can actually swap parents | ||
1508 | * for certain clock types. | ||
1509 | */ | ||
1510 | hlist_for_each_entry_safe(child, tmp, &clk->children, child_node) { | ||
1506 | /* Skip children who will be reparented to another clock */ | 1511 | /* Skip children who will be reparented to another clock */ |
1507 | if (child->new_parent && child->new_parent != clk) | 1512 | if (child->new_parent && child->new_parent != clk) |
1508 | continue; | 1513 | continue; |