Skip to content

Commit a52a8e9

Browse files
committed
Merge tag 'clk-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux
Pull clk fix from Stephen Boyd: "A single fix for the clk framework that needed some more bake time in linux-next. The problem is that two clks being registered at the same time can lead to a busted clk tree if the parent isn't fully registered by the time the child finds the parent. We rejigger the place where we mark the parent as fully registered so that the child can't find the parent until things are proper" * tag 'clk-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux: clk: Don't parent clks until the parent is fully registered
2 parents fa36bbe + 54baf56 commit a52a8e9

File tree

1 file changed

+12
-3
lines changed

1 file changed

+12
-3
lines changed

drivers/clk/clk.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3418,6 +3418,14 @@ static int __clk_core_init(struct clk_core *core)
34183418

34193419
clk_prepare_lock();
34203420

3421+
/*
3422+
* Set hw->core after grabbing the prepare_lock to synchronize with
3423+
* callers of clk_core_fill_parent_index() where we treat hw->core
3424+
* being NULL as the clk not being registered yet. This is crucial so
3425+
* that clks aren't parented until their parent is fully registered.
3426+
*/
3427+
core->hw->core = core;
3428+
34213429
ret = clk_pm_runtime_get(core);
34223430
if (ret)
34233431
goto unlock;
@@ -3582,8 +3590,10 @@ static int __clk_core_init(struct clk_core *core)
35823590
out:
35833591
clk_pm_runtime_put(core);
35843592
unlock:
3585-
if (ret)
3593+
if (ret) {
35863594
hlist_del_init(&core->child_node);
3595+
core->hw->core = NULL;
3596+
}
35873597

35883598
clk_prepare_unlock();
35893599

@@ -3847,7 +3857,6 @@ __clk_register(struct device *dev, struct device_node *np, struct clk_hw *hw)
38473857
core->num_parents = init->num_parents;
38483858
core->min_rate = 0;
38493859
core->max_rate = ULONG_MAX;
3850-
hw->core = core;
38513860

38523861
ret = clk_core_populate_parent_map(core, init);
38533862
if (ret)
@@ -3865,7 +3874,7 @@ __clk_register(struct device *dev, struct device_node *np, struct clk_hw *hw)
38653874
goto fail_create_clk;
38663875
}
38673876

3868-
clk_core_link_consumer(hw->core, hw->clk);
3877+
clk_core_link_consumer(core, hw->clk);
38693878

38703879
ret = __clk_core_init(core);
38713880
if (!ret)

0 commit comments

Comments
 (0)