diff options
Diffstat (limited to 'drivers/clk/imx/clk-pfdv2.c')
| -rw-r--r-- | drivers/clk/imx/clk-pfdv2.c | 23 | 
1 files changed, 18 insertions, 5 deletions
| diff --git a/drivers/clk/imx/clk-pfdv2.c b/drivers/clk/imx/clk-pfdv2.c index 6b744c84278e..6ca53a960eb7 100644 --- a/drivers/clk/imx/clk-pfdv2.c +++ b/drivers/clk/imx/clk-pfdv2.c @@ -161,8 +161,17 @@ static int clk_pfdv2_set_rate(struct clk_hw *hw, unsigned long rate,  	if (!rate)  		return -EINVAL; -	/* PFD can NOT change rate without gating */ -	WARN_ON(clk_pfdv2_is_enabled(hw)); +	/* +	 * PFD can NOT change rate without gating. +	 * as the PFDs may enabled in HW by default but no +	 * consumer used it, the enable count is '0', so the +	 * 'SET_RATE_GATE' can NOT help on blocking the set_rate +	 * ops especially for 'assigned-clock-xxx'. In order +	 * to simplify the case, just disable the PFD if it is +	 * enabled in HW but not in SW. +	 */ +	if (clk_pfdv2_is_enabled(hw)) +		clk_pfdv2_disable(hw);  	tmp = tmp * 18 + rate / 2;  	do_div(tmp, rate); @@ -191,8 +200,8 @@ static const struct clk_ops clk_pfdv2_ops = {  	.is_enabled     = clk_pfdv2_is_enabled,  }; -struct clk_hw *imx_clk_hw_pfdv2(const char *name, const char *parent_name, -			     void __iomem *reg, u8 idx) +struct clk_hw *imx_clk_hw_pfdv2(enum imx_pfdv2_type type, const char *name, +			     const char *parent_name, void __iomem *reg, u8 idx)  {  	struct clk_init_data init;  	struct clk_pfdv2 *pfd; @@ -214,7 +223,10 @@ struct clk_hw *imx_clk_hw_pfdv2(const char *name, const char *parent_name,  	init.ops = &clk_pfdv2_ops;  	init.parent_names = &parent_name;  	init.num_parents = 1; -	init.flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT; +	if (type == IMX_PFDV2_IMX7ULP) +		init.flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT; +	else +		init.flags = CLK_SET_RATE_GATE;  	pfd->hw.init = &init; @@ -227,3 +239,4 @@ struct clk_hw *imx_clk_hw_pfdv2(const char *name, const char *parent_name,  	return hw;  } +EXPORT_SYMBOL_GPL(imx_clk_hw_pfdv2); |