Commit 3215b9d5 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:
 "A late collection of fixes for regressions seen this release cycle.
  Normally I send this earlier than now but real life got in the way.
  Things are back to normal now.

  There's the normal set of SoC driver fixes: i.MX boot warning, TI
  display clks, allwinner clk ops being wrong (fun), driver probe
  badness on error paths, correctness fix for the new aspeed driver, and
  even a fix for a race condition in the bcm2835 clk driver.

  At the core framework level we also got some fixes for the clk phase
  API caching at the wrong time, better handling of the enabled state of
  orphan clks, and a fix for a newly introduced bug in how we handle
  rate calculations for pass-through clks"

* tag 'clk-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux:
  clk: bcm2835: Protect sections updating shared registers
  clk: bcm2835: Fix ana->maskX definitions
  clk: aspeed: Prevent reset if clock is enabled
  clk: aspeed: Fix is_enabled for certain clocks
  clk: qcom: msm8916: Fix return value check in qcom_apcs_msm8916_clk_probe()
  clk: hisilicon: hi3660:Fix potential NULL dereference in hi3660_stub_clk_probe()
  clk: fix determine rate error with pass-through clock
  clk: migrate the count of orphaned clocks at init
  clk: update cached phase to respect the fact when setting phase
  clk: ti: am43xx: add set-rate-parent support for display clkctrl clock
  clk: ti: am33xx: add set-rate-parent support for display clkctrl clock
  clk: ti: clkctrl: add support for CLK_SET_RATE_PARENT flag
  clk: imx51-imx53: Fix UART4/5 registration on i.MX50 and i.MX53
  clk: sunxi-ng: a31: Fix CLK_OUT_* clock ops
