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. -----BEGIN PGP SIGNATURE----- iQJFBAABCAAvFiEE9L57QeeUxqYDyoaDrQKIl8bklSUFAmG7kWERHHNib3lkQGtl cm5lbC5vcmcACgkQrQKIl8bklSVx+w//fOqrqTa7GmF8sJ8NCupsguITAOjwfZYr 5Gifw9yRwTOUGpgPX2mrvFrOLhQTdnQ+WzPzve0WNa1IE/KmuxDrt2FaAhRZ6VKy w2Ix0xm2oJhECnvVFTUZSrRNSCKQbB1IBph0Zj8hJaFc02ZPftC1alTmSAW2hcAr dvx7PB+hhVIsmgJp//7CfXAR0rJI6cEiIpr5sOyoTNTV1Rp0KK0ZqgLuyq1ibUj8 JEyi1OZsKN/+sXV4xaTGK8ECLwhx16KCKWYQYaUZfd7yL79hbRz3vwCFcEOAK6tg HG6MW1ZxaY4GT0dH06XVjBu2JmIeqbmFeXf4UWeIilctKflANikKZlWdkoJrOO2e t7aYIVxu1SOkv6WmskugrV5ZM4CmIjs7qGx5q73Iu0bUeXjY0bI3NazfBlVJmV9K fTIEex3zFfnjDWCkoloVnCHDjBTUjOJ6CKPWpTH7qlJlT8z3iv4rJWnmZzpIS5Kg 4tP2xa+mMkmsluhhjGjQk4ofgaK53iQbik+cApdkmZSga/nJTo56cWnaKgUyONAR AcWi9QWwVwg0NeeSd8ZyUu+lGb4l+fv91DINeVv+04JmaCKggSdE64v+zrt2hE1n zZAHifaGfrebZe9w6Ugr0Ex/81E6Ev7ud8HGPw6MMZyoSScDESwXPHja/zJtnNns sClDnXFlJ3g= =UA+0 -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
a52a8e9eaf
|
@ -3418,6 +3418,14 @@ static int __clk_core_init(struct clk_core *core)
|
|||
|
||||
clk_prepare_lock();
|
||||
|
||||
/*
|
||||
* Set hw->core after grabbing the prepare_lock to synchronize with
|
||||
* callers of clk_core_fill_parent_index() where we treat hw->core
|
||||
* being NULL as the clk not being registered yet. This is crucial so
|
||||
* that clks aren't parented until their parent is fully registered.
|
||||
*/
|
||||
core->hw->core = core;
|
||||
|
||||
ret = clk_pm_runtime_get(core);
|
||||
if (ret)
|
||||
goto unlock;
|
||||
|
@ -3582,8 +3590,10 @@ static int __clk_core_init(struct clk_core *core)
|
|||
out:
|
||||
clk_pm_runtime_put(core);
|
||||
unlock:
|
||||
if (ret)
|
||||
if (ret) {
|
||||
hlist_del_init(&core->child_node);
|
||||
core->hw->core = NULL;
|
||||
}
|
||||
|
||||
clk_prepare_unlock();
|
||||
|
||||
|
@ -3847,7 +3857,6 @@ __clk_register(struct device *dev, struct device_node *np, struct clk_hw *hw)
|
|||
core->num_parents = init->num_parents;
|
||||
core->min_rate = 0;
|
||||
core->max_rate = ULONG_MAX;
|
||||
hw->core = core;
|
||||
|
||||
ret = clk_core_populate_parent_map(core, init);
|
||||
if (ret)
|
||||
|
@ -3865,7 +3874,7 @@ __clk_register(struct device *dev, struct device_node *np, struct clk_hw *hw)
|
|||
goto fail_create_clk;
|
||||
}
|
||||
|
||||
clk_core_link_consumer(hw->core, hw->clk);
|
||||
clk_core_link_consumer(core, hw->clk);
|
||||
|
||||
ret = __clk_core_init(core);
|
||||
if (!ret)
|
||||
|
|
Loading…
Reference in New Issue