Commit d4961772 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull clk fixes from Stephen Boyd:
 "Here's the latest pile of clk driver and clk framework fixes for this
  release:

   - Two clk framework fixes for a long standing issue in
     clk_notifier_{register,unregister}() where we used a pointer that
     was for a struct containing a list head when there was no container
     struct

   - A compile warning fix for socfpga that's good to have

   - A double free problem with devm registered fixed factor clks

   - One last fix to the Qualcomm camera clk driver to use the right clk
     ops so clks don't get stuck and stop working because the firmware
     takes them for a ride"

* tag 'clk-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux:
  clk: fixed: fix double free in resource managed fixed-factor clock
  clk: fix invalid usage of list cursor in unregister
  clk: fix invalid usage of list cursor in register
  clk: qcom: camcc: Update the clock ops for the SC7180
  clk: socfpga: fix iomem pointer cast on 64-bit
parents 9288e1f7 50ce6826
...@@ -66,7 +66,14 @@ EXPORT_SYMBOL_GPL(clk_fixed_factor_ops); ...@@ -66,7 +66,14 @@ EXPORT_SYMBOL_GPL(clk_fixed_factor_ops);
static void devm_clk_hw_register_fixed_factor_release(struct device *dev, void *res) static void devm_clk_hw_register_fixed_factor_release(struct device *dev, void *res)
{ {
clk_hw_unregister_fixed_factor(&((struct clk_fixed_factor *)res)->hw); struct clk_fixed_factor *fix = res;
/*
* We can not use clk_hw_unregister_fixed_factor, since it will kfree()
* the hw, resulting in double free. Just unregister the hw and let
* devres code kfree() it.
*/
clk_hw_unregister(&fix->hw);
} }
static struct clk_hw * static struct clk_hw *
......
...@@ -4357,20 +4357,19 @@ int clk_notifier_register(struct clk *clk, struct notifier_block *nb) ...@@ -4357,20 +4357,19 @@ int clk_notifier_register(struct clk *clk, struct notifier_block *nb)
/* search the list of notifiers for this clk */ /* search the list of notifiers for this clk */
list_for_each_entry(cn, &clk_notifier_list, node) list_for_each_entry(cn, &clk_notifier_list, node)
if (cn->clk == clk) if (cn->clk == clk)
break; goto found;
/* if clk wasn't in the notifier list, allocate new clk_notifier */ /* if clk wasn't in the notifier list, allocate new clk_notifier */
if (cn->clk != clk) { cn = kzalloc(sizeof(*cn), GFP_KERNEL);
cn = kzalloc(sizeof(*cn), GFP_KERNEL); if (!cn)
if (!cn) goto out;
goto out;
cn->clk = clk; cn->clk = clk;
srcu_init_notifier_head(&cn->notifier_head); srcu_init_notifier_head(&cn->notifier_head);
list_add(&cn->node, &clk_notifier_list); list_add(&cn->node, &clk_notifier_list);
}
found:
ret = srcu_notifier_chain_register(&cn->notifier_head, nb); ret = srcu_notifier_chain_register(&cn->notifier_head, nb);
clk->core->notifier_count++; clk->core->notifier_count++;
...@@ -4395,32 +4394,28 @@ EXPORT_SYMBOL_GPL(clk_notifier_register); ...@@ -4395,32 +4394,28 @@ EXPORT_SYMBOL_GPL(clk_notifier_register);
*/ */
int clk_notifier_unregister(struct clk *clk, struct notifier_block *nb) int clk_notifier_unregister(struct clk *clk, struct notifier_block *nb)
{ {
struct clk_notifier *cn = NULL; struct clk_notifier *cn;
int ret = -EINVAL; int ret = -ENOENT;
if (!clk || !nb) if (!clk || !nb)
return -EINVAL; return -EINVAL;
clk_prepare_lock(); clk_prepare_lock();
list_for_each_entry(cn, &clk_notifier_list, node) list_for_each_entry(cn, &clk_notifier_list, node) {
if (cn->clk == clk) if (cn->clk == clk) {
break; ret = srcu_notifier_chain_unregister(&cn->notifier_head, nb);
if (cn->clk == clk) {
ret = srcu_notifier_chain_unregister(&cn->notifier_head, nb);
clk->core->notifier_count--; clk->core->notifier_count--;
/* XXX the notifier code should handle this better */ /* XXX the notifier code should handle this better */
if (!cn->notifier_head.head) { if (!cn->notifier_head.head) {
srcu_cleanup_notifier_head(&cn->notifier_head); srcu_cleanup_notifier_head(&cn->notifier_head);
list_del(&cn->node); list_del(&cn->node);
kfree(cn); kfree(cn);
}
break;
} }
} else {
ret = -ENOENT;
} }
clk_prepare_unlock(); clk_prepare_unlock();
......
...@@ -304,7 +304,7 @@ static struct clk_rcg2 cam_cc_bps_clk_src = { ...@@ -304,7 +304,7 @@ static struct clk_rcg2 cam_cc_bps_clk_src = {
.name = "cam_cc_bps_clk_src", .name = "cam_cc_bps_clk_src",
.parent_data = cam_cc_parent_data_2, .parent_data = cam_cc_parent_data_2,
.num_parents = 5, .num_parents = 5,
.ops = &clk_rcg2_ops, .ops = &clk_rcg2_shared_ops,
}, },
}; };
...@@ -325,7 +325,7 @@ static struct clk_rcg2 cam_cc_cci_0_clk_src = { ...@@ -325,7 +325,7 @@ static struct clk_rcg2 cam_cc_cci_0_clk_src = {
.name = "cam_cc_cci_0_clk_src", .name = "cam_cc_cci_0_clk_src",
.parent_data = cam_cc_parent_data_5, .parent_data = cam_cc_parent_data_5,
.num_parents = 3, .num_parents = 3,
.ops = &clk_rcg2_ops, .ops = &clk_rcg2_shared_ops,
}, },
}; };
...@@ -339,7 +339,7 @@ static struct clk_rcg2 cam_cc_cci_1_clk_src = { ...@@ -339,7 +339,7 @@ static struct clk_rcg2 cam_cc_cci_1_clk_src = {
.name = "cam_cc_cci_1_clk_src", .name = "cam_cc_cci_1_clk_src",
.parent_data = cam_cc_parent_data_5, .parent_data = cam_cc_parent_data_5,
.num_parents = 3, .num_parents = 3,
.ops = &clk_rcg2_ops, .ops = &clk_rcg2_shared_ops,
}, },
}; };
...@@ -360,7 +360,7 @@ static struct clk_rcg2 cam_cc_cphy_rx_clk_src = { ...@@ -360,7 +360,7 @@ static struct clk_rcg2 cam_cc_cphy_rx_clk_src = {
.name = "cam_cc_cphy_rx_clk_src", .name = "cam_cc_cphy_rx_clk_src",
.parent_data = cam_cc_parent_data_3, .parent_data = cam_cc_parent_data_3,
.num_parents = 6, .num_parents = 6,
.ops = &clk_rcg2_ops, .ops = &clk_rcg2_shared_ops,
}, },
}; };
...@@ -379,7 +379,7 @@ static struct clk_rcg2 cam_cc_csi0phytimer_clk_src = { ...@@ -379,7 +379,7 @@ static struct clk_rcg2 cam_cc_csi0phytimer_clk_src = {
.name = "cam_cc_csi0phytimer_clk_src", .name = "cam_cc_csi0phytimer_clk_src",
.parent_data = cam_cc_parent_data_0, .parent_data = cam_cc_parent_data_0,
.num_parents = 4, .num_parents = 4,
.ops = &clk_rcg2_ops, .ops = &clk_rcg2_shared_ops,
}, },
}; };
...@@ -393,7 +393,7 @@ static struct clk_rcg2 cam_cc_csi1phytimer_clk_src = { ...@@ -393,7 +393,7 @@ static struct clk_rcg2 cam_cc_csi1phytimer_clk_src = {
.name = "cam_cc_csi1phytimer_clk_src", .name = "cam_cc_csi1phytimer_clk_src",
.parent_data = cam_cc_parent_data_0, .parent_data = cam_cc_parent_data_0,
.num_parents = 4, .num_parents = 4,
.ops = &clk_rcg2_ops, .ops = &clk_rcg2_shared_ops,
}, },
}; };
...@@ -407,7 +407,7 @@ static struct clk_rcg2 cam_cc_csi2phytimer_clk_src = { ...@@ -407,7 +407,7 @@ static struct clk_rcg2 cam_cc_csi2phytimer_clk_src = {
.name = "cam_cc_csi2phytimer_clk_src", .name = "cam_cc_csi2phytimer_clk_src",
.parent_data = cam_cc_parent_data_0, .parent_data = cam_cc_parent_data_0,
.num_parents = 4, .num_parents = 4,
.ops = &clk_rcg2_ops, .ops = &clk_rcg2_shared_ops,
}, },
}; };
...@@ -421,7 +421,7 @@ static struct clk_rcg2 cam_cc_csi3phytimer_clk_src = { ...@@ -421,7 +421,7 @@ static struct clk_rcg2 cam_cc_csi3phytimer_clk_src = {
.name = "cam_cc_csi3phytimer_clk_src", .name = "cam_cc_csi3phytimer_clk_src",
.parent_data = cam_cc_parent_data_0, .parent_data = cam_cc_parent_data_0,
.num_parents = 4, .num_parents = 4,
.ops = &clk_rcg2_ops, .ops = &clk_rcg2_shared_ops,
}, },
}; };
...@@ -443,7 +443,7 @@ static struct clk_rcg2 cam_cc_fast_ahb_clk_src = { ...@@ -443,7 +443,7 @@ static struct clk_rcg2 cam_cc_fast_ahb_clk_src = {
.name = "cam_cc_fast_ahb_clk_src", .name = "cam_cc_fast_ahb_clk_src",
.parent_data = cam_cc_parent_data_0, .parent_data = cam_cc_parent_data_0,
.num_parents = 4, .num_parents = 4,
.ops = &clk_rcg2_ops, .ops = &clk_rcg2_shared_ops,
}, },
}; };
...@@ -466,7 +466,7 @@ static struct clk_rcg2 cam_cc_icp_clk_src = { ...@@ -466,7 +466,7 @@ static struct clk_rcg2 cam_cc_icp_clk_src = {
.name = "cam_cc_icp_clk_src", .name = "cam_cc_icp_clk_src",
.parent_data = cam_cc_parent_data_2, .parent_data = cam_cc_parent_data_2,
.num_parents = 5, .num_parents = 5,
.ops = &clk_rcg2_ops, .ops = &clk_rcg2_shared_ops,
}, },
}; };
...@@ -488,7 +488,7 @@ static struct clk_rcg2 cam_cc_ife_0_clk_src = { ...@@ -488,7 +488,7 @@ static struct clk_rcg2 cam_cc_ife_0_clk_src = {
.name = "cam_cc_ife_0_clk_src", .name = "cam_cc_ife_0_clk_src",
.parent_data = cam_cc_parent_data_4, .parent_data = cam_cc_parent_data_4,
.num_parents = 4, .num_parents = 4,
.ops = &clk_rcg2_ops, .ops = &clk_rcg2_shared_ops,
}, },
}; };
...@@ -510,7 +510,7 @@ static struct clk_rcg2 cam_cc_ife_0_csid_clk_src = { ...@@ -510,7 +510,7 @@ static struct clk_rcg2 cam_cc_ife_0_csid_clk_src = {
.name = "cam_cc_ife_0_csid_clk_src", .name = "cam_cc_ife_0_csid_clk_src",
.parent_data = cam_cc_parent_data_3, .parent_data = cam_cc_parent_data_3,
.num_parents = 6, .num_parents = 6,
.ops = &clk_rcg2_ops, .ops = &clk_rcg2_shared_ops,
}, },
}; };
...@@ -524,7 +524,7 @@ static struct clk_rcg2 cam_cc_ife_1_clk_src = { ...@@ -524,7 +524,7 @@ static struct clk_rcg2 cam_cc_ife_1_clk_src = {
.name = "cam_cc_ife_1_clk_src", .name = "cam_cc_ife_1_clk_src",
.parent_data = cam_cc_parent_data_4, .parent_data = cam_cc_parent_data_4,
.num_parents = 4, .num_parents = 4,
.ops = &clk_rcg2_ops, .ops = &clk_rcg2_shared_ops,
}, },
}; };
...@@ -538,7 +538,7 @@ static struct clk_rcg2 cam_cc_ife_1_csid_clk_src = { ...@@ -538,7 +538,7 @@ static struct clk_rcg2 cam_cc_ife_1_csid_clk_src = {
.name = "cam_cc_ife_1_csid_clk_src", .name = "cam_cc_ife_1_csid_clk_src",
.parent_data = cam_cc_parent_data_3, .parent_data = cam_cc_parent_data_3,
.num_parents = 6, .num_parents = 6,
.ops = &clk_rcg2_ops, .ops = &clk_rcg2_shared_ops,
}, },
}; };
...@@ -553,7 +553,7 @@ static struct clk_rcg2 cam_cc_ife_lite_clk_src = { ...@@ -553,7 +553,7 @@ static struct clk_rcg2 cam_cc_ife_lite_clk_src = {
.parent_data = cam_cc_parent_data_4, .parent_data = cam_cc_parent_data_4,
.num_parents = 4, .num_parents = 4,
.flags = CLK_SET_RATE_PARENT, .flags = CLK_SET_RATE_PARENT,
.ops = &clk_rcg2_ops, .ops = &clk_rcg2_shared_ops,
}, },
}; };
...@@ -567,7 +567,7 @@ static struct clk_rcg2 cam_cc_ife_lite_csid_clk_src = { ...@@ -567,7 +567,7 @@ static struct clk_rcg2 cam_cc_ife_lite_csid_clk_src = {
.name = "cam_cc_ife_lite_csid_clk_src", .name = "cam_cc_ife_lite_csid_clk_src",
.parent_data = cam_cc_parent_data_3, .parent_data = cam_cc_parent_data_3,
.num_parents = 6, .num_parents = 6,
.ops = &clk_rcg2_ops, .ops = &clk_rcg2_shared_ops,
}, },
}; };
...@@ -590,7 +590,7 @@ static struct clk_rcg2 cam_cc_ipe_0_clk_src = { ...@@ -590,7 +590,7 @@ static struct clk_rcg2 cam_cc_ipe_0_clk_src = {
.name = "cam_cc_ipe_0_clk_src", .name = "cam_cc_ipe_0_clk_src",
.parent_data = cam_cc_parent_data_2, .parent_data = cam_cc_parent_data_2,
.num_parents = 5, .num_parents = 5,
.ops = &clk_rcg2_ops, .ops = &clk_rcg2_shared_ops,
}, },
}; };
...@@ -613,7 +613,7 @@ static struct clk_rcg2 cam_cc_jpeg_clk_src = { ...@@ -613,7 +613,7 @@ static struct clk_rcg2 cam_cc_jpeg_clk_src = {
.name = "cam_cc_jpeg_clk_src", .name = "cam_cc_jpeg_clk_src",
.parent_data = cam_cc_parent_data_2, .parent_data = cam_cc_parent_data_2,
.num_parents = 5, .num_parents = 5,
.ops = &clk_rcg2_ops, .ops = &clk_rcg2_shared_ops,
}, },
}; };
...@@ -635,7 +635,7 @@ static struct clk_rcg2 cam_cc_lrme_clk_src = { ...@@ -635,7 +635,7 @@ static struct clk_rcg2 cam_cc_lrme_clk_src = {
.name = "cam_cc_lrme_clk_src", .name = "cam_cc_lrme_clk_src",
.parent_data = cam_cc_parent_data_6, .parent_data = cam_cc_parent_data_6,
.num_parents = 5, .num_parents = 5,
.ops = &clk_rcg2_ops, .ops = &clk_rcg2_shared_ops,
}, },
}; };
...@@ -656,7 +656,7 @@ static struct clk_rcg2 cam_cc_mclk0_clk_src = { ...@@ -656,7 +656,7 @@ static struct clk_rcg2 cam_cc_mclk0_clk_src = {
.name = "cam_cc_mclk0_clk_src", .name = "cam_cc_mclk0_clk_src",
.parent_data = cam_cc_parent_data_1, .parent_data = cam_cc_parent_data_1,
.num_parents = 3, .num_parents = 3,
.ops = &clk_rcg2_ops, .ops = &clk_rcg2_shared_ops,
}, },
}; };
...@@ -670,7 +670,7 @@ static struct clk_rcg2 cam_cc_mclk1_clk_src = { ...@@ -670,7 +670,7 @@ static struct clk_rcg2 cam_cc_mclk1_clk_src = {
.name = "cam_cc_mclk1_clk_src", .name = "cam_cc_mclk1_clk_src",
.parent_data = cam_cc_parent_data_1, .parent_data = cam_cc_parent_data_1,
.num_parents = 3, .num_parents = 3,
.ops = &clk_rcg2_ops, .ops = &clk_rcg2_shared_ops,
}, },
}; };
...@@ -684,7 +684,7 @@ static struct clk_rcg2 cam_cc_mclk2_clk_src = { ...@@ -684,7 +684,7 @@ static struct clk_rcg2 cam_cc_mclk2_clk_src = {
.name = "cam_cc_mclk2_clk_src", .name = "cam_cc_mclk2_clk_src",
.parent_data = cam_cc_parent_data_1, .parent_data = cam_cc_parent_data_1,
.num_parents = 3, .num_parents = 3,
.ops = &clk_rcg2_ops, .ops = &clk_rcg2_shared_ops,
}, },
}; };
...@@ -698,7 +698,7 @@ static struct clk_rcg2 cam_cc_mclk3_clk_src = { ...@@ -698,7 +698,7 @@ static struct clk_rcg2 cam_cc_mclk3_clk_src = {
.name = "cam_cc_mclk3_clk_src", .name = "cam_cc_mclk3_clk_src",
.parent_data = cam_cc_parent_data_1, .parent_data = cam_cc_parent_data_1,
.num_parents = 3, .num_parents = 3,
.ops = &clk_rcg2_ops, .ops = &clk_rcg2_shared_ops,
}, },
}; };
...@@ -712,7 +712,7 @@ static struct clk_rcg2 cam_cc_mclk4_clk_src = { ...@@ -712,7 +712,7 @@ static struct clk_rcg2 cam_cc_mclk4_clk_src = {
.name = "cam_cc_mclk4_clk_src", .name = "cam_cc_mclk4_clk_src",
.parent_data = cam_cc_parent_data_1, .parent_data = cam_cc_parent_data_1,
.num_parents = 3, .num_parents = 3,
.ops = &clk_rcg2_ops, .ops = &clk_rcg2_shared_ops,
}, },
}; };
...@@ -732,7 +732,7 @@ static struct clk_rcg2 cam_cc_slow_ahb_clk_src = { ...@@ -732,7 +732,7 @@ static struct clk_rcg2 cam_cc_slow_ahb_clk_src = {
.parent_data = cam_cc_parent_data_0, .parent_data = cam_cc_parent_data_0,
.num_parents = 4, .num_parents = 4,
.flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
.ops = &clk_rcg2_ops, .ops = &clk_rcg2_shared_ops,
}, },
}; };
......
...@@ -99,7 +99,7 @@ static unsigned long socfpga_clk_recalc_rate(struct clk_hw *hwclk, ...@@ -99,7 +99,7 @@ static unsigned long socfpga_clk_recalc_rate(struct clk_hw *hwclk,
val = readl(socfpgaclk->div_reg) >> socfpgaclk->shift; val = readl(socfpgaclk->div_reg) >> socfpgaclk->shift;
val &= GENMASK(socfpgaclk->width - 1, 0); val &= GENMASK(socfpgaclk->width - 1, 0);
/* Check for GPIO_DB_CLK by its offset */ /* Check for GPIO_DB_CLK by its offset */
if ((int) socfpgaclk->div_reg & SOCFPGA_GPIO_DB_CLK_OFFSET) if ((uintptr_t) socfpgaclk->div_reg & SOCFPGA_GPIO_DB_CLK_OFFSET)
div = val + 1; div = val + 1;
else else
div = (1 << val); div = (1 << val);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment