One core framework fix to walk the orphan list and match up clks to

parents when clk providers register the DT provider after registering
 all their clks (as they should). Then a handful of driver fixes for the
 qcom, imx, and at91 drivers. The driver fixes are relatively small fixes
 for incorrect register settings or missing locks causing race
 conditions.
 -----BEGIN PGP SIGNATURE-----
 
 iQJFBAABCAAvFiEE9L57QeeUxqYDyoaDrQKIl8bklSUFAl39mi8RHHNib3lkQGtl
 cm5lbC5vcmcACgkQrQKIl8bklSUqKBAAieZ+vd5y0G04xTsUHnM1p7zqvqSzHJoM
 zl1hd5t1ag6hOrkOiaei1W8n10xIw4oIsyJm5iirKzmtIiqLPxQhDjKIMGtcDj9s
 wqvOSSUEn6TKC9aajdjIHnZLmy6UWg5Zu+c8SaxE0ssuCKv/ZV3Mn0YViRSuZIIw
 isngZMsD4QlkdmtcKDuxdg27tz+FG72fMa7CN6xvlC5SXMqfrYl8UdShVQTNWoeE
 4DQunD54zUDpBxwZIUuALTpFWnWbRRAnmSQxUBrXBqpJAbpofnfuiLM+T/RFwXiO
 qAawJtmv43AVAAjLVHtgA2UdgXhEJQhgjzmhVbjTz6y5tYV0oqBnOmHXIwOi1nG2
 Rw1Zq4+5Vsn3ChlIdIaN1RyEyImIruOu3wP/ttAc5wFGV11jMEBn6SA/RC7ovuO6
 3nUsoUHarnf4YYDAu7YFDcVaFyt+jLzySMg5dwwaIb+pfu6PyM10GKIEt04Js2Ul
 eZskXxLj133hV1Pj+Z6rMAmPdraLdZfi5o9IOaeJvfEnlqyzI4d1Q9J+1oXJl7Fc
 acB0zWO/NfHd3D7zUFcCi7Da49usuG3sxLeK6I9/GmBEPbeUfcufDrzTADpBqnhY
 J+Ra4KVNZI4lYzI5JMDHC491dyjIIoWe1eWuHaT3o4VFNgpNH6LBrOetqT6YnmKv
 69/jiNEvCrg=
 =Ac9x
 -----END PGP SIGNATURE-----

Merge tag 'clk-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux

Pull clk fixes from Stephen Boyd:
 "One core framework fix to walk the orphan list and match up clks to
  parents when clk providers register the DT provider after registering
  all their clks (as they should).

  Then a handful of driver fixes for the qcom, imx, and at91 drivers.

  The driver fixes are relatively small fixes for incorrect register
  settings or missing locks causing race conditions"

* tag 'clk-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux:
  clk: qcom: Avoid SMMU/cx gdsc corner cases
  clk: qcom: gcc-sc7180: Fix setting flag for votable GDSCs
  clk: Move clk_core_reparent_orphans() under CONFIG_OF
  clk: at91: fix possible deadlock
  clk: walk orphan list on clock provider registration
  clk: imx: pll14xx: fix clk_pll14xx_wait_lock
  clk: imx: clk-imx7ulp: Add missing sentinel of ulp_div_table
  clk: imx: clk-composite-8m: add lock to gate/mux
This commit is contained in:
Linus Torvalds 2019-12-21 05:55:35 -08:00
commit 12ac9a08fc
12 changed files with 56 additions and 31 deletions

View File

@ -348,7 +348,7 @@ static void __init at91sam926x_pmc_setup(struct device_node *np,
return;
mainxtal_name = of_clk_get_parent_name(np, i);
regmap = syscon_node_to_regmap(np);
regmap = device_node_to_regmap(np);
if (IS_ERR(regmap))
return;

View File

@ -83,7 +83,7 @@ static void __init at91sam9rl_pmc_setup(struct device_node *np)
return;
mainxtal_name = of_clk_get_parent_name(np, i);
regmap = syscon_node_to_regmap(np);
regmap = device_node_to_regmap(np);
if (IS_ERR(regmap))
return;

View File

@ -146,7 +146,7 @@ static void __init at91sam9x5_pmc_setup(struct device_node *np,
return;
mainxtal_name = of_clk_get_parent_name(np, i);
regmap = syscon_node_to_regmap(np);
regmap = device_node_to_regmap(np);
if (IS_ERR(regmap))
return;

View File

@ -275,7 +275,7 @@ static int __init pmc_register_ops(void)
np = of_find_matching_node(NULL, sama5d2_pmc_dt_ids);
pmcreg = syscon_node_to_regmap(np);
pmcreg = device_node_to_regmap(np);
if (IS_ERR(pmcreg))
return PTR_ERR(pmcreg);

View File

@ -162,7 +162,7 @@ static void __init sama5d2_pmc_setup(struct device_node *np)
return;
mainxtal_name = of_clk_get_parent_name(np, i);
regmap = syscon_node_to_regmap(np);
regmap = device_node_to_regmap(np);
if (IS_ERR(regmap))
return;

View File

@ -136,7 +136,7 @@ static void __init sama5d4_pmc_setup(struct device_node *np)
return;
mainxtal_name = of_clk_get_parent_name(np, i);
regmap = syscon_node_to_regmap(np);
regmap = device_node_to_regmap(np);
if (IS_ERR(regmap))
return;

View File

@ -3249,6 +3249,34 @@ static inline void clk_debug_unregister(struct clk_core *core)
}
#endif
static void clk_core_reparent_orphans_nolock(void)
{
struct clk_core *orphan;
struct hlist_node *tmp2;
/*
* walk the list of orphan clocks and reparent any that newly finds a
* parent.
*/
hlist_for_each_entry_safe(orphan, tmp2, &clk_orphan_list, child_node) {
struct clk_core *parent = __clk_init_parent(orphan);
/*
* We need to use __clk_set_parent_before() and _after() to
* to properly migrate any prepare/enable count of the orphan
* clock. This is important for CLK_IS_CRITICAL clocks, which
* are enabled during init but might not have a parent yet.
*/
if (parent) {
/* update the clk tree topology */
__clk_set_parent_before(orphan, parent);
__clk_set_parent_after(orphan, parent, NULL);
__clk_recalc_accuracies(orphan);
__clk_recalc_rates(orphan, 0);
}
}
}
/**
* __clk_core_init - initialize the data structures in a struct clk_core
* @core: clk_core being initialized
@ -3259,8 +3287,6 @@ static inline void clk_debug_unregister(struct clk_core *core)
static int __clk_core_init(struct clk_core *core)
{
int ret;
struct clk_core *orphan;
struct hlist_node *tmp2;
unsigned long rate;
if (!core)
@ -3407,27 +3433,8 @@ static int __clk_core_init(struct clk_core *core)
clk_enable_unlock(flags);
}
/*
* walk the list of orphan clocks and reparent any that newly finds a
* parent.
*/
hlist_for_each_entry_safe(orphan, tmp2, &clk_orphan_list, child_node) {
struct clk_core *parent = __clk_init_parent(orphan);
clk_core_reparent_orphans_nolock();
/*
* We need to use __clk_set_parent_before() and _after() to
* to properly migrate any prepare/enable count of the orphan
* clock. This is important for CLK_IS_CRITICAL clocks, which
* are enabled during init but might not have a parent yet.
*/
if (parent) {
/* update the clk tree topology */
__clk_set_parent_before(orphan, parent);
__clk_set_parent_after(orphan, parent, NULL);
__clk_recalc_accuracies(orphan);
__clk_recalc_rates(orphan, 0);
}
}
kref_init(&core->ref);
out:
@ -4179,6 +4186,13 @@ int clk_notifier_unregister(struct clk *clk, struct notifier_block *nb)
EXPORT_SYMBOL_GPL(clk_notifier_unregister);
#ifdef CONFIG_OF
static void clk_core_reparent_orphans(void)
{
clk_prepare_lock();
clk_core_reparent_orphans_nolock();
clk_prepare_unlock();
}
/**
* struct of_clk_provider - Clock provider registration structure
* @link: Entry in global list of clock providers
@ -4274,6 +4288,8 @@ int of_clk_add_provider(struct device_node *np,
mutex_unlock(&of_clk_mutex);
pr_debug("Added clock from %pOF\n", np);
clk_core_reparent_orphans();
ret = of_clk_set_defaults(np, true);
if (ret < 0)
of_clk_del_provider(np);
@ -4309,6 +4325,8 @@ int of_clk_add_hw_provider(struct device_node *np,
mutex_unlock(&of_clk_mutex);
pr_debug("Added clk_hw provider from %pOF\n", np);
clk_core_reparent_orphans();
ret = of_clk_set_defaults(np, true);
if (ret < 0)
of_clk_del_provider(np);

View File

@ -142,6 +142,7 @@ struct clk *imx8m_clk_composite_flags(const char *name,
mux->reg = reg;
mux->shift = PCG_PCS_SHIFT;
mux->mask = PCG_PCS_MASK;
mux->lock = &imx_ccm_lock;
div = kzalloc(sizeof(*div), GFP_KERNEL);
if (!div)
@ -161,6 +162,7 @@ struct clk *imx8m_clk_composite_flags(const char *name,
gate_hw = &gate->hw;
gate->reg = reg;
gate->bit_idx = PCG_CGC_SHIFT;
gate->lock = &imx_ccm_lock;
hw = clk_hw_register_composite(NULL, name, parent_names, num_parents,
mux_hw, &clk_mux_ops, div_hw,

View File

@ -40,6 +40,7 @@ static const struct clk_div_table ulp_div_table[] = {
{ .val = 5, .div = 16, },
{ .val = 6, .div = 32, },
{ .val = 7, .div = 64, },
{ /* sentinel */ },
};
static const int pcc2_uart_clk_ids[] __initconst = {

View File

@ -159,7 +159,7 @@ static int clk_pll14xx_wait_lock(struct clk_pll14xx *pll)
{
u32 val;
return readl_poll_timeout(pll->base, val, val & LOCK_TIMEOUT_US, 0,
return readl_poll_timeout(pll->base, val, val & LOCK_STATUS, 0,
LOCK_TIMEOUT_US);
}

View File

@ -2186,7 +2186,8 @@ static struct gdsc hlos1_vote_mmnoc_mmu_tbu_hf0_gdsc = {
.pd = {
.name = "hlos1_vote_mmnoc_mmu_tbu_hf0_gdsc",
},
.pwrsts = PWRSTS_OFF_ON | VOTABLE,
.pwrsts = PWRSTS_OFF_ON,
.flags = VOTABLE,
};
static struct gdsc hlos1_vote_mmnoc_mmu_tbu_sf_gdsc = {
@ -2194,7 +2195,8 @@ static struct gdsc hlos1_vote_mmnoc_mmu_tbu_sf_gdsc = {
.pd = {
.name = "hlos1_vote_mmnoc_mmu_tbu_sf_gdsc",
},
.pwrsts = PWRSTS_OFF_ON | VOTABLE,
.pwrsts = PWRSTS_OFF_ON,
.flags = VOTABLE,
};
static struct gdsc *gcc_sc7180_gdscs[] = {

View File

@ -242,10 +242,12 @@ static struct clk_branch gfx3d_isense_clk = {
static struct gdsc gpu_cx_gdsc = {
.gdscr = 0x1004,
.gds_hw_ctrl = 0x1008,
.pd = {
.name = "gpu_cx",
},
.pwrsts = PWRSTS_OFF_ON,
.flags = VOTABLE,
};
static struct gdsc gpu_gx_gdsc = {