History

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

Pull clk fixes from Stephen Boyd: "Two fixes for the NKMP clks on Allwinner SoCs, a locking fix for clkdev where we forgot to hold a lock while iterating a list that can change, and finally a build fix that adds some stubs for clk APIs that are used by devfreq drivers on platforms without the clk APIs" * tag 'clk-fixes-for-linus' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/clk/linux: clk: Add missing stubs for a few functions clkdev: Hold clocks_mutex while iterating clocks list clk: sunxi-ng: nkmp: Explain why zero width check is needed clk: sunxi-ng: nkmp: Avoid GENMASK(-1, 0)

Linus Torvalds committed 7 years ago

Commit 8f762162 parents 46572f7 b88c9f43 files · +40 −5Browse files

Unified · Split

3 files
  1. drivers/clk/clkdev.c +5 −0
  2. drivers/clk/sunxi-ng/ccu_nkmp.c +19 −5
  3. include/linux/clk.h +16 −0
drivers/clk/clkdev.c+5−0
@@ -46,6 +46,8 @@ static struct clk_lookup *clk_find(const char *dev_id, const char *con_id) · 45 unmodified lines
4646 if (con_id)
4747 best_possible += 1;
4848
49+ lockdep_assert_held(&clocks_mutex);
50+
4951 list_for_each_entry(p, &clocks, node) {
5052 match = 0;
5153 if (p->dev_id) {
@@ -402,7 +404,10 @@ void devm_clk_release_clkdev(struct device *dev, const char *con_id, · 350 unmodified lines
402404 struct clk_lookup *cl;
403405 int rval;
404406
407+ mutex_lock(&clocks_mutex);
405408 cl = clk_find(dev_id, con_id);
409+ mutex_unlock(&clocks_mutex);
410+
406411 WARN_ON(!cl);
407412 rval = devres_release(dev, devm_clkdev_release,
408413 devm_clk_match_clkdev, cl);
drivers/clk/sunxi-ng/ccu_nkmp.c+19−5
@@ -167,7 +167,7 @@ static int ccu_nkmp_set_rate(struct clk_hw *hw, unsigned long rate, · 166 unmodified lines
167167 unsigned long parent_rate)
168168 {
169169 struct ccu_nkmp *nkmp = hw_to_ccu_nkmp(hw);
170− u32 n_mask, k_mask, m_mask, p_mask;
170+ u32 n_mask = 0, k_mask = 0, m_mask = 0, p_mask = 0;
171171 struct _ccu_nkmp _nkmp;
172172 unsigned long flags;
173173 u32 reg;
@@ -186,10 +186,24 @@ static int ccu_nkmp_set_rate(struct clk_hw *hw, unsigned long rate, · 12 unmodified lines
186186
187187 ccu_nkmp_find_best(parent_rate, rate, &_nkmp);
188188
189− n_mask = GENMASK(nkmp->n.width + nkmp->n.shift - 1, nkmp->n.shift);
190− k_mask = GENMASK(nkmp->k.width + nkmp->k.shift - 1, nkmp->k.shift);
191− m_mask = GENMASK(nkmp->m.width + nkmp->m.shift - 1, nkmp->m.shift);
192− p_mask = GENMASK(nkmp->p.width + nkmp->p.shift - 1, nkmp->p.shift);
189+ /*
190+ * If width is 0, GENMASK() macro may not generate expected mask (0)
191+ * as it falls under undefined behaviour by C standard due to shifts
192+ * which are equal or greater than width of left operand. This can
193+ * be easily avoided by explicitly checking if width is 0.
194+ */
195+ if (nkmp->n.width)
196+ n_mask = GENMASK(nkmp->n.width + nkmp->n.shift - 1,
197+ nkmp->n.shift);
198+ if (nkmp->k.width)
199+ k_mask = GENMASK(nkmp->k.width + nkmp->k.shift - 1,
200+ nkmp->k.shift);
201+ if (nkmp->m.width)
202+ m_mask = GENMASK(nkmp->m.width + nkmp->m.shift - 1,
203+ nkmp->m.shift);
204+ if (nkmp->p.width)
205+ p_mask = GENMASK(nkmp->p.width + nkmp->p.shift - 1,
206+ nkmp->p.shift);
193207
194208 spin_lock_irqsave(nkmp->common.lock, flags);
195209
include/linux/clk.h+16−0
@@ -811,6 +811,22 @@ static inline bool clk_has_parent(struct clk *clk, struct clk *parent) · 810 unmodified lines
811811 return true;
812812 }
813813
814+static inline int clk_set_rate_range(struct clk *clk, unsigned long min,
815+ unsigned long max)
816+{
817+ return 0;
818+}
819+
820+static inline int clk_set_min_rate(struct clk *clk, unsigned long rate)
821+{
822+ return 0;
823+}
824+
825+static inline int clk_set_max_rate(struct clk *clk, unsigned long rate)
826+{
827+ return 0;
828+}
829+
814830 static inline int clk_set_parent(struct clk *clk, struct clk *parent)
815831 {
816832 return 0;