Skip to content

Commit 1ee89c5

Browse files
committed
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
2 parents 6981e2a + aaa6d06 commit 1ee89c5

File tree

10 files changed

+83
-29
lines changed

10 files changed

+83
-29
lines changed

arch/arm/mach-imx/mach-imx6q.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,8 +211,9 @@ static void __init imx6q_1588_init(void)
211211
* set bit IOMUXC_GPR1[21]. Or the PTP clock must be from pad
212212
* (external OSC), and we need to clear the bit.
213213
*/
214-
clksel = ptp_clk == enet_ref ? IMX6Q_GPR1_ENET_CLK_SEL_ANATOP :
215-
IMX6Q_GPR1_ENET_CLK_SEL_PAD;
214+
clksel = clk_is_match(ptp_clk, enet_ref) ?
215+
IMX6Q_GPR1_ENET_CLK_SEL_ANATOP :
216+
IMX6Q_GPR1_ENET_CLK_SEL_PAD;
216217
gpr = syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
217218
if (!IS_ERR(gpr))
218219
regmap_update_bits(gpr, IOMUXC_GPR1,

drivers/clk/clk-divider.c

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -144,12 +144,6 @@ static unsigned long clk_divider_recalc_rate(struct clk_hw *hw,
144144
divider->flags);
145145
}
146146

147-
/*
148-
* The reverse of DIV_ROUND_UP: The maximum number which
149-
* divided by m is r
150-
*/
151-
#define MULT_ROUND_UP(r, m) ((r) * (m) + (m) - 1)
152-
153147
static bool _is_valid_table_div(const struct clk_div_table *table,
154148
unsigned int div)
155149
{
@@ -225,19 +219,24 @@ static int _div_round_closest(const struct clk_div_table *table,
225219
unsigned long parent_rate, unsigned long rate,
226220
unsigned long flags)
227221
{
228-
int up, down, div;
222+
int up, down;
223+
unsigned long up_rate, down_rate;
229224

230-
up = down = div = DIV_ROUND_CLOSEST(parent_rate, rate);
225+
up = DIV_ROUND_UP(parent_rate, rate);
226+
down = parent_rate / rate;
231227

232228
if (flags & CLK_DIVIDER_POWER_OF_TWO) {
233-
up = __roundup_pow_of_two(div);
234-
down = __rounddown_pow_of_two(div);
229+
up = __roundup_pow_of_two(up);
230+
down = __rounddown_pow_of_two(down);
235231
} else if (table) {
236-
up = _round_up_table(table, div);
237-
down = _round_down_table(table, div);
232+
up = _round_up_table(table, up);
233+
down = _round_down_table(table, down);
238234
}
239235

240-
return (up - div) <= (div - down) ? up : down;
236+
up_rate = DIV_ROUND_UP(parent_rate, up);
237+
down_rate = DIV_ROUND_UP(parent_rate, down);
238+
239+
return (rate - up_rate) <= (down_rate - rate) ? up : down;
241240
}
242241

243242
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,
313312
return i;
314313
}
315314
parent_rate = __clk_round_rate(__clk_get_parent(hw->clk),
316-
MULT_ROUND_UP(rate, i));
315+
rate * i);
317316
now = DIV_ROUND_UP(parent_rate, i);
318317
if (_is_best_div(rate, now, best, flags)) {
319318
bestdiv = i;
@@ -353,7 +352,7 @@ static long clk_divider_round_rate(struct clk_hw *hw, unsigned long rate,
353352
bestdiv = readl(divider->reg) >> divider->shift;
354353
bestdiv &= div_mask(divider->width);
355354
bestdiv = _get_div(divider->table, bestdiv, divider->flags);
356-
return bestdiv;
355+
return DIV_ROUND_UP(*prate, bestdiv);
357356
}
358357

359358
return divider_round_rate(hw, rate, prate, divider->table,

drivers/clk/clk.c

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1350,7 +1350,6 @@ static unsigned long clk_core_get_rate(struct clk_core *clk)
13501350

13511351
return rate;
13521352
}
1353-
EXPORT_SYMBOL_GPL(clk_core_get_rate);
13541353

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

2172+
/**
2173+
* clk_is_match - check if two clk's point to the same hardware clock
2174+
* @p: clk compared against q
2175+
* @q: clk compared against p
2176+
*
2177+
* Returns true if the two struct clk pointers both point to the same hardware
2178+
* clock node. Put differently, returns true if struct clk *p and struct clk *q
2179+
* share the same struct clk_core object.
2180+
*
2181+
* Returns false otherwise. Note that two NULL clks are treated as matching.
2182+
*/
2183+
bool clk_is_match(const struct clk *p, const struct clk *q)
2184+
{
2185+
/* trivial case: identical struct clk's or both NULL */
2186+
if (p == q)
2187+
return true;
2188+
2189+
/* true if clk->core pointers match. Avoid derefing garbage */
2190+
if (!IS_ERR_OR_NULL(p) && !IS_ERR_OR_NULL(q))
2191+
if (p->core == q->core)
2192+
return true;
2193+
2194+
return false;
2195+
}
2196+
EXPORT_SYMBOL_GPL(clk_is_match);
2197+
21732198
/**
21742199
* __clk_init - initialize the data structures in a struct clk
21752200
* @dev: device initializing this clk, placeholder for now

drivers/clk/qcom/gcc-msm8960.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,17 @@ static struct clk_pll pll3 = {
4848
},
4949
};
5050

51+
static struct clk_regmap pll4_vote = {
52+
.enable_reg = 0x34c0,
53+
.enable_mask = BIT(4),
54+
.hw.init = &(struct clk_init_data){
55+
.name = "pll4_vote",
56+
.parent_names = (const char *[]){ "pll4" },
57+
.num_parents = 1,
58+
.ops = &clk_pll_vote_ops,
59+
},
60+
};
61+
5162
static struct clk_pll pll8 = {
5263
.l_reg = 0x3144,
5364
.m_reg = 0x3148,
@@ -3023,6 +3034,7 @@ static struct clk_branch rpm_msg_ram_h_clk = {
30233034

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

32483260
static struct clk_regmap *gcc_apq8064_clks[] = {
32493261
[PLL3] = &pll3.clkr,
3262+
[PLL4_VOTE] = &pll4_vote,
32503263
[PLL8] = &pll8.clkr,
32513264
[PLL8_VOTE] = &pll8_vote,
32523265
[PLL14] = &pll14.clkr,

drivers/clk/qcom/lcc-ipq806x.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -462,7 +462,6 @@ static struct platform_driver lcc_ipq806x_driver = {
462462
.remove = lcc_ipq806x_remove,
463463
.driver = {
464464
.name = "lcc-ipq806x",
465-
.owner = THIS_MODULE,
466465
.of_match_table = lcc_ipq806x_match_table,
467466
},
468467
};

drivers/clk/qcom/lcc-msm8960.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -417,8 +417,8 @@ static struct clk_rcg slimbus_src = {
417417
.mnctr_en_bit = 8,
418418
.mnctr_reset_bit = 7,
419419
.mnctr_mode_shift = 5,
420-
.n_val_shift = 16,
421-
.m_val_shift = 16,
420+
.n_val_shift = 24,
421+
.m_val_shift = 8,
422422
.width = 8,
423423
},
424424
.p = {
@@ -547,7 +547,7 @@ static int lcc_msm8960_probe(struct platform_device *pdev)
547547
return PTR_ERR(regmap);
548548

549549
/* Use the correct frequency plan depending on speed of PLL4 */
550-
val = regmap_read(regmap, 0x4, &val);
550+
regmap_read(regmap, 0x4, &val);
551551
if (val == 0x12) {
552552
slimbus_src.freq_tbl = clk_tbl_aif_osr_492;
553553
mi2s_osr_src.freq_tbl = clk_tbl_aif_osr_492;
@@ -574,7 +574,6 @@ static struct platform_driver lcc_msm8960_driver = {
574574
.remove = lcc_msm8960_remove,
575575
.driver = {
576576
.name = "lcc-msm8960",
577-
.owner = THIS_MODULE,
578577
.of_match_table = lcc_msm8960_match_table,
579578
},
580579
};

drivers/clk/ti/fapll.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ static int ti_fapll_enable(struct clk_hw *hw)
8484
struct fapll_data *fd = to_fapll(hw);
8585
u32 v = readl_relaxed(fd->base);
8686

87-
v |= (1 << FAPLL_MAIN_PLLEN);
87+
v |= FAPLL_MAIN_PLLEN;
8888
writel_relaxed(v, fd->base);
8989

9090
return 0;
@@ -95,7 +95,7 @@ static void ti_fapll_disable(struct clk_hw *hw)
9595
struct fapll_data *fd = to_fapll(hw);
9696
u32 v = readl_relaxed(fd->base);
9797

98-
v &= ~(1 << FAPLL_MAIN_PLLEN);
98+
v &= ~FAPLL_MAIN_PLLEN;
9999
writel_relaxed(v, fd->base);
100100
}
101101

@@ -104,7 +104,7 @@ static int ti_fapll_is_enabled(struct clk_hw *hw)
104104
struct fapll_data *fd = to_fapll(hw);
105105
u32 v = readl_relaxed(fd->base);
106106

107-
return v & (1 << FAPLL_MAIN_PLLEN);
107+
return v & FAPLL_MAIN_PLLEN;
108108
}
109109

