Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1ee89c51 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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

Pull clock framework fixes from Michael Turquette:
 "The clk fixes for 4.0-rc4 comprise three themes.

  First are the usual driver fixes for new regressions since v3.19.

  Second are fixes to the common clock divider type caused by recent
  changes to how we round clock rates.  This affects many clock drivers
  that use this common code.

  Finally there are fixes for drivers that improperly compared struct
  clk pointers (drivers must not deref these pointers).  While some of
  these drivers have done this for a long time, this did not cause a
  problem until we started generating unique struct clk pointers for
  every consumer.  A new function, clk_is_match was introduced to get
  these drivers working again and they are fixed up to no longer deref
  the pointers themselves"

* tag 'clk-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux:
  ASoC: kirkwood: fix struct clk pointer comparing
  ASoC: fsl_spdif: fix struct clk pointer comparing
  ARM: imx: fix struct clk pointer comparing
  clk: introduce clk_is_match
  clk: don't export static symbol
  clk: divider: fix calculation of initial best divider when rounding to closest
  clk: divider: fix selection of divider when rounding to closest
  clk: divider: fix calculation of maximal parent rate for a given divider
  clk: divider: return real rate instead of divider value
  clk: qcom: fix platform_no_drv_owner.cocci warnings
  clk: qcom: fix platform_no_drv_owner.cocci warnings
  clk: qcom: Add PLL4 vote clock
  clk: qcom: lcc-msm8960: Fix PLL rate detection
  clk: qcom: Fix slimbus n and m val offsets
  clk: ti: Fix FAPLL parent enable bit handling
parents 6981e2af aaa6d062
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -211,7 +211,8 @@ static void __init imx6q_1588_init(void)
	 * set bit IOMUXC_GPR1[21].  Or the PTP clock must be from pad
	 * (external OSC), and we need to clear the bit.
	 */
	clksel = ptp_clk == enet_ref ? IMX6Q_GPR1_ENET_CLK_SEL_ANATOP :
	clksel = clk_is_match(ptp_clk, enet_ref) ?
				IMX6Q_GPR1_ENET_CLK_SEL_ANATOP :
				IMX6Q_GPR1_ENET_CLK_SEL_PAD;
	gpr = syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
	if (!IS_ERR(gpr))
+14 −15
Original line number Diff line number Diff line
@@ -144,12 +144,6 @@ static unsigned long clk_divider_recalc_rate(struct clk_hw *hw,
				   divider->flags);
}

/*
 * The reverse of DIV_ROUND_UP: The maximum number which
 * divided by m is r
 */
#define MULT_ROUND_UP(r, m) ((r) * (m) + (m) - 1)