parents 303851e1 7997f3b2
......@@ -449,17 +449,17 @@ struct bcm2835_pll_ana_bits {
static const struct bcm2835_pll_ana_bits bcm2835_ana_default = {
.mask0 = 0,
.set0 = 0,
.mask1 = (u32)~(A2W_PLL_KI_MASK | A2W_PLL_KP_MASK),
.mask1 = A2W_PLL_KI_MASK | A2W_PLL_KP_MASK,
.set1 = (2 << A2W_PLL_KI_SHIFT) | (8 << A2W_PLL_KP_SHIFT),
.mask3 = (u32)~A2W_PLL_KA_MASK,
.mask3 = A2W_PLL_KA_MASK,
.set3 = (2 << A2W_PLL_KA_SHIFT),
.fb_prediv_mask = BIT(14),
};
static const struct bcm2835_pll_ana_bits bcm2835_ana_pllh = {
.mask0 = (u32)~(A2W_PLLH_KA_MASK | A2W_PLLH_KI_LOW_MASK),
.mask0 = A2W_PLLH_KA_MASK | A2W_PLLH_KI_LOW_MASK,
.set0 = (2 << A2W_PLLH_KA_SHIFT) | (2 << A2W_PLLH_KI_LOW_SHIFT),
.mask1 = (u32)~(A2W_PLLH_KI_HIGH_MASK | A2W_PLLH_KP_MASK),
.mask1 = A2W_PLLH_KI_HIGH_MASK | A2W_PLLH_KP_MASK,
.set1 = (6 << A2W_PLLH_KP_SHIFT),
.mask3 = 0,
.set3 = 0,
......@@ -623,8 +623,10 @@ static int bcm2835_pll_on(struct clk_hw *hw)
~A2W_PLL_CTRL_PWRDN);
/* Take the PLL out of reset. */
spin_lock(&cprman->regs_lock);
cprman_write(cprman, data->cm_ctrl_reg,
cprman_read(cprman, data->cm_ctrl_reg) & ~CM_PLL_ANARST);
spin_unlock(&cprman->regs_lock);
/* Wait for the PLL to lock. */
timeout = ktime_add_ns(ktime_get(), LOCK_TIMEOUT_NS);
......@@ -701,9 +703,11 @@ static int bcm2835_pll_set_rate(struct clk_hw *hw,
}
/* Unmask the reference clock from the oscillator. */
spin_lock(&cprman->regs_lock);
cprman_write(cprman, A2W_XOSC_CTRL,
cprman_read(cprman, A2W_XOSC_CTRL) |
data->reference_enable_mask);
spin_unlock(&cprman->regs_lock);
if (do_ana_setup_first)
bcm2835_pll_write_ana(cprman, data->ana_reg_base, ana);
......
......@@ -205,6 +205,18 @@ static const struct aspeed_clk_soc_data ast2400_data = {
.calc_pll = aspeed_ast2400_calc_pll,
};
static int aspeed_clk_is_enabled(struct clk_hw *hw)
{
struct aspeed_clk_gate *gate = to_aspeed_clk_gate(hw);
u32 clk = BIT(gate->clock_idx);
u32 enval = (gate->flags & CLK_GATE_SET_TO_DISABLE) ? 0 : clk;
u32 reg;
regmap_read(gate->map, ASPEED_CLK_STOP_CTRL, &reg);
return ((reg & clk) == enval) ? 1 : 0;
}
static int aspeed_clk_enable(struct clk_hw *hw)
{
struct aspeed_clk_gate *gate = to_aspeed_clk_gate(hw);
......@@ -215,6 +227,11 @@ static int aspeed_clk_enable(struct clk_hw *hw)
spin_lock_irqsave(gate->lock, flags);
if (aspeed_clk_is_enabled(hw)) {
spin_unlock_irqrestore(gate->lock, flags);
return 0;
}
if (gate->reset_idx >= 0) {
/* Put IP in reset */
regmap_update_bits(gate->map, ASPEED_RESET_CTRL, rst, rst);
......@@ -255,17 +272,6 @@ static void aspeed_clk_disable(struct clk_hw *hw)
spin_unlock_irqrestore(gate->lock, flags);
}
static int aspeed_clk_is_enabled(struct clk_hw *hw)
{
struct aspeed_clk_gate *gate = to_aspeed_clk_gate(hw);
u32 clk = BIT(gate->clock_idx);
u32 reg;
regmap_read(gate->map, ASPEED_CLK_STOP_CTRL, &reg);
return (reg & clk) ? 0 : 1;
}
static const struct clk_ops aspeed_clk_gate_ops = {
.enable = aspeed_clk_enable,
.disable = aspeed_clk_disable,
......
......@@ -1125,8 +1125,10 @@ static int clk_core_round_rate_nolock(struct clk_core *core,
{
lockdep_assert_held(&prepare_lock);
if (!core)
if (!core) {
req->rate = 0;
return 0;
}
clk_core_init_rate_req(core, req);
......@@ -2309,8 +2311,11 @@ static int clk_core_set_phase_nolock(struct clk_core *core, int degrees)
trace_clk_set_phase(core, degrees);
if (core->ops->set_phase)
if (core->ops->set_phase) {
ret = core->ops->set_phase(core->hw, degrees);
if (!ret)
core->phase = degrees;
}
trace_clk_set_phase_complete(core, degrees);
......@@ -2967,23 +2972,38 @@ static int __clk_core_init(struct clk_core *core)
rate = 0;
core->rate = core->req_rate = rate;
/*
* Enable CLK_IS_CRITICAL clocks so newly added critical clocks
* don't get accidentally disabled when walking the orphan tree and
* reparenting clocks
*/
if (core->flags & CLK_IS_CRITICAL) {
unsigned long flags;
clk_core_prepare(core);
flags = clk_enable_lock();
clk_core_enable(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);
unsigned long flags;
/*
* we could call __clk_set_parent, but that would result in a
* redundant call to the .set_rate op, if it exists
* 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 */
flags = clk_enable_lock();
clk_reparent(orphan, parent);
clk_enable_unlock(flags);
__clk_set_parent_before(orphan, parent);
__clk_set_parent_after(orphan, parent, NULL);
__clk_recalc_accuracies(orphan);
__clk_recalc_rates(orphan, 0);
}
......@@ -3000,16 +3020,6 @@ static int __clk_core_init(struct clk_core *core)
if (core->ops->init)
core->ops->init(core->hw);
if (core->flags & CLK_IS_CRITICAL) {
unsigned long flags;
clk_core_prepare(core);
flags = clk_enable_lock();
clk_core_enable(core);
clk_enable_unlock(flags);
}
kref_init(&core->ref);
out:
clk_pm_runtime_put(core);
......
......@@ -149,6 +149,8 @@ static int hi3660_stub_clk_probe(struct platform_device *pdev)
return PTR_ERR(stub_clk_chan.mbox);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res)
return -EINVAL;
freq_reg = devm_ioremap(dev, res->start, resource_size(res));
if (!freq_reg)
return -ENOMEM;
......
......@@ -131,7 +131,17 @@ static const char *ieee1588_sels[] = { "pll3_sw", "pll4_sw", "dummy" /* usbphy2_
static struct clk *clk[IMX5_CLK_END];
static struct clk_onecell_data clk_data;
static struct clk ** const uart_clks[] __initconst = {
static struct clk ** const uart_clks_mx51[] __initconst = {
&clk[IMX5_CLK_UART1_IPG_GATE],
&clk[IMX5_CLK_UART1_PER_GATE],
&clk[IMX5_CLK_UART2_IPG_GATE],
&clk[IMX5_CLK_UART2_PER_GATE],
&clk[IMX5_CLK_UART3_IPG_GATE],
&clk[IMX5_CLK_UART3_PER_GATE],
NULL
};
static struct clk ** const uart_clks_mx50_mx53[] __initconst = {
&clk[IMX5_CLK_UART1_IPG_GATE],
&clk[IMX5_CLK_UART1_PER_GATE],
&clk[IMX5_CLK_UART2_IPG_GATE],
......@@ -321,8 +331,6 @@ static void __init mx5_clocks_common_init(void __iomem *ccm_base)
clk_prepare_enable(clk[IMX5_CLK_TMAX1]);
clk_prepare_enable(clk[IMX5_CLK_TMAX2]); /* esdhc2, fec */
clk_prepare_enable(clk[IMX5_CLK_TMAX3]); /* esdhc1, esdhc4 */
imx_register_uart_clocks(uart_clks);
}
static void __init mx50_clocks_init(struct device_node *np)
......@@ -388,6 +396,8 @@ static void __init mx50_clocks_init(struct device_node *np)
r = clk_round_rate(clk[IMX5_CLK_USBOH3_PER_GATE], 54000000);
clk_set_rate(clk[IMX5_CLK_USBOH3_PER_GATE], r);
imx_register_uart_clocks(uart_clks_mx50_mx53);
}
CLK_OF_DECLARE(imx50_ccm, "fsl,imx50-ccm", mx50_clocks_init);
......@@ -477,6 +487,8 @@ static void __init mx51_clocks_init(struct device_node *np)
val = readl(MXC_CCM_CLPCR);
val |= 1 << 23;
writel(val, MXC_CCM_CLPCR);
imx_register_uart_clocks(uart_clks_mx51);
}
CLK_OF_DECLARE(imx51_ccm, "fsl,imx51-ccm", mx51_clocks_init);
......@@ -606,5 +618,7 @@ static void __init mx53_clocks_init(struct device_node *np)
r = clk_round_rate(clk[IMX5_CLK_USBOH3_PER_GATE], 54000000);
clk_set_rate(clk[IMX5_CLK_USBOH3_PER_GATE], r);
imx_register_uart_clocks(uart_clks_mx50_mx53);
}
CLK_OF_DECLARE(imx53_ccm, "fsl,imx53-ccm", mx53_clocks_init);
......@@ -49,11 +49,10 @@ static int qcom_apcs_msm8916_clk_probe(struct platform_device *pdev)
struct clk_regmap_mux_div *a53cc;
struct regmap *regmap;
struct clk_init_data init = { };
int ret;
int ret = -ENODEV;
regmap = dev_get_regmap(parent, NULL);
if (IS_ERR(regmap)) {
ret = PTR_ERR(regmap);
if (!regmap) {
dev_err(dev, "failed to get regmap: %d\n", ret);
return ret;
}
......
......@@ -762,7 +762,7 @@ static struct ccu_mp out_a_clk = {
.features = CCU_FEATURE_FIXED_PREDIV,
.hw.init = CLK_HW_INIT_PARENTS("out-a",
clk_out_parents,
&ccu_div_ops,
&ccu_mp_ops,
0),
},
};
......@@ -783,7 +783,7 @@ static struct ccu_mp out_b_clk = {
.features = CCU_FEATURE_FIXED_PREDIV,
.hw.init = CLK_HW_INIT_PARENTS("out-b",
clk_out_parents,
&ccu_div_ops,
&ccu_mp_ops,
0),
},
};
......@@ -804,7 +804,7 @@ static struct ccu_mp out_c_clk = {
.features = CCU_FEATURE_FIXED_PREDIV,
.hw.init = CLK_HW_INIT_PARENTS("out-c",
clk_out_parents,
&ccu_div_ops,
&ccu_mp_ops,
0),
},
};
......
......@@ -45,7 +45,7 @@ static const struct omap_clkctrl_bit_data am3_gpio4_bit_data[] __initconst = {
static const struct omap_clkctrl_reg_data am3_l4_per_clkctrl_regs[] __initconst = {
{ AM3_CPGMAC0_CLKCTRL, NULL, CLKF_SW_SUP, "cpsw_125mhz_gclk", "cpsw_125mhz_clkdm" },
{ AM3_LCDC_CLKCTRL, NULL, CLKF_SW_SUP, "lcd_gclk", "lcdc_clkdm" },
{ AM3_LCDC_CLKCTRL, NULL, CLKF_SW_SUP | CLKF_SET_RATE_PARENT, "lcd_gclk", "lcdc_clkdm" },
{ AM3_USB_OTG_HS_CLKCTRL, NULL, CLKF_SW_SUP, "usbotg_fck", "l3s_clkdm" },
{ AM3_TPTC0_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" },
{ AM3_EMIF_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_ddr_m2_div2_ck", "l3_clkdm" },
......
......@@ -187,7 +187,7 @@ static const struct omap_clkctrl_reg_data am4_l4_per_clkctrl_regs[] __initconst
{ AM4_OCP2SCP0_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" },
{ AM4_OCP2SCP1_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" },
{ AM4_EMIF_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_ddr_m2_ck", "emif_clkdm" },
{ AM4_DSS_CORE_CLKCTRL, NULL, CLKF_SW_SUP, "disp_clk", "dss_clkdm" },
{ AM4_DSS_CORE_CLKCTRL, NULL, CLKF_SW_SUP | CLKF_SET_RATE_PARENT, "disp_clk", "dss_clkdm" },
{ AM4_CPGMAC0_CLKCTRL, NULL, CLKF_SW_SUP, "cpsw_125mhz_gclk", "cpsw_125mhz_clkdm" },
{ 0 },
};
......
......@@ -537,6 +537,8 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node)
init.parent_names = &reg_data->parent;
init.num_parents = 1;
init.flags = 0;
if (reg_data->flags & CLKF_SET_RATE_PARENT)
init.flags |= CLK_SET_RATE_PARENT;
init.name = kasprintf(GFP_KERNEL, "%s:%s:%04x:%d",
node->parent->name, node->name,
reg_data->offset, 0);
......
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