110110
static unsigned long ti_fapll_recalc_rate(struct clk_hw *hw,

include/linux/clk.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,19 @@ int clk_set_phase(struct clk *clk, int degrees);
125125
*/
126126
int clk_get_phase(struct clk *clk);
127127

128+
/**
129+
* clk_is_match - check if two clk's point to the same hardware clock
130+
* @p: clk compared against q
131+
* @q: clk compared against p
132+
*
133+
* Returns true if the two struct clk pointers both point to the same hardware
134+
* clock node. Put differently, returns true if struct clk *p and struct clk *q
135+
* share the same struct clk_core object.
136+
*
137+
* Returns false otherwise. Note that two NULL clks are treated as matching.
138+
*/
139+
bool clk_is_match(const struct clk *p, const struct clk *q);
140+
128141
#else
129142

130143
static inline long clk_get_accuracy(struct clk *clk)
@@ -142,6 +155,11 @@ static inline long clk_get_phase(struct clk *clk)
142155
return -ENOTSUPP;
143156
}
144157

158+
static inline bool clk_is_match(const struct clk *p, const struct clk *q)
159+
{
160+
return p == q;
161+
}
162+
145163
#endif
146164

147165
/**

sound/soc/fsl/fsl_spdif.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1049,7 +1049,7 @@ static u32 fsl_spdif_txclk_caldiv(struct fsl_spdif_priv *spdif_priv,
10491049
enum spdif_txrate index, bool round)
10501050
{
10511051
const u32 rate[] = { 32000, 44100, 48000, 96000, 192000 };
1052-
bool is_sysclk = clk == spdif_priv->sysclk;
1052+
bool is_sysclk = clk_is_match(clk, spdif_priv->sysclk);
10531053
u64 rate_ideal, rate_actual, sub;
10541054
u32 sysclk_dfmin, sysclk_dfmax;
10551055
u32 txclk_df, sysclk_df, arate;
@@ -1143,7 +1143,7 @@ static int fsl_spdif_probe_txclk(struct fsl_spdif_priv *spdif_priv,
11431143
spdif_priv->txclk_src[index], rate[index]);
11441144
dev_dbg(&pdev->dev, "use txclk df %d for %dHz sample rate\n",
11451145
spdif_priv->txclk_df[index], rate[index]);
1146-
if (spdif_priv->txclk[index] == spdif_priv->sysclk)
1146+
if (clk_is_match(spdif_priv->txclk[index], spdif_priv->sysclk))
11471147
dev_dbg(&pdev->dev, "use sysclk df %d for %dHz sample rate\n",
11481148
spdif_priv->sysclk_df[index], rate[index]);
11491149
dev_dbg(&pdev->dev, "the best rate for %dHz sample rate is %dHz\n",

sound/soc/kirkwood/kirkwood-i2s.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -579,7 +579,7 @@ static int kirkwood_i2s_dev_probe(struct platform_device *pdev)
579579
if (PTR_ERR(priv->extclk) == -EPROBE_DEFER)
580580
return -EPROBE_DEFER;
581581
} else {
582-
if (priv->extclk == priv->clk) {
582+
if (clk_is_match(priv->extclk, priv->clk)) {
583583
devm_clk_put(&pdev->dev, priv->extclk);
584584
priv->extclk = ERR_PTR(-EINVAL);
585585
} else {

0 commit comments

Comments
 (0)