static bool _is_valid_table_div(const struct clk_div_table *table,
							 unsigned int div)
{
@@ -225,19 +219,24 @@ static int _div_round_closest(const struct clk_div_table *table,
			      unsigned long parent_rate, unsigned long rate,
			      unsigned long flags)
{
	int up, down, div;
	int up, down;
	unsigned long up_rate, down_rate;

	up = down = div = DIV_ROUND_CLOSEST(parent_rate, rate);
	up = DIV_ROUND_UP(parent_rate, rate);
	down = parent_rate / rate;

	if (flags & CLK_DIVIDER_POWER_OF_TWO) {
		up = __roundup_pow_of_two(div);
		down = __rounddown_pow_of_two(div);
		up = __roundup_pow_of_two(up);
		down = __rounddown_pow_of_two(down);
	} else if (table) {
		up = _round_up_table(table, div);
		down = _round_down_table(table, div);
		up = _round_up_table(table, up);
		down = _round_down_table(table, down);
	}

	return (up - div) <= (div - down) ? up : down;
	up_rate = DIV_ROUND_UP(parent_rate, up);
	down_rate = DIV_ROUND_UP(parent_rate, down);

	return (rate - up_rate) <= (down_rate - rate) ? up : down;
}

static int _div_round(const struct clk_div_table *table,
@@ -313,7 +312,7 @@ static int clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate,
			return i;
		}
		parent_rate = __clk_round_rate(__clk_get_parent(hw->clk),
				MULT_ROUND_UP(rate, i));
					       rate * i);
		now = DIV_ROUND_UP(parent_rate, i);
		if (_is_best_div(rate, now, best, flags)) {
			bestdiv = i;
@@ -353,7 +352,7 @@ static long clk_divider_round_rate(struct clk_hw *hw, unsigned long rate,
		bestdiv = readl(divider->reg) >> divider->shift;
		bestdiv &= div_mask(divider->width);
		bestdiv = _get_div(divider->table, bestdiv, divider->flags);
		return bestdiv;
		return DIV_ROUND_UP(*prate, bestdiv);
	}

	return divider_round_rate(hw, rate, prate, divider->table,
+26 −1
Original line number Diff line number Diff line
@@ -1350,7 +1350,6 @@ static unsigned long clk_core_get_rate(struct clk_core *clk)

	return rate;
}
EXPORT_SYMBOL_GPL(clk_core_get_rate);

/**
 * clk_get_rate - return the rate of clk
@@ -2170,6 +2169,32 @@ int clk_get_phase(struct clk *clk)
	return clk_core_get_phase(clk->core);
}

/**
 * clk_is_match - check if two clk's point to the same hardware clock
 * @p: clk compared against q
 * @q: clk compared against p
 *
 * Returns true if the two struct clk pointers both point to the same hardware
 * clock node. Put differently, returns true if struct clk *p and struct clk *q
 * share the same struct clk_core object.
 *
 * Returns false otherwise. Note that two NULL clks are treated as matching.
 */
bool clk_is_match(const struct clk *p, const struct clk *q)
{
	/* trivial case: identical struct clk's or both NULL */
	if (p == q)
		return true;

	/* true if clk->core pointers match. Avoid derefing garbage */
	if (!IS_ERR_OR_NULL(p) && !IS_ERR_OR_NULL(q))
		if (p->core == q->core)
			return true;

	return false;
}
EXPORT_SYMBOL_GPL(clk_is_match);

/**
 * __clk_init - initialize the data structures in a struct clk
 * @dev:	device initializing this clk, placeholder for now
+13 −0
Original line number Diff line number Diff line
@@ -48,6 +48,17 @@ static struct clk_pll pll3 = {
	},
};

static struct clk_regmap pll4_vote = {
	.enable_reg = 0x34c0,
	.enable_mask = BIT(4),
	.hw.init = &(struct clk_init_data){
		.name = "pll4_vote",
		.parent_names = (const char *[]){ "pll4" },
		.num_parents = 1,
		.ops = &clk_pll_vote_ops,
	},
};

static struct clk_pll pll8 = {
	.l_reg = 0x3144,
	.m_reg = 0x3148,
@@ -3023,6 +3034,7 @@ static struct clk_branch rpm_msg_ram_h_clk = {

static struct clk_regmap *gcc_msm8960_clks[] = {
	[PLL3] = &pll3.clkr,
	[PLL4_VOTE] = &pll4_vote,
	[PLL8] = &pll8.clkr,
	[PLL8_VOTE] = &pll8_vote,
	[PLL14] = &pll14.clkr,
@@ -3247,6 +3259,7 @@ static const struct qcom_reset_map gcc_msm8960_resets[] = {

static struct clk_regmap *gcc_apq8064_clks[] = {
	[PLL3] = &pll3.clkr,
	[PLL4_VOTE] = &pll4_vote,
	[PLL8] = &pll8.clkr,
	[PLL8_VOTE] = &pll8_vote,
	[PLL14] = &pll14.clkr,
+0 −1
Original line number Diff line number Diff line
@@ -462,7 +462,6 @@ static struct platform_driver lcc_ipq806x_driver = {
	.remove		= lcc_ipq806x_remove,
	.driver		= {
		.name	= "lcc-ipq806x",
		.owner	= THIS_MODULE,
		.of_match_table = lcc_ipq806x_match_table,
	},
};
Loading