Blame view

drivers/clk/clk.c 84.9 KB
b2476490e   Mike Turquette   clk: introduce th...
1
2
3
4
5
6
7
8
9
10
  /*
   * Copyright (C) 2010-2011 Canonical Ltd <jeremy.kerr@canonical.com>
   * Copyright (C) 2011-2012 Linaro Ltd <mturquette@linaro.org>
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License version 2 as
   * published by the Free Software Foundation.
   *
   * Standard functionality for the common clock API.  See Documentation/clk.txt
   */
3c3731173   Stephen Boyd   clk: Include clk....
11
  #include <linux/clk.h>
b09d6d991   Michael Turquette   clk: remove clk-p...
12
  #include <linux/clk-provider.h>
86be408bf   Sylwester Nawrocki   clk: Support for ...
13
  #include <linux/clk/clk-conf.h>
b2476490e   Mike Turquette   clk: introduce th...
14
15
16
17
18
19
  #include <linux/module.h>
  #include <linux/mutex.h>
  #include <linux/spinlock.h>
  #include <linux/err.h>
  #include <linux/list.h>
  #include <linux/slab.h>
766e6a4ec   Grant Likely   clk: add DT clock...
20
  #include <linux/of.h>
46c8773a5   Stephen Boyd   clk: Add devm_clk...
21
  #include <linux/device.h>
f2f6c2556   Prashant Gaikwad   clk: add common o...
22
  #include <linux/init.h>
533ddeb1e   Mike Turquette   clk: allow reentr...
23
  #include <linux/sched.h>
562ef0b09   Stephen Boyd   clk: Silence spar...
24
  #include <linux/clkdev.h>
b2476490e   Mike Turquette   clk: introduce th...
25

d6782c263   Sylwester Nawrocki   clk: Provide not ...
26
  #include "clk.h"
b2476490e   Mike Turquette   clk: introduce th...
27
28
  static DEFINE_SPINLOCK(enable_lock);
  static DEFINE_MUTEX(prepare_lock);
533ddeb1e   Mike Turquette   clk: allow reentr...
29
30
31
32
33
  static struct task_struct *prepare_owner;
  static struct task_struct *enable_owner;
  
  static int prepare_refcnt;
  static int enable_refcnt;
b2476490e   Mike Turquette   clk: introduce th...
34
35
36
  static HLIST_HEAD(clk_root_list);
  static HLIST_HEAD(clk_orphan_list);
  static LIST_HEAD(clk_notifier_list);
b09d6d991   Michael Turquette   clk: remove clk-p...
37
38
39
40
41
42
43
44
45
46
47
48
49
  /***    private data structures    ***/
  
  struct clk_core {
  	const char		*name;
  	const struct clk_ops	*ops;
  	struct clk_hw		*hw;
  	struct module		*owner;
  	struct clk_core		*parent;
  	const char		**parent_names;
  	struct clk_core		**parents;
  	u8			num_parents;
  	u8			new_parent_index;
  	unsigned long		rate;
1c8e60044   Tomeu Vizoso   clk: Add rate con...
50
  	unsigned long		req_rate;
b09d6d991   Michael Turquette   clk: remove clk-p...
51
52
53
54
  	unsigned long		new_rate;
  	struct clk_core		*new_parent;
  	struct clk_core		*new_child;
  	unsigned long		flags;
e6500344e   Heiko Stuebner   clk: track the or...
55
  	bool			orphan;
b09d6d991   Michael Turquette   clk: remove clk-p...
56
57
  	unsigned int		enable_count;
  	unsigned int		prepare_count;
9783c0d98   Stephen Boyd   clk: Allow provid...
58
59
  	unsigned long		min_rate;
  	unsigned long		max_rate;
b09d6d991   Michael Turquette   clk: remove clk-p...
60
61
62
63
  	unsigned long		accuracy;
  	int			phase;
  	struct hlist_head	children;
  	struct hlist_node	child_node;
1c8e60044   Tomeu Vizoso   clk: Add rate con...
64
  	struct hlist_head	clks;
b09d6d991   Michael Turquette   clk: remove clk-p...
65
66
67
  	unsigned int		notifier_count;
  #ifdef CONFIG_DEBUG_FS
  	struct dentry		*dentry;
8c9a8a8f7   Maxime Coquelin   clk: Move debug_n...
68
  	struct hlist_node	debug_node;
b09d6d991   Michael Turquette   clk: remove clk-p...
69
70
71
  #endif
  	struct kref		ref;
  };
dfc202ead   Stephen Boyd   clk: Add tracepoi...
72
73
  #define CREATE_TRACE_POINTS
  #include <trace/events/clk.h>
b09d6d991   Michael Turquette   clk: remove clk-p...
74
75
76
77
  struct clk {
  	struct clk_core	*core;
  	const char *dev_id;
  	const char *con_id;
1c8e60044   Tomeu Vizoso   clk: Add rate con...
78
79
  	unsigned long min_rate;
  	unsigned long max_rate;
50595f8b9   Stephen Boyd   clk: Rename child...
80
  	struct hlist_node clks_node;
b09d6d991   Michael Turquette   clk: remove clk-p...
81
  };
eab89f690   Mike Turquette   clk: abstract loc...
82
83
84
  /***           locking             ***/
  static void clk_prepare_lock(void)
  {
533ddeb1e   Mike Turquette   clk: allow reentr...
85
86
87
88
89
90
91
92
93
94
95
  	if (!mutex_trylock(&prepare_lock)) {
  		if (prepare_owner == current) {
  			prepare_refcnt++;
  			return;
  		}
  		mutex_lock(&prepare_lock);
  	}
  	WARN_ON_ONCE(prepare_owner != NULL);
  	WARN_ON_ONCE(prepare_refcnt != 0);
  	prepare_owner = current;
  	prepare_refcnt = 1;
eab89f690   Mike Turquette   clk: abstract loc...
96
97
98
99
  }
  
  static void clk_prepare_unlock(void)
  {
533ddeb1e   Mike Turquette   clk: allow reentr...
100
101
102
103
104
105
  	WARN_ON_ONCE(prepare_owner != current);
  	WARN_ON_ONCE(prepare_refcnt == 0);
  
  	if (--prepare_refcnt)
  		return;
  	prepare_owner = NULL;
eab89f690   Mike Turquette   clk: abstract loc...
106
107
108
109
  	mutex_unlock(&prepare_lock);
  }
  
  static unsigned long clk_enable_lock(void)
a57aa1853   Stephen Boyd   clk: Silence warn...
110
  	__acquires(enable_lock)
eab89f690   Mike Turquette   clk: abstract loc...
111
112
  {
  	unsigned long flags;
533ddeb1e   Mike Turquette   clk: allow reentr...
113
114
115
116
  
  	if (!spin_trylock_irqsave(&enable_lock, flags)) {
  		if (enable_owner == current) {
  			enable_refcnt++;
a57aa1853   Stephen Boyd   clk: Silence warn...
117
  			__acquire(enable_lock);
533ddeb1e   Mike Turquette   clk: allow reentr...
118
119
120
121
122
123
124
125
  			return flags;
  		}
  		spin_lock_irqsave(&enable_lock, flags);
  	}
  	WARN_ON_ONCE(enable_owner != NULL);
  	WARN_ON_ONCE(enable_refcnt != 0);
  	enable_owner = current;
  	enable_refcnt = 1;
eab89f690   Mike Turquette   clk: abstract loc...
126
127
128
129
  	return flags;
  }
  
  static void clk_enable_unlock(unsigned long flags)
a57aa1853   Stephen Boyd   clk: Silence warn...
130
  	__releases(enable_lock)
eab89f690   Mike Turquette   clk: abstract loc...
131
  {
533ddeb1e   Mike Turquette   clk: allow reentr...
132
133
  	WARN_ON_ONCE(enable_owner != current);
  	WARN_ON_ONCE(enable_refcnt == 0);
a57aa1853   Stephen Boyd   clk: Silence warn...
134
135
  	if (--enable_refcnt) {
  		__release(enable_lock);
533ddeb1e   Mike Turquette   clk: allow reentr...
136
  		return;
a57aa1853   Stephen Boyd   clk: Silence warn...
137
  	}
533ddeb1e   Mike Turquette   clk: allow reentr...
138
  	enable_owner = NULL;
eab89f690   Mike Turquette   clk: abstract loc...
139
140
  	spin_unlock_irqrestore(&enable_lock, flags);
  }
4dff95dc9   Stephen Boyd   clk: Remove forwa...
141
142
143
144
145
146
147
148
  static bool clk_core_is_prepared(struct clk_core *core)
  {
  	/*
  	 * .is_prepared is optional for clocks that can prepare
  	 * fall back to software usage counter if it is missing
  	 */
  	if (!core->ops->is_prepared)
  		return core->prepare_count;
b2476490e   Mike Turquette   clk: introduce th...
149

4dff95dc9   Stephen Boyd   clk: Remove forwa...
150
151
  	return core->ops->is_prepared(core->hw);
  }
b2476490e   Mike Turquette   clk: introduce th...
152

4dff95dc9   Stephen Boyd   clk: Remove forwa...
153
154
155
156
157
158
159
160
  static bool clk_core_is_enabled(struct clk_core *core)
  {
  	/*
  	 * .is_enabled is only mandatory for clocks that gate
  	 * fall back to software usage counter if .is_enabled is missing
  	 */
  	if (!core->ops->is_enabled)
  		return core->enable_count;
6b44c854b   Sachin Kamat   clk: Fix build wa...
161

4dff95dc9   Stephen Boyd   clk: Remove forwa...
162
163
  	return core->ops->is_enabled(core->hw);
  }
6b44c854b   Sachin Kamat   clk: Fix build wa...
164

4dff95dc9   Stephen Boyd   clk: Remove forwa...
165
  /***    helper functions   ***/
1af599df6   Prashant Gaikwad   clk: human-readab...
166

b76281cb9   Geert Uytterhoeven   clk: Make clk inp...
167
  const char *__clk_get_name(const struct clk *clk)
1af599df6   Prashant Gaikwad   clk: human-readab...
168
  {
4dff95dc9   Stephen Boyd   clk: Remove forwa...
169
  	return !clk ? NULL : clk->core->name;
1af599df6   Prashant Gaikwad   clk: human-readab...
170
  }
4dff95dc9   Stephen Boyd   clk: Remove forwa...
171
  EXPORT_SYMBOL_GPL(__clk_get_name);
1af599df6   Prashant Gaikwad   clk: human-readab...
172

e7df6f6e2   Stephen Boyd   clk: Constify clk...
173
  const char *clk_hw_get_name(const struct clk_hw *hw)
1a9c069cb   Stephen Boyd   clk: Add clk_hw_*...
174
175
176
177
  {
  	return hw->core->name;
  }
  EXPORT_SYMBOL_GPL(clk_hw_get_name);
4dff95dc9   Stephen Boyd   clk: Remove forwa...
178
179
180
181
182
  struct clk_hw *__clk_get_hw(struct clk *clk)
  {
  	return !clk ? NULL : clk->core->hw;
  }
  EXPORT_SYMBOL_GPL(__clk_get_hw);
1af599df6   Prashant Gaikwad   clk: human-readab...
183

e7df6f6e2   Stephen Boyd   clk: Constify clk...
184
  unsigned int clk_hw_get_num_parents(const struct clk_hw *hw)
1a9c069cb   Stephen Boyd   clk: Add clk_hw_*...
185
186
187
188
  {
  	return hw->core->num_parents;
  }
  EXPORT_SYMBOL_GPL(clk_hw_get_num_parents);
e7df6f6e2   Stephen Boyd   clk: Constify clk...
189
  struct clk_hw *clk_hw_get_parent(const struct clk_hw *hw)
1a9c069cb   Stephen Boyd   clk: Add clk_hw_*...
190
191
192
193
  {
  	return hw->core->parent ? hw->core->parent->hw : NULL;
  }
  EXPORT_SYMBOL_GPL(clk_hw_get_parent);
4dff95dc9   Stephen Boyd   clk: Remove forwa...
194
195
  static struct clk_core *__clk_lookup_subtree(const char *name,
  					     struct clk_core *core)
bddca8944   Prashant Gaikwad   clk: JSON debugfs...
196
  {
035a61c31   Tomeu Vizoso   clk: Make clk API...
197
  	struct clk_core *child;
4dff95dc9   Stephen Boyd   clk: Remove forwa...
198
  	struct clk_core *ret;
bddca8944   Prashant Gaikwad   clk: JSON debugfs...
199

4dff95dc9   Stephen Boyd   clk: Remove forwa...
200
201
  	if (!strcmp(core->name, name))
  		return core;
bddca8944   Prashant Gaikwad   clk: JSON debugfs...
202

4dff95dc9   Stephen Boyd   clk: Remove forwa...
203
204
205
206
  	hlist_for_each_entry(child, &core->children, child_node) {
  		ret = __clk_lookup_subtree(name, child);
  		if (ret)
  			return ret;
bddca8944   Prashant Gaikwad   clk: JSON debugfs...
207
  	}
4dff95dc9   Stephen Boyd   clk: Remove forwa...
208
  	return NULL;
bddca8944   Prashant Gaikwad   clk: JSON debugfs...
209
  }
4dff95dc9   Stephen Boyd   clk: Remove forwa...
210
  static struct clk_core *clk_core_lookup(const char *name)
bddca8944   Prashant Gaikwad   clk: JSON debugfs...
211
  {
4dff95dc9   Stephen Boyd   clk: Remove forwa...
212
213
  	struct clk_core *root_clk;
  	struct clk_core *ret;
bddca8944   Prashant Gaikwad   clk: JSON debugfs...
214

4dff95dc9   Stephen Boyd   clk: Remove forwa...
215
216
  	if (!name)
  		return NULL;
bddca8944   Prashant Gaikwad   clk: JSON debugfs...
217

4dff95dc9   Stephen Boyd   clk: Remove forwa...
218
219
220
221
222
  	/* search the 'proper' clk tree first */
  	hlist_for_each_entry(root_clk, &clk_root_list, child_node) {
  		ret = __clk_lookup_subtree(name, root_clk);
  		if (ret)
  			return ret;
bddca8944   Prashant Gaikwad   clk: JSON debugfs...
223
  	}
4dff95dc9   Stephen Boyd   clk: Remove forwa...
224
225
226
227
228
229
  	/* if not found, then search the orphan tree */
  	hlist_for_each_entry(root_clk, &clk_orphan_list, child_node) {
  		ret = __clk_lookup_subtree(name, root_clk);
  		if (ret)
  			return ret;
  	}
bddca8944   Prashant Gaikwad   clk: JSON debugfs...
230

4dff95dc9   Stephen Boyd   clk: Remove forwa...
231
  	return NULL;
bddca8944   Prashant Gaikwad   clk: JSON debugfs...
232
  }
4dff95dc9   Stephen Boyd   clk: Remove forwa...
233
234
  static struct clk_core *clk_core_get_parent_by_index(struct clk_core *core,
  							 u8 index)
bddca8944   Prashant Gaikwad   clk: JSON debugfs...
235
  {
4dff95dc9   Stephen Boyd   clk: Remove forwa...
236
237
  	if (!core || index >= core->num_parents)
  		return NULL;
88cfbef2a   Masahiro Yamada   clk: simplify clk...
238
239
240
241
242
243
  
  	if (!core->parents[index])
  		core->parents[index] =
  				clk_core_lookup(core->parent_names[index]);
  
  	return core->parents[index];
bddca8944   Prashant Gaikwad   clk: JSON debugfs...
244
  }
e7df6f6e2   Stephen Boyd   clk: Constify clk...
245
246
  struct clk_hw *
  clk_hw_get_parent_by_index(const struct clk_hw *hw, unsigned int index)
1a9c069cb   Stephen Boyd   clk: Add clk_hw_*...
247
248
249
250
251
252
253
254
  {
  	struct clk_core *parent;
  
  	parent = clk_core_get_parent_by_index(hw->core, index);
  
  	return !parent ? NULL : parent->hw;
  }
  EXPORT_SYMBOL_GPL(clk_hw_get_parent_by_index);
4dff95dc9   Stephen Boyd   clk: Remove forwa...
255
256
257
258
  unsigned int __clk_get_enable_count(struct clk *clk)
  {
  	return !clk ? 0 : clk->core->enable_count;
  }
b2476490e   Mike Turquette   clk: introduce th...
259

4dff95dc9   Stephen Boyd   clk: Remove forwa...
260
261
262
  static unsigned long clk_core_get_rate_nolock(struct clk_core *core)
  {
  	unsigned long ret;
b2476490e   Mike Turquette   clk: introduce th...
263

4dff95dc9   Stephen Boyd   clk: Remove forwa...
264
265
266
267
  	if (!core) {
  		ret = 0;
  		goto out;
  	}
b2476490e   Mike Turquette   clk: introduce th...
268

4dff95dc9   Stephen Boyd   clk: Remove forwa...
269
  	ret = core->rate;
b2476490e   Mike Turquette   clk: introduce th...
270

47b0eeb3d   Stephen Boyd   clk: Deprecate CL...
271
  	if (!core->num_parents)
4dff95dc9   Stephen Boyd   clk: Remove forwa...
272
  		goto out;
c646cbf10   Alex Elder   clk: support hard...
273

4dff95dc9   Stephen Boyd   clk: Remove forwa...
274
275
  	if (!core->parent)
  		ret = 0;
b2476490e   Mike Turquette   clk: introduce th...
276

b2476490e   Mike Turquette   clk: introduce th...
277
278
279
  out:
  	return ret;
  }
e7df6f6e2   Stephen Boyd   clk: Constify clk...
280
  unsigned long clk_hw_get_rate(const struct clk_hw *hw)
1a9c069cb   Stephen Boyd   clk: Add clk_hw_*...
281
282
283
284
  {
  	return clk_core_get_rate_nolock(hw->core);
  }
  EXPORT_SYMBOL_GPL(clk_hw_get_rate);
4dff95dc9   Stephen Boyd   clk: Remove forwa...
285
286
287
288
  static unsigned long __clk_get_accuracy(struct clk_core *core)
  {
  	if (!core)
  		return 0;
b2476490e   Mike Turquette   clk: introduce th...
289

4dff95dc9   Stephen Boyd   clk: Remove forwa...
290
  	return core->accuracy;
b2476490e   Mike Turquette   clk: introduce th...
291
  }
4dff95dc9   Stephen Boyd   clk: Remove forwa...
292
  unsigned long __clk_get_flags(struct clk *clk)
fcb0ee6a3   Sylwester Nawrocki   clk: Implement cl...
293
  {
4dff95dc9   Stephen Boyd   clk: Remove forwa...
294
  	return !clk ? 0 : clk->core->flags;
fcb0ee6a3   Sylwester Nawrocki   clk: Implement cl...
295
  }
4dff95dc9   Stephen Boyd   clk: Remove forwa...
296
  EXPORT_SYMBOL_GPL(__clk_get_flags);
fcb0ee6a3   Sylwester Nawrocki   clk: Implement cl...
297

e7df6f6e2   Stephen Boyd   clk: Constify clk...
298
  unsigned long clk_hw_get_flags(const struct clk_hw *hw)
1a9c069cb   Stephen Boyd   clk: Add clk_hw_*...
299
300
301
302
  {
  	return hw->core->flags;
  }
  EXPORT_SYMBOL_GPL(clk_hw_get_flags);
e7df6f6e2   Stephen Boyd   clk: Constify clk...
303
  bool clk_hw_is_prepared(const struct clk_hw *hw)
1a9c069cb   Stephen Boyd   clk: Add clk_hw_*...
304
305
306
  {
  	return clk_core_is_prepared(hw->core);
  }
be68bf883   Joachim Eastwood   clk: Add clk_hw_i...
307
308
309
310
  bool clk_hw_is_enabled(const struct clk_hw *hw)
  {
  	return clk_core_is_enabled(hw->core);
  }
4dff95dc9   Stephen Boyd   clk: Remove forwa...
311
  bool __clk_is_enabled(struct clk *clk)
b2476490e   Mike Turquette   clk: introduce th...
312
  {
4dff95dc9   Stephen Boyd   clk: Remove forwa...
313
314
  	if (!clk)
  		return false;
b2476490e   Mike Turquette   clk: introduce th...
315

4dff95dc9   Stephen Boyd   clk: Remove forwa...
316
317
318
  	return clk_core_is_enabled(clk->core);
  }
  EXPORT_SYMBOL_GPL(__clk_is_enabled);
b2476490e   Mike Turquette   clk: introduce th...
319

4dff95dc9   Stephen Boyd   clk: Remove forwa...
320
321
322
323
324
  static bool mux_is_better_rate(unsigned long rate, unsigned long now,
  			   unsigned long best, unsigned long flags)
  {
  	if (flags & CLK_MUX_ROUND_CLOSEST)
  		return abs(now - rate) < abs(best - rate);
1af599df6   Prashant Gaikwad   clk: human-readab...
325

4dff95dc9   Stephen Boyd   clk: Remove forwa...
326
327
  	return now <= rate && now > best;
  }
bddca8944   Prashant Gaikwad   clk: JSON debugfs...
328

9d33f89c4   Jerome Brunet   clk: honor CLK_MU...
329
330
331
  int clk_mux_determine_rate_flags(struct clk_hw *hw,
  				 struct clk_rate_request *req,
  				 unsigned long flags)
4dff95dc9   Stephen Boyd   clk: Remove forwa...
332
333
  {
  	struct clk_core *core = hw->core, *parent, *best_parent = NULL;
0817b62cc   Boris Brezillon   clk: change clk_o...
334
335
336
  	int i, num_parents, ret;
  	unsigned long best = 0;
  	struct clk_rate_request parent_req = *req;
b2476490e   Mike Turquette   clk: introduce th...
337

4dff95dc9   Stephen Boyd   clk: Remove forwa...
338
339
340
  	/* if NO_REPARENT flag set, pass through to current parent */
  	if (core->flags & CLK_SET_RATE_NO_REPARENT) {
  		parent = core->parent;
0817b62cc   Boris Brezillon   clk: change clk_o...
341
342
343
344
345
346
347
348
  		if (core->flags & CLK_SET_RATE_PARENT) {
  			ret = __clk_determine_rate(parent ? parent->hw : NULL,
  						   &parent_req);
  			if (ret)
  				return ret;
  
  			best = parent_req.rate;
  		} else if (parent) {
4dff95dc9   Stephen Boyd   clk: Remove forwa...
349
  			best = clk_core_get_rate_nolock(parent);
0817b62cc   Boris Brezillon   clk: change clk_o...
350
  		} else {
4dff95dc9   Stephen Boyd   clk: Remove forwa...
351
  			best = clk_core_get_rate_nolock(core);
0817b62cc   Boris Brezillon   clk: change clk_o...
352
  		}
4dff95dc9   Stephen Boyd   clk: Remove forwa...
353
354
  		goto out;
  	}
b2476490e   Mike Turquette   clk: introduce th...
355

4dff95dc9   Stephen Boyd   clk: Remove forwa...
356
357
358
359
360
361
  	/* find the parent that can provide the fastest rate <= rate */
  	num_parents = core->num_parents;
  	for (i = 0; i < num_parents; i++) {
  		parent = clk_core_get_parent_by_index(core, i);
  		if (!parent)
  			continue;
0817b62cc   Boris Brezillon   clk: change clk_o...
362
363
364
365
366
367
368
369
370
371
372
373
  
  		if (core->flags & CLK_SET_RATE_PARENT) {
  			parent_req = *req;
  			ret = __clk_determine_rate(parent->hw, &parent_req);
  			if (ret)
  				continue;
  		} else {
  			parent_req.rate = clk_core_get_rate_nolock(parent);
  		}
  
  		if (mux_is_better_rate(req->rate, parent_req.rate,
  				       best, flags)) {
4dff95dc9   Stephen Boyd   clk: Remove forwa...
374
  			best_parent = parent;
0817b62cc   Boris Brezillon   clk: change clk_o...
375
  			best = parent_req.rate;
4dff95dc9   Stephen Boyd   clk: Remove forwa...
376
377
  		}
  	}
b2476490e   Mike Turquette   clk: introduce th...
378

57d866e60   Boris Brezillon   clk: fix some det...
379
380
  	if (!best_parent)
  		return -EINVAL;
4dff95dc9   Stephen Boyd   clk: Remove forwa...
381
382
  out:
  	if (best_parent)
0817b62cc   Boris Brezillon   clk: change clk_o...
383
384
385
  		req->best_parent_hw = best_parent->hw;
  	req->best_parent_rate = best;
  	req->rate = best;
b2476490e   Mike Turquette   clk: introduce th...
386

0817b62cc   Boris Brezillon   clk: change clk_o...
387
  	return 0;
b33d212f4   Ulf Hansson   clk: Restructure ...
388
  }
9d33f89c4   Jerome Brunet   clk: honor CLK_MU...
389
  EXPORT_SYMBOL_GPL(clk_mux_determine_rate_flags);
4dff95dc9   Stephen Boyd   clk: Remove forwa...
390
391
  
  struct clk *__clk_lookup(const char *name)
fcb0ee6a3   Sylwester Nawrocki   clk: Implement cl...
392
  {
4dff95dc9   Stephen Boyd   clk: Remove forwa...
393
394
395
  	struct clk_core *core = clk_core_lookup(name);
  
  	return !core ? NULL : core->hw->clk;
fcb0ee6a3   Sylwester Nawrocki   clk: Implement cl...
396
  }
b2476490e   Mike Turquette   clk: introduce th...
397

4dff95dc9   Stephen Boyd   clk: Remove forwa...
398
399
400
  static void clk_core_get_boundaries(struct clk_core *core,
  				    unsigned long *min_rate,
  				    unsigned long *max_rate)
1c155b3df   Ulf Hansson   clk: Unprepare th...
401
  {
4dff95dc9   Stephen Boyd   clk: Remove forwa...
402
  	struct clk *clk_user;
1c155b3df   Ulf Hansson   clk: Unprepare th...
403

9783c0d98   Stephen Boyd   clk: Allow provid...
404
405
  	*min_rate = core->min_rate;
  	*max_rate = core->max_rate;
496eadf82   Krzysztof Kozlowski   clk: Use lockdep ...
406

4dff95dc9   Stephen Boyd   clk: Remove forwa...
407
408
  	hlist_for_each_entry(clk_user, &core->clks, clks_node)
  		*min_rate = max(*min_rate, clk_user->min_rate);
1c155b3df   Ulf Hansson   clk: Unprepare th...
409

4dff95dc9   Stephen Boyd   clk: Remove forwa...
410
411
412
  	hlist_for_each_entry(clk_user, &core->clks, clks_node)
  		*max_rate = min(*max_rate, clk_user->max_rate);
  }
1c155b3df   Ulf Hansson   clk: Unprepare th...
413

9783c0d98   Stephen Boyd   clk: Allow provid...
414
415
416
417
418
419
420
  void clk_hw_set_rate_range(struct clk_hw *hw, unsigned long min_rate,
  			   unsigned long max_rate)
  {
  	hw->core->min_rate = min_rate;
  	hw->core->max_rate = max_rate;
  }
  EXPORT_SYMBOL_GPL(clk_hw_set_rate_range);
4dff95dc9   Stephen Boyd   clk: Remove forwa...
421
422
423
424
425
  /*
   * Helper for finding best parent to provide a given frequency. This can be used
   * directly as a determine_rate callback (e.g. for a mux), or from a more
   * complex clock that may combine a mux with other operations.
   */
0817b62cc   Boris Brezillon   clk: change clk_o...
426
427
  int __clk_mux_determine_rate(struct clk_hw *hw,
  			     struct clk_rate_request *req)
4dff95dc9   Stephen Boyd   clk: Remove forwa...
428
  {
0817b62cc   Boris Brezillon   clk: change clk_o...
429
  	return clk_mux_determine_rate_flags(hw, req, 0);
1c155b3df   Ulf Hansson   clk: Unprepare th...
430
  }
4dff95dc9   Stephen Boyd   clk: Remove forwa...
431
  EXPORT_SYMBOL_GPL(__clk_mux_determine_rate);
1c155b3df   Ulf Hansson   clk: Unprepare th...
432

0817b62cc   Boris Brezillon   clk: change clk_o...
433
434
  int __clk_mux_determine_rate_closest(struct clk_hw *hw,
  				     struct clk_rate_request *req)
b2476490e   Mike Turquette   clk: introduce th...
435
  {
0817b62cc   Boris Brezillon   clk: change clk_o...
436
  	return clk_mux_determine_rate_flags(hw, req, CLK_MUX_ROUND_CLOSEST);
4dff95dc9   Stephen Boyd   clk: Remove forwa...
437
438
  }
  EXPORT_SYMBOL_GPL(__clk_mux_determine_rate_closest);
b2476490e   Mike Turquette   clk: introduce th...
439

4dff95dc9   Stephen Boyd   clk: Remove forwa...
440
  /***        clk api        ***/
496eadf82   Krzysztof Kozlowski   clk: Use lockdep ...
441

4dff95dc9   Stephen Boyd   clk: Remove forwa...
442
443
  static void clk_core_unprepare(struct clk_core *core)
  {
a63347251   Stephen Boyd   clk: Add some mor...
444
  	lockdep_assert_held(&prepare_lock);
4dff95dc9   Stephen Boyd   clk: Remove forwa...
445
446
  	if (!core)
  		return;
b2476490e   Mike Turquette   clk: introduce th...
447

4dff95dc9   Stephen Boyd   clk: Remove forwa...
448
449
  	if (WARN_ON(core->prepare_count == 0))
  		return;
b2476490e   Mike Turquette   clk: introduce th...
450

2e20fbf59   Lee Jones   clk: WARN_ON abou...
451
452
  	if (WARN_ON(core->prepare_count == 1 && core->flags & CLK_IS_CRITICAL))
  		return;
4dff95dc9   Stephen Boyd   clk: Remove forwa...
453
454
  	if (--core->prepare_count > 0)
  		return;
b2476490e   Mike Turquette   clk: introduce th...
455

4dff95dc9   Stephen Boyd   clk: Remove forwa...
456
  	WARN_ON(core->enable_count > 0);
b2476490e   Mike Turquette   clk: introduce th...
457

4dff95dc9   Stephen Boyd   clk: Remove forwa...
458
  	trace_clk_unprepare(core);
b2476490e   Mike Turquette   clk: introduce th...
459

4dff95dc9   Stephen Boyd   clk: Remove forwa...
460
461
462
463
464
  	if (core->ops->unprepare)
  		core->ops->unprepare(core->hw);
  
  	trace_clk_unprepare_complete(core);
  	clk_core_unprepare(core->parent);
b2476490e   Mike Turquette   clk: introduce th...
465
  }
a6adc30ba   Dong Aisheng   clk: introduce cl...
466
467
468
469
470
471
  static void clk_core_unprepare_lock(struct clk_core *core)
  {
  	clk_prepare_lock();
  	clk_core_unprepare(core);
  	clk_prepare_unlock();
  }
4dff95dc9   Stephen Boyd   clk: Remove forwa...
472
473
474
475
476
477
478
479
480
481
482
483
  /**
   * clk_unprepare - undo preparation of a clock source
   * @clk: the clk being unprepared
   *
   * clk_unprepare may sleep, which differentiates it from clk_disable.  In a
   * simple case, clk_unprepare can be used instead of clk_disable to gate a clk
   * if the operation may sleep.  One example is a clk which is accessed over
   * I2c.  In the complex case a clk gate operation may require a fast and a slow
   * part.  It is this reason that clk_unprepare and clk_disable are not mutually
   * exclusive.  In fact clk_disable must be called before clk_unprepare.
   */
  void clk_unprepare(struct clk *clk)
1e435256d   Olof Johansson   clk: add clk_igno...
484
  {
4dff95dc9   Stephen Boyd   clk: Remove forwa...
485
486
  	if (IS_ERR_OR_NULL(clk))
  		return;
a6adc30ba   Dong Aisheng   clk: introduce cl...
487
  	clk_core_unprepare_lock(clk->core);
1e435256d   Olof Johansson   clk: add clk_igno...
488
  }
4dff95dc9   Stephen Boyd   clk: Remove forwa...
489
  EXPORT_SYMBOL_GPL(clk_unprepare);
1e435256d   Olof Johansson   clk: add clk_igno...
490

4dff95dc9   Stephen Boyd   clk: Remove forwa...
491
  static int clk_core_prepare(struct clk_core *core)
b2476490e   Mike Turquette   clk: introduce th...
492
  {
4dff95dc9   Stephen Boyd   clk: Remove forwa...
493
  	int ret = 0;
b2476490e   Mike Turquette   clk: introduce th...
494

a63347251   Stephen Boyd   clk: Add some mor...
495
  	lockdep_assert_held(&prepare_lock);
4dff95dc9   Stephen Boyd   clk: Remove forwa...
496
  	if (!core)
1e435256d   Olof Johansson   clk: add clk_igno...
497
  		return 0;
1e435256d   Olof Johansson   clk: add clk_igno...
498

4dff95dc9   Stephen Boyd   clk: Remove forwa...
499
500
501
502
  	if (core->prepare_count == 0) {
  		ret = clk_core_prepare(core->parent);
  		if (ret)
  			return ret;
b2476490e   Mike Turquette   clk: introduce th...
503

4dff95dc9   Stephen Boyd   clk: Remove forwa...
504
  		trace_clk_prepare(core);
b2476490e   Mike Turquette   clk: introduce th...
505

4dff95dc9   Stephen Boyd   clk: Remove forwa...
506
507
  		if (core->ops->prepare)
  			ret = core->ops->prepare(core->hw);
b2476490e   Mike Turquette   clk: introduce th...
508

4dff95dc9   Stephen Boyd   clk: Remove forwa...
509
  		trace_clk_prepare_complete(core);
1c155b3df   Ulf Hansson   clk: Unprepare th...
510

4dff95dc9   Stephen Boyd   clk: Remove forwa...
511
512
513
514
515
  		if (ret) {
  			clk_core_unprepare(core->parent);
  			return ret;
  		}
  	}
1c155b3df   Ulf Hansson   clk: Unprepare th...
516

4dff95dc9   Stephen Boyd   clk: Remove forwa...
517
  	core->prepare_count++;
b2476490e   Mike Turquette   clk: introduce th...
518
519
520
  
  	return 0;
  }
b2476490e   Mike Turquette   clk: introduce th...
521

a6adc30ba   Dong Aisheng   clk: introduce cl...
522
523
524
525
526
527
528
529
530
531
  static int clk_core_prepare_lock(struct clk_core *core)
  {
  	int ret;
  
  	clk_prepare_lock();
  	ret = clk_core_prepare(core);
  	clk_prepare_unlock();
  
  	return ret;
  }
4dff95dc9   Stephen Boyd   clk: Remove forwa...
532
533
534
535
536
537
538
539
540
541
542
543
544
  /**
   * clk_prepare - prepare a clock source
   * @clk: the clk being prepared
   *
   * clk_prepare may sleep, which differentiates it from clk_enable.  In a simple
   * case, clk_prepare can be used instead of clk_enable to ungate a clk if the
   * operation may sleep.  One example is a clk which is accessed over I2c.  In
   * the complex case a clk ungate operation may require a fast and a slow part.
   * It is this reason that clk_prepare and clk_enable are not mutually
   * exclusive.  In fact clk_prepare must be called before clk_enable.
   * Returns 0 on success, -EERROR otherwise.
   */
  int clk_prepare(struct clk *clk)
b2476490e   Mike Turquette   clk: introduce th...
545
  {
4dff95dc9   Stephen Boyd   clk: Remove forwa...
546
547
  	if (!clk)
  		return 0;
b2476490e   Mike Turquette   clk: introduce th...
548

a6adc30ba   Dong Aisheng   clk: introduce cl...
549
  	return clk_core_prepare_lock(clk->core);
b2476490e   Mike Turquette   clk: introduce th...
550
  }
4dff95dc9   Stephen Boyd   clk: Remove forwa...
551
  EXPORT_SYMBOL_GPL(clk_prepare);
b2476490e   Mike Turquette   clk: introduce th...
552

4dff95dc9   Stephen Boyd   clk: Remove forwa...
553
  static void clk_core_disable(struct clk_core *core)
b2476490e   Mike Turquette   clk: introduce th...
554
  {
a63347251   Stephen Boyd   clk: Add some mor...
555
  	lockdep_assert_held(&enable_lock);
4dff95dc9   Stephen Boyd   clk: Remove forwa...
556
557
  	if (!core)
  		return;
035a61c31   Tomeu Vizoso   clk: Make clk API...
558

4dff95dc9   Stephen Boyd   clk: Remove forwa...
559
560
  	if (WARN_ON(core->enable_count == 0))
  		return;
b2476490e   Mike Turquette   clk: introduce th...
561

2e20fbf59   Lee Jones   clk: WARN_ON abou...
562
563
  	if (WARN_ON(core->enable_count == 1 && core->flags & CLK_IS_CRITICAL))
  		return;
4dff95dc9   Stephen Boyd   clk: Remove forwa...
564
565
  	if (--core->enable_count > 0)
  		return;
035a61c31   Tomeu Vizoso   clk: Make clk API...
566

2f87a6ea1   Paul E. McKenney   clk: Add _rcuidle...
567
  	trace_clk_disable_rcuidle(core);
035a61c31   Tomeu Vizoso   clk: Make clk API...
568

4dff95dc9   Stephen Boyd   clk: Remove forwa...
569
570
  	if (core->ops->disable)
  		core->ops->disable(core->hw);
035a61c31   Tomeu Vizoso   clk: Make clk API...
571

2f87a6ea1   Paul E. McKenney   clk: Add _rcuidle...
572
  	trace_clk_disable_complete_rcuidle(core);
035a61c31   Tomeu Vizoso   clk: Make clk API...
573

4dff95dc9   Stephen Boyd   clk: Remove forwa...
574
  	clk_core_disable(core->parent);
035a61c31   Tomeu Vizoso   clk: Make clk API...
575
  }
7ef3dcc81   James Hogan   clk: abstract par...
576

a6adc30ba   Dong Aisheng   clk: introduce cl...
577
578
579
580
581
582
583
584
  static void clk_core_disable_lock(struct clk_core *core)
  {
  	unsigned long flags;
  
  	flags = clk_enable_lock();
  	clk_core_disable(core);
  	clk_enable_unlock(flags);
  }
4dff95dc9   Stephen Boyd   clk: Remove forwa...
585
586
587
588
589
590
591
592
593
594
595
596
597
  /**
   * clk_disable - gate a clock
   * @clk: the clk being gated
   *
   * clk_disable must not sleep, which differentiates it from clk_unprepare.  In
   * a simple case, clk_disable can be used instead of clk_unprepare to gate a
   * clk if the operation is fast and will never sleep.  One example is a
   * SoC-internal clk which is controlled via simple register writes.  In the
   * complex case a clk gate operation may require a fast and a slow part.  It is
   * this reason that clk_unprepare and clk_disable are not mutually exclusive.
   * In fact clk_disable must be called before clk_unprepare.
   */
  void clk_disable(struct clk *clk)
b2476490e   Mike Turquette   clk: introduce th...
598
  {
4dff95dc9   Stephen Boyd   clk: Remove forwa...
599
600
  	if (IS_ERR_OR_NULL(clk))
  		return;
a6adc30ba   Dong Aisheng   clk: introduce cl...
601
  	clk_core_disable_lock(clk->core);
b2476490e   Mike Turquette   clk: introduce th...
602
  }
4dff95dc9   Stephen Boyd   clk: Remove forwa...
603
  EXPORT_SYMBOL_GPL(clk_disable);
b2476490e   Mike Turquette   clk: introduce th...
604

4dff95dc9   Stephen Boyd   clk: Remove forwa...
605
  static int clk_core_enable(struct clk_core *core)
b2476490e   Mike Turquette   clk: introduce th...
606
  {
4dff95dc9   Stephen Boyd   clk: Remove forwa...
607
  	int ret = 0;
b2476490e   Mike Turquette   clk: introduce th...
608

a63347251   Stephen Boyd   clk: Add some mor...
609
  	lockdep_assert_held(&enable_lock);
4dff95dc9   Stephen Boyd   clk: Remove forwa...
610
611
  	if (!core)
  		return 0;
b2476490e   Mike Turquette   clk: introduce th...
612

4dff95dc9   Stephen Boyd   clk: Remove forwa...
613
614
  	if (WARN_ON(core->prepare_count == 0))
  		return -ESHUTDOWN;
b2476490e   Mike Turquette   clk: introduce th...
615

4dff95dc9   Stephen Boyd   clk: Remove forwa...
616
617
  	if (core->enable_count == 0) {
  		ret = clk_core_enable(core->parent);
b2476490e   Mike Turquette   clk: introduce th...
618

4dff95dc9   Stephen Boyd   clk: Remove forwa...
619
620
  		if (ret)
  			return ret;
b2476490e   Mike Turquette   clk: introduce th...
621

f17a0dd1c   Paul E. McKenney   clk: Use _rcuidle...
622
  		trace_clk_enable_rcuidle(core);
035a61c31   Tomeu Vizoso   clk: Make clk API...
623

4dff95dc9   Stephen Boyd   clk: Remove forwa...
624
625
  		if (core->ops->enable)
  			ret = core->ops->enable(core->hw);
035a61c31   Tomeu Vizoso   clk: Make clk API...
626

f17a0dd1c   Paul E. McKenney   clk: Use _rcuidle...
627
  		trace_clk_enable_complete_rcuidle(core);
4dff95dc9   Stephen Boyd   clk: Remove forwa...
628
629
630
631
632
633
634
635
636
  
  		if (ret) {
  			clk_core_disable(core->parent);
  			return ret;
  		}
  	}
  
  	core->enable_count++;
  	return 0;
035a61c31   Tomeu Vizoso   clk: Make clk API...
637
  }
b2476490e   Mike Turquette   clk: introduce th...
638

a6adc30ba   Dong Aisheng   clk: introduce cl...
639
640
641
642
643
644
645
646
647
648
649
  static int clk_core_enable_lock(struct clk_core *core)
  {
  	unsigned long flags;
  	int ret;
  
  	flags = clk_enable_lock();
  	ret = clk_core_enable(core);
  	clk_enable_unlock(flags);
  
  	return ret;
  }
4dff95dc9   Stephen Boyd   clk: Remove forwa...
650
651
652
653
654
655
656
657
658
659
660
661
662
663
  /**
   * clk_enable - ungate a clock
   * @clk: the clk being ungated
   *
   * clk_enable must not sleep, which differentiates it from clk_prepare.  In a
   * simple case, clk_enable can be used instead of clk_prepare to ungate a clk
   * if the operation will never sleep.  One example is a SoC-internal clk which
   * is controlled via simple register writes.  In the complex case a clk ungate
   * operation may require a fast and a slow part.  It is this reason that
   * clk_enable and clk_prepare are not mutually exclusive.  In fact clk_prepare
   * must be called before clk_enable.  Returns 0 on success, -EERROR
   * otherwise.
   */
  int clk_enable(struct clk *clk)
5279fc402   Boris BREZILLON   clk: add clk accu...
664
  {
4dff95dc9   Stephen Boyd   clk: Remove forwa...
665
  	if (!clk)
5279fc402   Boris BREZILLON   clk: add clk accu...
666
  		return 0;
a6adc30ba   Dong Aisheng   clk: introduce cl...
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
  	return clk_core_enable_lock(clk->core);
  }
  EXPORT_SYMBOL_GPL(clk_enable);
  
  static int clk_core_prepare_enable(struct clk_core *core)
  {
  	int ret;
  
  	ret = clk_core_prepare_lock(core);
  	if (ret)
  		return ret;
  
  	ret = clk_core_enable_lock(core);
  	if (ret)
  		clk_core_unprepare_lock(core);
5279fc402   Boris BREZILLON   clk: add clk accu...
682

4dff95dc9   Stephen Boyd   clk: Remove forwa...
683
  	return ret;
b2476490e   Mike Turquette   clk: introduce th...
684
  }
a6adc30ba   Dong Aisheng   clk: introduce cl...
685
686
687
688
689
690
  
  static void clk_core_disable_unprepare(struct clk_core *core)
  {
  	clk_core_disable_lock(core);
  	clk_core_unprepare_lock(core);
  }
b2476490e   Mike Turquette   clk: introduce th...
691

7ec986efe   Dong Aisheng   clk: move clk_dis...
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
  static void clk_unprepare_unused_subtree(struct clk_core *core)
  {
  	struct clk_core *child;
  
  	lockdep_assert_held(&prepare_lock);
  
  	hlist_for_each_entry(child, &core->children, child_node)
  		clk_unprepare_unused_subtree(child);
  
  	if (core->prepare_count)
  		return;
  
  	if (core->flags & CLK_IGNORE_UNUSED)
  		return;
  
  	if (clk_core_is_prepared(core)) {
  		trace_clk_unprepare(core);
  		if (core->ops->unprepare_unused)
  			core->ops->unprepare_unused(core->hw);
  		else if (core->ops->unprepare)
  			core->ops->unprepare(core->hw);
  		trace_clk_unprepare_complete(core);
  	}
  }
  
  static void clk_disable_unused_subtree(struct clk_core *core)
  {
  	struct clk_core *child;
  	unsigned long flags;
  
  	lockdep_assert_held(&prepare_lock);
  
  	hlist_for_each_entry(child, &core->children, child_node)
  		clk_disable_unused_subtree(child);
a4b3518d1   Dong Aisheng   clk: core: suppor...
726
727
  	if (core->flags & CLK_OPS_PARENT_ENABLE)
  		clk_core_prepare_enable(core->parent);
7ec986efe   Dong Aisheng   clk: move clk_dis...
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
  	flags = clk_enable_lock();
  
  	if (core->enable_count)
  		goto unlock_out;
  
  	if (core->flags & CLK_IGNORE_UNUSED)
  		goto unlock_out;
  
  	/*
  	 * some gate clocks have special needs during the disable-unused
  	 * sequence.  call .disable_unused if available, otherwise fall
  	 * back to .disable
  	 */
  	if (clk_core_is_enabled(core)) {
  		trace_clk_disable(core);
  		if (core->ops->disable_unused)
  			core->ops->disable_unused(core->hw);
  		else if (core->ops->disable)
  			core->ops->disable(core->hw);
  		trace_clk_disable_complete(core);
  	}
  
  unlock_out:
  	clk_enable_unlock(flags);
a4b3518d1   Dong Aisheng   clk: core: suppor...
752
753
  	if (core->flags & CLK_OPS_PARENT_ENABLE)
  		clk_core_disable_unprepare(core->parent);
7ec986efe   Dong Aisheng   clk: move clk_dis...
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
  }
  
  static bool clk_ignore_unused;
  static int __init clk_ignore_unused_setup(char *__unused)
  {
  	clk_ignore_unused = true;
  	return 1;
  }
  __setup("clk_ignore_unused", clk_ignore_unused_setup);
  
  static int clk_disable_unused(void)
  {
  	struct clk_core *core;
  
  	if (clk_ignore_unused) {
  		pr_warn("clk: Not disabling unused clocks
  ");
  		return 0;
  	}
  
  	clk_prepare_lock();
  
  	hlist_for_each_entry(core, &clk_root_list, child_node)
  		clk_disable_unused_subtree(core);
  
  	hlist_for_each_entry(core, &clk_orphan_list, child_node)
  		clk_disable_unused_subtree(core);
  
  	hlist_for_each_entry(core, &clk_root_list, child_node)
  		clk_unprepare_unused_subtree(core);
  
  	hlist_for_each_entry(core, &clk_orphan_list, child_node)
  		clk_unprepare_unused_subtree(core);
  
  	clk_prepare_unlock();
  
  	return 0;
  }
  late_initcall_sync(clk_disable_unused);
0817b62cc   Boris Brezillon   clk: change clk_o...
793
794
  static int clk_core_round_rate_nolock(struct clk_core *core,
  				      struct clk_rate_request *req)
3d6ee287a   Ulf Hansson   clk: Introduce op...
795
  {
4dff95dc9   Stephen Boyd   clk: Remove forwa...
796
  	struct clk_core *parent;
0817b62cc   Boris Brezillon   clk: change clk_o...
797
  	long rate;
4dff95dc9   Stephen Boyd   clk: Remove forwa...
798
799
  
  	lockdep_assert_held(&prepare_lock);
3d6ee287a   Ulf Hansson   clk: Introduce op...
800

d6968fca7   Stephen Boyd   clk: s/clk/core/ ...
801
  	if (!core)
4dff95dc9   Stephen Boyd   clk: Remove forwa...
802
  		return 0;
3d6ee287a   Ulf Hansson   clk: Introduce op...
803

4dff95dc9   Stephen Boyd   clk: Remove forwa...
804
  	parent = core->parent;
0817b62cc   Boris Brezillon   clk: change clk_o...
805
806
807
808
809
810
811
  	if (parent) {
  		req->best_parent_hw = parent->hw;
  		req->best_parent_rate = parent->rate;
  	} else {
  		req->best_parent_hw = NULL;
  		req->best_parent_rate = 0;
  	}
3d6ee287a   Ulf Hansson   clk: Introduce op...
812

4dff95dc9   Stephen Boyd   clk: Remove forwa...
813
  	if (core->ops->determine_rate) {
0817b62cc   Boris Brezillon   clk: change clk_o...
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
  		return core->ops->determine_rate(core->hw, req);
  	} else if (core->ops->round_rate) {
  		rate = core->ops->round_rate(core->hw, req->rate,
  					     &req->best_parent_rate);
  		if (rate < 0)
  			return rate;
  
  		req->rate = rate;
  	} else if (core->flags & CLK_SET_RATE_PARENT) {
  		return clk_core_round_rate_nolock(parent, req);
  	} else {
  		req->rate = core->rate;
  	}
  
  	return 0;
3d6ee287a   Ulf Hansson   clk: Introduce op...
829
  }
4dff95dc9   Stephen Boyd   clk: Remove forwa...
830
831
832
  /**
   * __clk_determine_rate - get the closest rate actually supported by a clock
   * @hw: determine the rate of this clock
2d5b520cf   Peng Fan   clk: correct comm...
833
   * @req: target rate request
4dff95dc9   Stephen Boyd   clk: Remove forwa...
834
   *
6e5ab41b1   Stephen Boyd   clk: Update some ...
835
   * Useful for clk_ops such as .set_rate and .determine_rate.
4dff95dc9   Stephen Boyd   clk: Remove forwa...
836
   */
0817b62cc   Boris Brezillon   clk: change clk_o...
837
  int __clk_determine_rate(struct clk_hw *hw, struct clk_rate_request *req)
035a61c31   Tomeu Vizoso   clk: Make clk API...
838
  {
0817b62cc   Boris Brezillon   clk: change clk_o...
839
840
  	if (!hw) {
  		req->rate = 0;
4dff95dc9   Stephen Boyd   clk: Remove forwa...
841
  		return 0;
0817b62cc   Boris Brezillon   clk: change clk_o...
842
  	}
035a61c31   Tomeu Vizoso   clk: Make clk API...
843

0817b62cc   Boris Brezillon   clk: change clk_o...
844
  	return clk_core_round_rate_nolock(hw->core, req);
035a61c31   Tomeu Vizoso   clk: Make clk API...
845
  }
4dff95dc9   Stephen Boyd   clk: Remove forwa...
846
  EXPORT_SYMBOL_GPL(__clk_determine_rate);
035a61c31   Tomeu Vizoso   clk: Make clk API...
847

1a9c069cb   Stephen Boyd   clk: Add clk_hw_*...
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
  unsigned long clk_hw_round_rate(struct clk_hw *hw, unsigned long rate)
  {
  	int ret;
  	struct clk_rate_request req;
  
  	clk_core_get_boundaries(hw->core, &req.min_rate, &req.max_rate);
  	req.rate = rate;
  
  	ret = clk_core_round_rate_nolock(hw->core, &req);
  	if (ret)
  		return 0;
  
  	return req.rate;
  }
  EXPORT_SYMBOL_GPL(clk_hw_round_rate);
4dff95dc9   Stephen Boyd   clk: Remove forwa...
863
864
865
866
867
868
869
870
871
872
  /**
   * clk_round_rate - round the given rate for a clk
   * @clk: the clk for which we are rounding a rate
   * @rate: the rate which is to be rounded
   *
   * Takes in a rate as input and rounds it to a rate that the clk can actually
   * use which is then returned.  If clk doesn't support round_rate operation
   * then the parent rate is returned.
   */
  long clk_round_rate(struct clk *clk, unsigned long rate)
035a61c31   Tomeu Vizoso   clk: Make clk API...
873
  {
fc4a05d4b   Stephen Boyd   clk: Remove unuse...
874
875
  	struct clk_rate_request req;
  	int ret;
4dff95dc9   Stephen Boyd   clk: Remove forwa...
876

035a61c31   Tomeu Vizoso   clk: Make clk API...
877
  	if (!clk)
4dff95dc9   Stephen Boyd   clk: Remove forwa...
878
  		return 0;
035a61c31   Tomeu Vizoso   clk: Make clk API...
879

4dff95dc9   Stephen Boyd   clk: Remove forwa...
880
  	clk_prepare_lock();
fc4a05d4b   Stephen Boyd   clk: Remove unuse...
881
882
883
884
885
  
  	clk_core_get_boundaries(clk->core, &req.min_rate, &req.max_rate);
  	req.rate = rate;
  
  	ret = clk_core_round_rate_nolock(clk->core, &req);
4dff95dc9   Stephen Boyd   clk: Remove forwa...
886
  	clk_prepare_unlock();
fc4a05d4b   Stephen Boyd   clk: Remove unuse...
887
888
889
890
  	if (ret)
  		return ret;
  
  	return req.rate;
035a61c31   Tomeu Vizoso   clk: Make clk API...
891
  }
4dff95dc9   Stephen Boyd   clk: Remove forwa...
892
  EXPORT_SYMBOL_GPL(clk_round_rate);
b2476490e   Mike Turquette   clk: introduce th...
893

4dff95dc9   Stephen Boyd   clk: Remove forwa...
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
  /**
   * __clk_notify - call clk notifier chain
   * @core: clk that is changing rate
   * @msg: clk notifier type (see include/linux/clk.h)
   * @old_rate: old clk rate
   * @new_rate: new clk rate
   *
   * Triggers a notifier call chain on the clk rate-change notification
   * for 'clk'.  Passes a pointer to the struct clk and the previous
   * and current rates to the notifier callback.  Intended to be called by
   * internal clock code only.  Returns NOTIFY_DONE from the last driver
   * called if all went well, or NOTIFY_STOP or NOTIFY_BAD immediately if
   * a driver returns that.
   */
  static int __clk_notify(struct clk_core *core, unsigned long msg,
  		unsigned long old_rate, unsigned long new_rate)
b2476490e   Mike Turquette   clk: introduce th...
910
  {
4dff95dc9   Stephen Boyd   clk: Remove forwa...
911
912
913
  	struct clk_notifier *cn;
  	struct clk_notifier_data cnd;
  	int ret = NOTIFY_DONE;
b2476490e   Mike Turquette   clk: introduce th...
914

4dff95dc9   Stephen Boyd   clk: Remove forwa...
915
916
  	cnd.old_rate = old_rate;
  	cnd.new_rate = new_rate;
b2476490e   Mike Turquette   clk: introduce th...
917

4dff95dc9   Stephen Boyd   clk: Remove forwa...
918
919
920
921
922
  	list_for_each_entry(cn, &clk_notifier_list, node) {
  		if (cn->clk->core == core) {
  			cnd.clk = cn->clk;
  			ret = srcu_notifier_call_chain(&cn->notifier_head, msg,
  					&cnd);
17c34c566   Peter De Schrijver   clk: aggregate re...
923
924
  			if (ret & NOTIFY_STOP_MASK)
  				return ret;
4dff95dc9   Stephen Boyd   clk: Remove forwa...
925
  		}
b2476490e   Mike Turquette   clk: introduce th...
926
  	}
4dff95dc9   Stephen Boyd   clk: Remove forwa...
927
  	return ret;
b2476490e   Mike Turquette   clk: introduce th...
928
  }
4dff95dc9   Stephen Boyd   clk: Remove forwa...
929
930
931
932
933
934
  /**
   * __clk_recalc_accuracies
   * @core: first clk in the subtree
   *
   * Walks the subtree of clks starting with clk and recalculates accuracies as
   * it goes.  Note that if a clk does not implement the .recalc_accuracy
6e5ab41b1   Stephen Boyd   clk: Update some ...
935
   * callback then it is assumed that the clock will take on the accuracy of its
4dff95dc9   Stephen Boyd   clk: Remove forwa...
936
   * parent.
4dff95dc9   Stephen Boyd   clk: Remove forwa...
937
938
   */
  static void __clk_recalc_accuracies(struct clk_core *core)
b2476490e   Mike Turquette   clk: introduce th...
939
  {
4dff95dc9   Stephen Boyd   clk: Remove forwa...
940
941
  	unsigned long parent_accuracy = 0;
  	struct clk_core *child;
b2476490e   Mike Turquette   clk: introduce th...
942

4dff95dc9   Stephen Boyd   clk: Remove forwa...
943
  	lockdep_assert_held(&prepare_lock);
b2476490e   Mike Turquette   clk: introduce th...
944

4dff95dc9   Stephen Boyd   clk: Remove forwa...
945
946
  	if (core->parent)
  		parent_accuracy = core->parent->accuracy;
b2476490e   Mike Turquette   clk: introduce th...
947

4dff95dc9   Stephen Boyd   clk: Remove forwa...
948
949
950
951
952
  	if (core->ops->recalc_accuracy)
  		core->accuracy = core->ops->recalc_accuracy(core->hw,
  							  parent_accuracy);
  	else
  		core->accuracy = parent_accuracy;
b2476490e   Mike Turquette   clk: introduce th...
953

4dff95dc9   Stephen Boyd   clk: Remove forwa...
954
955
  	hlist_for_each_entry(child, &core->children, child_node)
  		__clk_recalc_accuracies(child);
b2476490e   Mike Turquette   clk: introduce th...
956
  }
4dff95dc9   Stephen Boyd   clk: Remove forwa...
957
  static long clk_core_get_accuracy(struct clk_core *core)
e366fdd72   James Hogan   clk: clk-mux: imp...
958
  {
4dff95dc9   Stephen Boyd   clk: Remove forwa...
959
  	unsigned long accuracy;
15a02c1f6   Stephen Boyd   clk: Add __clk_mu...
960

4dff95dc9   Stephen Boyd   clk: Remove forwa...
961
962
963
  	clk_prepare_lock();
  	if (core && (core->flags & CLK_GET_ACCURACY_NOCACHE))
  		__clk_recalc_accuracies(core);
15a02c1f6   Stephen Boyd   clk: Add __clk_mu...
964

4dff95dc9   Stephen Boyd   clk: Remove forwa...
965
966
  	accuracy = __clk_get_accuracy(core);
  	clk_prepare_unlock();
e366fdd72   James Hogan   clk: clk-mux: imp...
967

4dff95dc9   Stephen Boyd   clk: Remove forwa...
968
  	return accuracy;
e366fdd72   James Hogan   clk: clk-mux: imp...
969
  }
15a02c1f6   Stephen Boyd   clk: Add __clk_mu...
970

4dff95dc9   Stephen Boyd   clk: Remove forwa...
971
972
973
974
975
976
977
978
979
980
  /**
   * clk_get_accuracy - return the accuracy of clk
   * @clk: the clk whose accuracy is being returned
   *
   * Simply returns the cached accuracy of the clk, unless
   * CLK_GET_ACCURACY_NOCACHE flag is set, which means a recalc_rate will be
   * issued.
   * If clk is NULL then returns 0.
   */
  long clk_get_accuracy(struct clk *clk)
035a61c31   Tomeu Vizoso   clk: Make clk API...
981
  {
4dff95dc9   Stephen Boyd   clk: Remove forwa...
982
983
  	if (!clk)
  		return 0;
035a61c31   Tomeu Vizoso   clk: Make clk API...
984

4dff95dc9   Stephen Boyd   clk: Remove forwa...
985
  	return clk_core_get_accuracy(clk->core);
035a61c31   Tomeu Vizoso   clk: Make clk API...
986
  }
4dff95dc9   Stephen Boyd   clk: Remove forwa...
987
  EXPORT_SYMBOL_GPL(clk_get_accuracy);
035a61c31   Tomeu Vizoso   clk: Make clk API...
988

4dff95dc9   Stephen Boyd   clk: Remove forwa...
989
990
  static unsigned long clk_recalc(struct clk_core *core,
  				unsigned long parent_rate)
1c8e60044   Tomeu Vizoso   clk: Add rate con...
991
  {
4dff95dc9   Stephen Boyd   clk: Remove forwa...
992
993
994
  	if (core->ops->recalc_rate)
  		return core->ops->recalc_rate(core->hw, parent_rate);
  	return parent_rate;
1c8e60044   Tomeu Vizoso   clk: Add rate con...
995
  }
4dff95dc9   Stephen Boyd   clk: Remove forwa...
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
  /**
   * __clk_recalc_rates
   * @core: first clk in the subtree
   * @msg: notification type (see include/linux/clk.h)
   *
   * Walks the subtree of clks starting with clk and recalculates rates as it
   * goes.  Note that if a clk does not implement the .recalc_rate callback then
   * it is assumed that the clock will take on the rate of its parent.
   *
   * clk_recalc_rates also propagates the POST_RATE_CHANGE notification,
   * if necessary.
15a02c1f6   Stephen Boyd   clk: Add __clk_mu...
1007
   */
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1008
  static void __clk_recalc_rates(struct clk_core *core, unsigned long msg)
15a02c1f6   Stephen Boyd   clk: Add __clk_mu...
1009
  {
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1010
1011
1012
  	unsigned long old_rate;
  	unsigned long parent_rate = 0;
  	struct clk_core *child;
e366fdd72   James Hogan   clk: clk-mux: imp...
1013

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1014
  	lockdep_assert_held(&prepare_lock);
15a02c1f6   Stephen Boyd   clk: Add __clk_mu...
1015

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1016
  	old_rate = core->rate;
b2476490e   Mike Turquette   clk: introduce th...
1017

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1018
1019
  	if (core->parent)
  		parent_rate = core->parent->rate;
b2476490e   Mike Turquette   clk: introduce th...
1020

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1021
  	core->rate = clk_recalc(core, parent_rate);
b2476490e   Mike Turquette   clk: introduce th...
1022

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1023
1024
1025
1026
1027
1028
  	/*
  	 * ignore NOTIFY_STOP and NOTIFY_BAD return values for POST_RATE_CHANGE
  	 * & ABORT_RATE_CHANGE notifiers
  	 */
  	if (core->notifier_count && msg)
  		__clk_notify(core, msg, old_rate, core->rate);
b2476490e   Mike Turquette   clk: introduce th...
1029

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1030
1031
1032
  	hlist_for_each_entry(child, &core->children, child_node)
  		__clk_recalc_rates(child, msg);
  }
b2476490e   Mike Turquette   clk: introduce th...
1033

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1034
1035
1036
  static unsigned long clk_core_get_rate(struct clk_core *core)
  {
  	unsigned long rate;
dfc202ead   Stephen Boyd   clk: Add tracepoi...
1037

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1038
  	clk_prepare_lock();
b2476490e   Mike Turquette   clk: introduce th...
1039

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1040
1041
1042
1043
1044
1045
1046
  	if (core && (core->flags & CLK_GET_RATE_NOCACHE))
  		__clk_recalc_rates(core, 0);
  
  	rate = clk_core_get_rate_nolock(core);
  	clk_prepare_unlock();
  
  	return rate;
b2476490e   Mike Turquette   clk: introduce th...
1047
1048
1049
  }
  
  /**
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1050
1051
   * clk_get_rate - return the rate of clk
   * @clk: the clk whose rate is being returned
b2476490e   Mike Turquette   clk: introduce th...
1052
   *
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1053
1054
1055
   * Simply returns the cached rate of the clk, unless CLK_GET_RATE_NOCACHE flag
   * is set, which means a recalc_rate will be issued.
   * If clk is NULL then returns 0.
b2476490e   Mike Turquette   clk: introduce th...
1056
   */
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1057
  unsigned long clk_get_rate(struct clk *clk)
b2476490e   Mike Turquette   clk: introduce th...
1058
  {
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1059
1060
  	if (!clk)
  		return 0;
63589e92c   Stephen Boyd   clk: Ignore error...
1061

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1062
  	return clk_core_get_rate(clk->core);
b2476490e   Mike Turquette   clk: introduce th...
1063
  }
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1064
  EXPORT_SYMBOL_GPL(clk_get_rate);
b2476490e   Mike Turquette   clk: introduce th...
1065

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1066
1067
  static int clk_fetch_parent_index(struct clk_core *core,
  				  struct clk_core *parent)
b2476490e   Mike Turquette   clk: introduce th...
1068
  {
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1069
  	int i;
b2476490e   Mike Turquette   clk: introduce th...
1070

508f884a6   Masahiro Yamada   clk: make sure pa...
1071
1072
  	if (!parent)
  		return -EINVAL;
470b5e2f9   Masahiro Yamada   clk: simplify clk...
1073
1074
  	for (i = 0; i < core->num_parents; i++)
  		if (clk_core_get_parent_by_index(core, i) == parent)
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1075
  			return i;
b2476490e   Mike Turquette   clk: introduce th...
1076

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1077
  	return -EINVAL;
b2476490e   Mike Turquette   clk: introduce th...
1078
  }
e6500344e   Heiko Stuebner   clk: track the or...
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
  /*
   * Update the orphan status of @core and all its children.
   */
  static void clk_core_update_orphan_status(struct clk_core *core, bool is_orphan)
  {
  	struct clk_core *child;
  
  	core->orphan = is_orphan;
  
  	hlist_for_each_entry(child, &core->children, child_node)
  		clk_core_update_orphan_status(child, is_orphan);
  }
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1091
  static void clk_reparent(struct clk_core *core, struct clk_core *new_parent)
b2476490e   Mike Turquette   clk: introduce th...
1092
  {
e6500344e   Heiko Stuebner   clk: track the or...
1093
  	bool was_orphan = core->orphan;
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1094
  	hlist_del(&core->child_node);
035a61c31   Tomeu Vizoso   clk: Make clk API...
1095

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1096
  	if (new_parent) {
e6500344e   Heiko Stuebner   clk: track the or...
1097
  		bool becomes_orphan = new_parent->orphan;
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1098
1099
1100
  		/* avoid duplicate POST_RATE_CHANGE notifications */
  		if (new_parent->new_child == core)
  			new_parent->new_child = NULL;
b2476490e   Mike Turquette   clk: introduce th...
1101

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1102
  		hlist_add_head(&core->child_node, &new_parent->children);
e6500344e   Heiko Stuebner   clk: track the or...
1103
1104
1105
  
  		if (was_orphan != becomes_orphan)
  			clk_core_update_orphan_status(core, becomes_orphan);
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1106
1107
  	} else {
  		hlist_add_head(&core->child_node, &clk_orphan_list);
e6500344e   Heiko Stuebner   clk: track the or...
1108
1109
  		if (!was_orphan)
  			clk_core_update_orphan_status(core, true);
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1110
  	}
dfc202ead   Stephen Boyd   clk: Add tracepoi...
1111

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1112
  	core->parent = new_parent;
035a61c31   Tomeu Vizoso   clk: Make clk API...
1113
  }
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1114
1115
  static struct clk_core *__clk_set_parent_before(struct clk_core *core,
  					   struct clk_core *parent)
b2476490e   Mike Turquette   clk: introduce th...
1116
1117
  {
  	unsigned long flags;
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1118
  	struct clk_core *old_parent = core->parent;
b2476490e   Mike Turquette   clk: introduce th...
1119

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1120
  	/*
fc8726a2c   Dong Aisheng   clk: core: suppor...
1121
1122
1123
  	 * 1. enable parents for CLK_OPS_PARENT_ENABLE clock
  	 *
  	 * 2. Migrate prepare state between parents and prevent race with
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
  	 * clk_enable().
  	 *
  	 * If the clock is not prepared, then a race with
  	 * clk_enable/disable() is impossible since we already have the
  	 * prepare lock (future calls to clk_enable() need to be preceded by
  	 * a clk_prepare()).
  	 *
  	 * If the clock is prepared, migrate the prepared state to the new
  	 * parent and also protect against a race with clk_enable() by
  	 * forcing the clock and the new parent on.  This ensures that all
  	 * future calls to clk_enable() are practically NOPs with respect to
  	 * hardware and software states.
  	 *
  	 * See also: Comment for clk_set_parent() below.
  	 */
fc8726a2c   Dong Aisheng   clk: core: suppor...
1139
1140
1141
1142
1143
1144
1145
1146
  
  	/* enable old_parent & parent if CLK_OPS_PARENT_ENABLE is set */
  	if (core->flags & CLK_OPS_PARENT_ENABLE) {
  		clk_core_prepare_enable(old_parent);
  		clk_core_prepare_enable(parent);
  	}
  
  	/* migrate prepare count if > 0 */
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1147
  	if (core->prepare_count) {
fc8726a2c   Dong Aisheng   clk: core: suppor...
1148
1149
  		clk_core_prepare_enable(parent);
  		clk_core_enable_lock(core);
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1150
  	}
63589e92c   Stephen Boyd   clk: Ignore error...
1151

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1152
  	/* update the clk tree topology */
eab89f690   Mike Turquette   clk: abstract loc...
1153
  	flags = clk_enable_lock();
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1154
  	clk_reparent(core, parent);
eab89f690   Mike Turquette   clk: abstract loc...
1155
  	clk_enable_unlock(flags);
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1156
1157
  
  	return old_parent;
b2476490e   Mike Turquette   clk: introduce th...
1158
  }
b2476490e   Mike Turquette   clk: introduce th...
1159

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1160
1161
1162
  static void __clk_set_parent_after(struct clk_core *core,
  				   struct clk_core *parent,
  				   struct clk_core *old_parent)
b2476490e   Mike Turquette   clk: introduce th...
1163
  {
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1164
1165
1166
1167
1168
  	/*
  	 * Finish the migration of prepare state and undo the changes done
  	 * for preventing a race with clk_enable().
  	 */
  	if (core->prepare_count) {
fc8726a2c   Dong Aisheng   clk: core: suppor...
1169
1170
1171
1172
1173
1174
1175
1176
  		clk_core_disable_lock(core);
  		clk_core_disable_unprepare(old_parent);
  	}
  
  	/* re-balance ref counting if CLK_OPS_PARENT_ENABLE is set */
  	if (core->flags & CLK_OPS_PARENT_ENABLE) {
  		clk_core_disable_unprepare(parent);
  		clk_core_disable_unprepare(old_parent);
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1177
1178
  	}
  }
b2476490e   Mike Turquette   clk: introduce th...
1179

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1180
1181
1182
1183
1184
1185
  static int __clk_set_parent(struct clk_core *core, struct clk_core *parent,
  			    u8 p_index)
  {
  	unsigned long flags;
  	int ret = 0;
  	struct clk_core *old_parent;
b2476490e   Mike Turquette   clk: introduce th...
1186

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1187
  	old_parent = __clk_set_parent_before(core, parent);
b2476490e   Mike Turquette   clk: introduce th...
1188

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1189
  	trace_clk_set_parent(core, parent);
b2476490e   Mike Turquette   clk: introduce th...
1190

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1191
1192
1193
  	/* change clock input source */
  	if (parent && core->ops->set_parent)
  		ret = core->ops->set_parent(core->hw, p_index);
dfc202ead   Stephen Boyd   clk: Add tracepoi...
1194

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1195
  	trace_clk_set_parent_complete(core, parent);
dfc202ead   Stephen Boyd   clk: Add tracepoi...
1196

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1197
1198
1199
1200
  	if (ret) {
  		flags = clk_enable_lock();
  		clk_reparent(core, old_parent);
  		clk_enable_unlock(flags);
c660b2ebb   Dong Aisheng   clk: remove dupli...
1201
  		__clk_set_parent_after(core, old_parent, parent);
dfc202ead   Stephen Boyd   clk: Add tracepoi...
1202

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1203
  		return ret;
b2476490e   Mike Turquette   clk: introduce th...
1204
  	}
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1205
  	__clk_set_parent_after(core, parent, old_parent);
b2476490e   Mike Turquette   clk: introduce th...
1206
1207
1208
1209
  	return 0;
  }
  
  /**
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1210
1211
1212
   * __clk_speculate_rates
   * @core: first clk in the subtree
   * @parent_rate: the "future" rate of clk's parent
b2476490e   Mike Turquette   clk: introduce th...
1213
   *
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1214
1215
1216
1217
1218
1219
1220
1221
   * Walks the subtree of clks starting with clk, speculating rates as it
   * goes and firing off PRE_RATE_CHANGE notifications as necessary.
   *
   * Unlike clk_recalc_rates, clk_speculate_rates exists only for sending
   * pre-rate change notifications and returns early if no clks in the
   * subtree have subscribed to the notifications.  Note that if a clk does not
   * implement the .recalc_rate callback then it is assumed that the clock will
   * take on the rate of its parent.
b2476490e   Mike Turquette   clk: introduce th...
1222
   */
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1223
1224
  static int __clk_speculate_rates(struct clk_core *core,
  				 unsigned long parent_rate)
b2476490e   Mike Turquette   clk: introduce th...
1225
  {
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1226
1227
1228
  	struct clk_core *child;
  	unsigned long new_rate;
  	int ret = NOTIFY_DONE;
b2476490e   Mike Turquette   clk: introduce th...
1229

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1230
  	lockdep_assert_held(&prepare_lock);
864e160ae   Dong Aisheng   clk: Squash __clk...
1231

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
  	new_rate = clk_recalc(core, parent_rate);
  
  	/* abort rate change if a driver returns NOTIFY_BAD or NOTIFY_STOP */
  	if (core->notifier_count)
  		ret = __clk_notify(core, PRE_RATE_CHANGE, core->rate, new_rate);
  
  	if (ret & NOTIFY_STOP_MASK) {
  		pr_debug("%s: clk notifier callback for clock %s aborted with error %d
  ",
  				__func__, core->name, ret);
  		goto out;
  	}
  
  	hlist_for_each_entry(child, &core->children, child_node) {
  		ret = __clk_speculate_rates(child, new_rate);
  		if (ret & NOTIFY_STOP_MASK)
  			break;
  	}
b2476490e   Mike Turquette   clk: introduce th...
1250

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1251
  out:
b2476490e   Mike Turquette   clk: introduce th...
1252
1253
  	return ret;
  }
b2476490e   Mike Turquette   clk: introduce th...
1254

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1255
1256
  static void clk_calc_subtree(struct clk_core *core, unsigned long new_rate,
  			     struct clk_core *new_parent, u8 p_index)
b2476490e   Mike Turquette   clk: introduce th...
1257
  {
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1258
  	struct clk_core *child;
b2476490e   Mike Turquette   clk: introduce th...
1259

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1260
1261
1262
1263
1264
1265
1266
  	core->new_rate = new_rate;
  	core->new_parent = new_parent;
  	core->new_parent_index = p_index;
  	/* include clk in new parent's PRE_RATE_CHANGE notifications */
  	core->new_child = NULL;
  	if (new_parent && new_parent != core->parent)
  		new_parent->new_child = core;
496eadf82   Krzysztof Kozlowski   clk: Use lockdep ...
1267

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1268
1269
1270
1271
1272
  	hlist_for_each_entry(child, &core->children, child_node) {
  		child->new_rate = clk_recalc(child, new_rate);
  		clk_calc_subtree(child, child->new_rate, NULL, 0);
  	}
  }
b2476490e   Mike Turquette   clk: introduce th...
1273

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1274
1275
1276
1277
1278
1279
1280
1281
1282
  /*
   * calculate the new rates returning the topmost clock that has to be
   * changed.
   */
  static struct clk_core *clk_calc_new_rates(struct clk_core *core,
  					   unsigned long rate)
  {
  	struct clk_core *top = core;
  	struct clk_core *old_parent, *parent;
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
  	unsigned long best_parent_rate = 0;
  	unsigned long new_rate;
  	unsigned long min_rate;
  	unsigned long max_rate;
  	int p_index = 0;
  	long ret;
  
  	/* sanity */
  	if (IS_ERR_OR_NULL(core))
  		return NULL;
  
  	/* save parent rate, if it exists */
  	parent = old_parent = core->parent;
71472c0c0   James Hogan   clk: add support ...
1296
  	if (parent)
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1297
  		best_parent_rate = parent->rate;
71472c0c0   James Hogan   clk: add support ...
1298

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1299
1300
1301
  	clk_core_get_boundaries(core, &min_rate, &max_rate);
  
  	/* find the closest rate and parent clk/rate */
d6968fca7   Stephen Boyd   clk: s/clk/core/ ...
1302
  	if (core->ops->determine_rate) {
0817b62cc   Boris Brezillon   clk: change clk_o...
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
  		struct clk_rate_request req;
  
  		req.rate = rate;
  		req.min_rate = min_rate;
  		req.max_rate = max_rate;
  		if (parent) {
  			req.best_parent_hw = parent->hw;
  			req.best_parent_rate = parent->rate;
  		} else {
  			req.best_parent_hw = NULL;
  			req.best_parent_rate = 0;
  		}
  
  		ret = core->ops->determine_rate(core->hw, &req);
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1317
1318
  		if (ret < 0)
  			return NULL;
1c8e60044   Tomeu Vizoso   clk: Add rate con...
1319

0817b62cc   Boris Brezillon   clk: change clk_o...
1320
1321
1322
  		best_parent_rate = req.best_parent_rate;
  		new_rate = req.rate;
  		parent = req.best_parent_hw ? req.best_parent_hw->core : NULL;
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1323
1324
  	} else if (core->ops->round_rate) {
  		ret = core->ops->round_rate(core->hw, rate,
0817b62cc   Boris Brezillon   clk: change clk_o...
1325
  					    &best_parent_rate);
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1326
1327
  		if (ret < 0)
  			return NULL;
035a61c31   Tomeu Vizoso   clk: Make clk API...
1328

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
  		new_rate = ret;
  		if (new_rate < min_rate || new_rate > max_rate)
  			return NULL;
  	} else if (!parent || !(core->flags & CLK_SET_RATE_PARENT)) {
  		/* pass-through clock without adjustable parent */
  		core->new_rate = core->rate;
  		return NULL;
  	} else {
  		/* pass-through clock with adjustable parent */
  		top = clk_calc_new_rates(parent, rate);
  		new_rate = parent->new_rate;
  		goto out;
  	}
1c8e60044   Tomeu Vizoso   clk: Add rate con...
1342

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1343
1344
1345
1346
1347
1348
1349
1350
  	/* some clocks must be gated to change parent */
  	if (parent != old_parent &&
  	    (core->flags & CLK_SET_PARENT_GATE) && core->prepare_count) {
  		pr_debug("%s: %s not gated but wants to reparent
  ",
  			 __func__, core->name);
  		return NULL;
  	}
b2476490e   Mike Turquette   clk: introduce th...
1351

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
  	/* try finding the new parent index */
  	if (parent && core->num_parents > 1) {
  		p_index = clk_fetch_parent_index(core, parent);
  		if (p_index < 0) {
  			pr_debug("%s: clk %s can not be parent of clk %s
  ",
  				 __func__, parent->name, core->name);
  			return NULL;
  		}
  	}
b2476490e   Mike Turquette   clk: introduce th...
1362

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1363
1364
1365
  	if ((core->flags & CLK_SET_RATE_PARENT) && parent &&
  	    best_parent_rate != parent->rate)
  		top = clk_calc_new_rates(parent, best_parent_rate);
035a61c31   Tomeu Vizoso   clk: Make clk API...
1366

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1367
1368
  out:
  	clk_calc_subtree(core, new_rate, parent, p_index);
b2476490e   Mike Turquette   clk: introduce th...
1369

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1370
  	return top;
b2476490e   Mike Turquette   clk: introduce th...
1371
  }
b2476490e   Mike Turquette   clk: introduce th...
1372

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1373
1374
1375
1376
  /*
   * Notify about rate changes in a subtree. Always walk down the whole tree
   * so that in case of an error we can walk down the whole tree again and
   * abort the change.
b2476490e   Mike Turquette   clk: introduce th...
1377
   */
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1378
1379
  static struct clk_core *clk_propagate_rate_change(struct clk_core *core,
  						  unsigned long event)
b2476490e   Mike Turquette   clk: introduce th...
1380
  {
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1381
  	struct clk_core *child, *tmp_clk, *fail_clk = NULL;
b2476490e   Mike Turquette   clk: introduce th...
1382
  	int ret = NOTIFY_DONE;
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1383
1384
  	if (core->rate == core->new_rate)
  		return NULL;
b2476490e   Mike Turquette   clk: introduce th...
1385

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1386
1387
1388
1389
  	if (core->notifier_count) {
  		ret = __clk_notify(core, event, core->rate, core->new_rate);
  		if (ret & NOTIFY_STOP_MASK)
  			fail_clk = core;
b2476490e   Mike Turquette   clk: introduce th...
1390
  	}
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1391
1392
1393
1394
1395
1396
1397
1398
  	hlist_for_each_entry(child, &core->children, child_node) {
  		/* Skip children who will be reparented to another clock */
  		if (child->new_parent && child->new_parent != core)
  			continue;
  		tmp_clk = clk_propagate_rate_change(child, event);
  		if (tmp_clk)
  			fail_clk = tmp_clk;
  	}
5279fc402   Boris BREZILLON   clk: add clk accu...
1399

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1400
1401
1402
1403
1404
1405
  	/* handle the new child who might not be in core->children yet */
  	if (core->new_child) {
  		tmp_clk = clk_propagate_rate_change(core->new_child, event);
  		if (tmp_clk)
  			fail_clk = tmp_clk;
  	}
5279fc402   Boris BREZILLON   clk: add clk accu...
1406

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1407
  	return fail_clk;
5279fc402   Boris BREZILLON   clk: add clk accu...
1408
  }
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1409
1410
1411
1412
1413
  /*
   * walk down a subtree and set the new rates notifying the rate
   * change on the way
   */
  static void clk_change_rate(struct clk_core *core)
035a61c31   Tomeu Vizoso   clk: Make clk API...
1414
  {
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1415
1416
1417
1418
1419
1420
  	struct clk_core *child;
  	struct hlist_node *tmp;
  	unsigned long old_rate;
  	unsigned long best_parent_rate = 0;
  	bool skip_set_rate = false;
  	struct clk_core *old_parent;
fc8726a2c   Dong Aisheng   clk: core: suppor...
1421
  	struct clk_core *parent = NULL;
035a61c31   Tomeu Vizoso   clk: Make clk API...
1422

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1423
  	old_rate = core->rate;
035a61c31   Tomeu Vizoso   clk: Make clk API...
1424

fc8726a2c   Dong Aisheng   clk: core: suppor...
1425
1426
  	if (core->new_parent) {
  		parent = core->new_parent;
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1427
  		best_parent_rate = core->new_parent->rate;
fc8726a2c   Dong Aisheng   clk: core: suppor...
1428
1429
  	} else if (core->parent) {
  		parent = core->parent;
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1430
  		best_parent_rate = core->parent->rate;
fc8726a2c   Dong Aisheng   clk: core: suppor...
1431
  	}
035a61c31   Tomeu Vizoso   clk: Make clk API...
1432

2eb8c7104   Heiko Stuebner   clk: add flag for...
1433
1434
1435
1436
1437
1438
1439
1440
  	if (core->flags & CLK_SET_RATE_UNGATE) {
  		unsigned long flags;
  
  		clk_core_prepare(core);
  		flags = clk_enable_lock();
  		clk_core_enable(core);
  		clk_enable_unlock(flags);
  	}
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1441
1442
1443
  	if (core->new_parent && core->new_parent != core->parent) {
  		old_parent = __clk_set_parent_before(core, core->new_parent);
  		trace_clk_set_parent(core, core->new_parent);
5279fc402   Boris BREZILLON   clk: add clk accu...
1444

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1445
1446
1447
1448
1449
1450
1451
1452
  		if (core->ops->set_rate_and_parent) {
  			skip_set_rate = true;
  			core->ops->set_rate_and_parent(core->hw, core->new_rate,
  					best_parent_rate,
  					core->new_parent_index);
  		} else if (core->ops->set_parent) {
  			core->ops->set_parent(core->hw, core->new_parent_index);
  		}
5279fc402   Boris BREZILLON   clk: add clk accu...
1453

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1454
1455
1456
  		trace_clk_set_parent_complete(core, core->new_parent);
  		__clk_set_parent_after(core, core->new_parent, old_parent);
  	}
8f2c2db13   Stephen Boyd   clk: Consolidate ...
1457

fc8726a2c   Dong Aisheng   clk: core: suppor...
1458
1459
  	if (core->flags & CLK_OPS_PARENT_ENABLE)
  		clk_core_prepare_enable(parent);
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1460
  	trace_clk_set_rate(core, core->new_rate);
b2476490e   Mike Turquette   clk: introduce th...
1461

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1462
1463
  	if (!skip_set_rate && core->ops->set_rate)
  		core->ops->set_rate(core->hw, core->new_rate, best_parent_rate);
496eadf82   Krzysztof Kozlowski   clk: Use lockdep ...
1464

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1465
  	trace_clk_set_rate_complete(core, core->new_rate);
b2476490e   Mike Turquette   clk: introduce th...
1466

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1467
  	core->rate = clk_recalc(core, best_parent_rate);
b2476490e   Mike Turquette   clk: introduce th...
1468

2eb8c7104   Heiko Stuebner   clk: add flag for...
1469
1470
1471
1472
1473
1474
1475
1476
  	if (core->flags & CLK_SET_RATE_UNGATE) {
  		unsigned long flags;
  
  		flags = clk_enable_lock();
  		clk_core_disable(core);
  		clk_enable_unlock(flags);
  		clk_core_unprepare(core);
  	}
fc8726a2c   Dong Aisheng   clk: core: suppor...
1477
1478
  	if (core->flags & CLK_OPS_PARENT_ENABLE)
  		clk_core_disable_unprepare(parent);
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1479
1480
  	if (core->notifier_count && old_rate != core->rate)
  		__clk_notify(core, POST_RATE_CHANGE, old_rate, core->rate);
b2476490e   Mike Turquette   clk: introduce th...
1481

85e88fab1   Michael Turquette   Merge branch 'clk...
1482
1483
  	if (core->flags & CLK_RECALC_NEW_RATES)
  		(void)clk_calc_new_rates(core, core->new_rate);
d8d919879   Bartlomiej Zolnierkiewicz   clk: add CLK_RECA...
1484

b2476490e   Mike Turquette   clk: introduce th...
1485
  	/*
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1486
1487
  	 * Use safe iteration, as change_rate can actually swap parents
  	 * for certain clock types.
b2476490e   Mike Turquette   clk: introduce th...
1488
  	 */
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1489
1490
1491
1492
1493
1494
  	hlist_for_each_entry_safe(child, tmp, &core->children, child_node) {
  		/* Skip children who will be reparented to another clock */
  		if (child->new_parent && child->new_parent != core)
  			continue;
  		clk_change_rate(child);
  	}
b2476490e   Mike Turquette   clk: introduce th...
1495

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1496
1497
1498
  	/* handle the new child who might not be in core->children yet */
  	if (core->new_child)
  		clk_change_rate(core->new_child);
b2476490e   Mike Turquette   clk: introduce th...
1499
  }
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1500
1501
  static int clk_core_set_rate_nolock(struct clk_core *core,
  				    unsigned long req_rate)
a093bde2b   Ulf Hansson   clk: Provide opti...
1502
  {
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1503
1504
  	struct clk_core *top, *fail_clk;
  	unsigned long rate = req_rate;
a093bde2b   Ulf Hansson   clk: Provide opti...
1505

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1506
1507
  	if (!core)
  		return 0;
a093bde2b   Ulf Hansson   clk: Provide opti...
1508

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1509
1510
1511
  	/* bail early if nothing to do */
  	if (rate == clk_core_get_rate_nolock(core))
  		return 0;
a093bde2b   Ulf Hansson   clk: Provide opti...
1512

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1513
1514
  	if ((core->flags & CLK_SET_RATE_GATE) && core->prepare_count)
  		return -EBUSY;
a093bde2b   Ulf Hansson   clk: Provide opti...
1515

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
  	/* calculate new rates and get the topmost changed clock */
  	top = clk_calc_new_rates(core, rate);
  	if (!top)
  		return -EINVAL;
  
  	/* notify that we are about to change rates */
  	fail_clk = clk_propagate_rate_change(top, PRE_RATE_CHANGE);
  	if (fail_clk) {
  		pr_debug("%s: failed to set %s rate
  ", __func__,
  				fail_clk->name);
  		clk_propagate_rate_change(top, ABORT_RATE_CHANGE);
  		return -EBUSY;
  	}
  
  	/* change the rates */
  	clk_change_rate(top);
  
  	core->req_rate = req_rate;
06b37e4a6   Lee Jones   clk: Remove unuse...
1535
  	return 0;
a093bde2b   Ulf Hansson   clk: Provide opti...
1536
  }
035a61c31   Tomeu Vizoso   clk: Make clk API...
1537
1538
  
  /**
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1539
1540
1541
   * clk_set_rate - specify a new rate for clk
   * @clk: the clk whose rate is being changed
   * @rate: the new rate for clk
035a61c31   Tomeu Vizoso   clk: Make clk API...
1542
   *
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
   * In the simplest case clk_set_rate will only adjust the rate of clk.
   *
   * Setting the CLK_SET_RATE_PARENT flag allows the rate change operation to
   * propagate up to clk's parent; whether or not this happens depends on the
   * outcome of clk's .round_rate implementation.  If *parent_rate is unchanged
   * after calling .round_rate then upstream parent propagation is ignored.  If
   * *parent_rate comes back with a new rate for clk's parent then we propagate
   * up to clk's parent and set its rate.  Upward propagation will continue
   * until either a clk does not support the CLK_SET_RATE_PARENT flag or
   * .round_rate stops requesting changes to clk's parent_rate.
   *
   * Rate changes are accomplished via tree traversal that also recalculates the
   * rates for the clocks and fires off POST_RATE_CHANGE notifiers.
   *
   * Returns 0 on success, -EERROR otherwise.
035a61c31   Tomeu Vizoso   clk: Make clk API...
1558
   */
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1559
  int clk_set_rate(struct clk *clk, unsigned long rate)
035a61c31   Tomeu Vizoso   clk: Make clk API...
1560
  {
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1561
  	int ret;
035a61c31   Tomeu Vizoso   clk: Make clk API...
1562
1563
  	if (!clk)
  		return 0;
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1564
1565
  	/* prevent racing with updates to the clock topology */
  	clk_prepare_lock();
da0f0b2c3   Tomasz Figa   clk: Correct look...
1566

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1567
  	ret = clk_core_set_rate_nolock(clk->core, rate);
da0f0b2c3   Tomasz Figa   clk: Correct look...
1568

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1569
  	clk_prepare_unlock();
4935b22c4   James Hogan   clk: move some pa...
1570

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1571
  	return ret;
4935b22c4   James Hogan   clk: move some pa...
1572
  }
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1573
  EXPORT_SYMBOL_GPL(clk_set_rate);
4935b22c4   James Hogan   clk: move some pa...
1574

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1575
1576
1577
1578
1579
1580
1581
1582
1583
  /**
   * clk_set_rate_range - set a rate range for a clock source
   * @clk: clock source
   * @min: desired minimum clock rate in Hz, inclusive
   * @max: desired maximum clock rate in Hz, inclusive
   *
   * Returns success (0) or negative errno.
   */
  int clk_set_rate_range(struct clk *clk, unsigned long min, unsigned long max)
4935b22c4   James Hogan   clk: move some pa...
1584
  {
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1585
  	int ret = 0;
4935b22c4   James Hogan   clk: move some pa...
1586

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1587
1588
  	if (!clk)
  		return 0;
903efc553   James Hogan   clk: fix new_pare...
1589

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1590
1591
1592
1593
1594
1595
  	if (min > max) {
  		pr_err("%s: clk %s dev %s con %s: invalid range [%lu, %lu]
  ",
  		       __func__, clk->core->name, clk->dev_id, clk->con_id,
  		       min, max);
  		return -EINVAL;
903efc553   James Hogan   clk: fix new_pare...
1596
  	}
4935b22c4   James Hogan   clk: move some pa...
1597

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1598
  	clk_prepare_lock();
4935b22c4   James Hogan   clk: move some pa...
1599

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1600
1601
1602
1603
  	if (min != clk->min_rate || max != clk->max_rate) {
  		clk->min_rate = min;
  		clk->max_rate = max;
  		ret = clk_core_set_rate_nolock(clk->core, clk->core->req_rate);
4935b22c4   James Hogan   clk: move some pa...
1604
  	}
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1605
  	clk_prepare_unlock();
4935b22c4   James Hogan   clk: move some pa...
1606

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1607
  	return ret;
3fa2252b7   Stephen Boyd   clk: Add set_rate...
1608
  }
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1609
  EXPORT_SYMBOL_GPL(clk_set_rate_range);
3fa2252b7   Stephen Boyd   clk: Add set_rate...
1610

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1611
1612
1613
1614
1615
1616
1617
1618
  /**
   * clk_set_min_rate - set a minimum clock rate for a clock source
   * @clk: clock source
   * @rate: desired minimum clock rate in Hz, inclusive
   *
   * Returns success (0) or negative errno.
   */
  int clk_set_min_rate(struct clk *clk, unsigned long rate)
3fa2252b7   Stephen Boyd   clk: Add set_rate...
1619
  {
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1620
1621
1622
1623
  	if (!clk)
  		return 0;
  
  	return clk_set_rate_range(clk, rate, clk->max_rate);
3fa2252b7   Stephen Boyd   clk: Add set_rate...
1624
  }
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1625
  EXPORT_SYMBOL_GPL(clk_set_min_rate);
3fa2252b7   Stephen Boyd   clk: Add set_rate...
1626

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1627
1628
1629
1630
1631
1632
1633
1634
  /**
   * clk_set_max_rate - set a maximum clock rate for a clock source
   * @clk: clock source
   * @rate: desired maximum clock rate in Hz, inclusive
   *
   * Returns success (0) or negative errno.
   */
  int clk_set_max_rate(struct clk *clk, unsigned long rate)
3fa2252b7   Stephen Boyd   clk: Add set_rate...
1635
  {
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1636
1637
  	if (!clk)
  		return 0;
4935b22c4   James Hogan   clk: move some pa...
1638

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1639
  	return clk_set_rate_range(clk, clk->min_rate, rate);
4935b22c4   James Hogan   clk: move some pa...
1640
  }
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1641
  EXPORT_SYMBOL_GPL(clk_set_max_rate);
4935b22c4   James Hogan   clk: move some pa...
1642

a093bde2b   Ulf Hansson   clk: Provide opti...
1643
  /**
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1644
1645
   * clk_get_parent - return the parent of a clk
   * @clk: the clk whose parent gets returned
b2476490e   Mike Turquette   clk: introduce th...
1646
   *
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1647
   * Simply returns clk->parent.  Returns NULL if clk is NULL.
b2476490e   Mike Turquette   clk: introduce th...
1648
   */
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1649
  struct clk *clk_get_parent(struct clk *clk)
b2476490e   Mike Turquette   clk: introduce th...
1650
  {
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1651
  	struct clk *parent;
b2476490e   Mike Turquette   clk: introduce th...
1652

fc4a05d4b   Stephen Boyd   clk: Remove unuse...
1653
1654
  	if (!clk)
  		return NULL;
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1655
  	clk_prepare_lock();
fc4a05d4b   Stephen Boyd   clk: Remove unuse...
1656
1657
  	/* TODO: Create a per-user clk and change callers to call clk_put */
  	parent = !clk->core->parent ? NULL : clk->core->parent->hw->clk;
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1658
  	clk_prepare_unlock();
496eadf82   Krzysztof Kozlowski   clk: Use lockdep ...
1659

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1660
1661
1662
  	return parent;
  }
  EXPORT_SYMBOL_GPL(clk_get_parent);
b2476490e   Mike Turquette   clk: introduce th...
1663

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1664
1665
  static struct clk_core *__clk_init_parent(struct clk_core *core)
  {
5146e0b05   Masahiro Yamada   clk: simplify __c...
1666
  	u8 index = 0;
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1667

2430a94d1   Masahiro Yamada   clk: fix __clk_in...
1668
  	if (core->num_parents > 1 && core->ops->get_parent)
5146e0b05   Masahiro Yamada   clk: simplify __c...
1669
  		index = core->ops->get_parent(core->hw);
b2476490e   Mike Turquette   clk: introduce th...
1670

5146e0b05   Masahiro Yamada   clk: simplify __c...
1671
  	return clk_core_get_parent_by_index(core, index);
b2476490e   Mike Turquette   clk: introduce th...
1672
  }
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1673
1674
  static void clk_core_reparent(struct clk_core *core,
  				  struct clk_core *new_parent)
b2476490e   Mike Turquette   clk: introduce th...
1675
  {
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1676
1677
1678
  	clk_reparent(core, new_parent);
  	__clk_recalc_accuracies(core);
  	__clk_recalc_rates(core, POST_RATE_CHANGE);
b2476490e   Mike Turquette   clk: introduce th...
1679
  }
42c86547f   Tomeu Vizoso   clk: Expose clk_h...
1680
1681
1682
1683
1684
1685
1686
  void clk_hw_reparent(struct clk_hw *hw, struct clk_hw *new_parent)
  {
  	if (!hw)
  		return;
  
  	clk_core_reparent(hw->core, !new_parent ? NULL : new_parent->core);
  }
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1687
1688
1689
1690
1691
1692
1693
1694
1695
  /**
   * clk_has_parent - check if a clock is a possible parent for another
   * @clk: clock source
   * @parent: parent clock source
   *
   * This function can be used in drivers that need to check that a clock can be
   * the parent of another without actually changing the parent.
   *
   * Returns true if @parent is a possible parent for @clk, false otherwise.
b2476490e   Mike Turquette   clk: introduce th...
1696
   */
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1697
  bool clk_has_parent(struct clk *clk, struct clk *parent)
b2476490e   Mike Turquette   clk: introduce th...
1698
  {
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1699
1700
  	struct clk_core *core, *parent_core;
  	unsigned int i;
b2476490e   Mike Turquette   clk: introduce th...
1701

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1702
1703
1704
  	/* NULL clocks should be nops, so return success if either is NULL. */
  	if (!clk || !parent)
  		return true;
7452b2191   Mike Turquette   clk: core: clk_ca...
1705

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1706
1707
  	core = clk->core;
  	parent_core = parent->core;
71472c0c0   James Hogan   clk: add support ...
1708

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1709
1710
1711
  	/* Optimize for the case where the parent is already the parent. */
  	if (core->parent == parent_core)
  		return true;
1c8e60044   Tomeu Vizoso   clk: Add rate con...
1712

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1713
1714
1715
  	for (i = 0; i < core->num_parents; i++)
  		if (strcmp(core->parent_names[i], parent_core->name) == 0)
  			return true;
03bc10ab5   Boris Brezillon   clk: check ->dete...
1716

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1717
1718
1719
  	return false;
  }
  EXPORT_SYMBOL_GPL(clk_has_parent);
03bc10ab5   Boris Brezillon   clk: check ->dete...
1720

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
  static int clk_core_set_parent(struct clk_core *core, struct clk_core *parent)
  {
  	int ret = 0;
  	int p_index = 0;
  	unsigned long p_rate = 0;
  
  	if (!core)
  		return 0;
  
  	/* prevent racing with updates to the clock topology */
  	clk_prepare_lock();
87e997822   Ranjani Vaidyanathan   MLK-17363-1 imx8:...
1732
1733
  	if ((core->parent == parent) &&
  		!(core->flags & CLK_SET_PARENT_NOCACHE))
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1734
1735
1736
1737
1738
  		goto out;
  
  	/* verify ops for for multi-parent clks */
  	if ((core->num_parents > 1) && (!core->ops->set_parent)) {
  		ret = -ENOSYS;
63f5c3b2b   Mike Turquette   clk: prevent spur...
1739
  		goto out;
7452b2191   Mike Turquette   clk: core: clk_ca...
1740
  	}
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1741
1742
1743
1744
  	/* check that we are allowed to re-parent if the clock is in use */
  	if ((core->flags & CLK_SET_PARENT_GATE) && core->prepare_count) {
  		ret = -EBUSY;
  		goto out;
b2476490e   Mike Turquette   clk: introduce th...
1745
  	}
71472c0c0   James Hogan   clk: add support ...
1746
  	/* try finding the new parent index */
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1747
  	if (parent) {
d6968fca7   Stephen Boyd   clk: s/clk/core/ ...
1748
  		p_index = clk_fetch_parent_index(core, parent);
f1c8b2edf   Tomasz Figa   clk: Add error ha...
1749
  		if (p_index < 0) {
71472c0c0   James Hogan   clk: add support ...
1750
1751
  			pr_debug("%s: clk %s can not be parent of clk %s
  ",
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1752
1753
1754
  					__func__, parent->name, core->name);
  			ret = p_index;
  			goto out;
71472c0c0   James Hogan   clk: add support ...
1755
  		}
e8f0e68ec   Masahiro Yamada   clk: slightly opt...
1756
  		p_rate = parent->rate;
b2476490e   Mike Turquette   clk: introduce th...
1757
  	}
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1758
1759
  	/* propagate PRE_RATE_CHANGE notifications */
  	ret = __clk_speculate_rates(core, p_rate);
b2476490e   Mike Turquette   clk: introduce th...
1760

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1761
1762
1763
  	/* abort if a driver objects */
  	if (ret & NOTIFY_STOP_MASK)
  		goto out;
b2476490e   Mike Turquette   clk: introduce th...
1764

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1765
1766
  	/* do the re-parent */
  	ret = __clk_set_parent(core, parent, p_index);
b2476490e   Mike Turquette   clk: introduce th...
1767

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1768
1769
1770
1771
1772
1773
  	/* propagate rate an accuracy recalculation accordingly */
  	if (ret) {
  		__clk_recalc_rates(core, ABORT_RATE_CHANGE);
  	} else {
  		__clk_recalc_rates(core, POST_RATE_CHANGE);
  		__clk_recalc_accuracies(core);
b2476490e   Mike Turquette   clk: introduce th...
1774
  	}
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1775
1776
  out:
  	clk_prepare_unlock();
71472c0c0   James Hogan   clk: add support ...
1777

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1778
1779
  	return ret;
  }
b2476490e   Mike Turquette   clk: introduce th...
1780

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
  /**
   * clk_set_parent - switch the parent of a mux clk
   * @clk: the mux clk whose input we are switching
   * @parent: the new input to clk
   *
   * Re-parent clk to use parent as its new input source.  If clk is in
   * prepared state, the clk will get enabled for the duration of this call. If
   * that's not acceptable for a specific clk (Eg: the consumer can't handle
   * that, the reparenting is glitchy in hardware, etc), use the
   * CLK_SET_PARENT_GATE flag to allow reparenting only when clk is unprepared.
   *
   * After successfully changing clk's parent clk_set_parent will update the
   * clk topology, sysfs topology and propagate rate recalculation via
   * __clk_recalc_rates.
   *
   * Returns 0 on success, -EERROR otherwise.
   */
  int clk_set_parent(struct clk *clk, struct clk *parent)
  {
  	if (!clk)
  		return 0;
  
  	return clk_core_set_parent(clk->core, parent ? parent->core : NULL);
b2476490e   Mike Turquette   clk: introduce th...
1804
  }
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1805
  EXPORT_SYMBOL_GPL(clk_set_parent);
b2476490e   Mike Turquette   clk: introduce th...
1806

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
  /**
   * clk_set_phase - adjust the phase shift of a clock signal
   * @clk: clock signal source
   * @degrees: number of degrees the signal is shifted
   *
   * Shifts the phase of a clock signal by the specified
   * degrees. Returns 0 on success, -EERROR otherwise.
   *
   * This function makes no distinction about the input or reference
   * signal that we adjust the clock signal phase against. For example
   * phase locked-loop clock signal generators we may shift phase with
   * respect to feedback clock signal input, but for other cases the
   * clock phase may be shifted with respect to some other, unspecified
   * signal.
   *
   * Additionally the concept of phase shift does not propagate through
   * the clock tree hierarchy, which sets it apart from clock rates and
   * clock accuracy. A parent clock phase attribute does not have an
   * impact on the phase attribute of a child clock.
b2476490e   Mike Turquette   clk: introduce th...
1826
   */
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1827
  int clk_set_phase(struct clk *clk, int degrees)
b2476490e   Mike Turquette   clk: introduce th...
1828
  {
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1829
  	int ret = -EINVAL;
b2476490e   Mike Turquette   clk: introduce th...
1830

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1831
1832
  	if (!clk)
  		return 0;
b2476490e   Mike Turquette   clk: introduce th...
1833

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1834
1835
1836
1837
  	/* sanity check degrees */
  	degrees %= 360;
  	if (degrees < 0)
  		degrees += 360;
bf47b4fd8   Pawel Moll   clk: Check parent...
1838

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1839
  	clk_prepare_lock();
3fa2252b7   Stephen Boyd   clk: Add set_rate...
1840

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1841
  	trace_clk_set_phase(clk->core, degrees);
3fa2252b7   Stephen Boyd   clk: Add set_rate...
1842

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1843
1844
  	if (clk->core->ops->set_phase)
  		ret = clk->core->ops->set_phase(clk->core->hw, degrees);
3fa2252b7   Stephen Boyd   clk: Add set_rate...
1845

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1846
  	trace_clk_set_phase_complete(clk->core, degrees);
dfc202ead   Stephen Boyd   clk: Add tracepoi...
1847

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1848
1849
  	if (!ret)
  		clk->core->phase = degrees;
b2476490e   Mike Turquette   clk: introduce th...
1850

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1851
  	clk_prepare_unlock();
dfc202ead   Stephen Boyd   clk: Add tracepoi...
1852

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1853
1854
1855
  	return ret;
  }
  EXPORT_SYMBOL_GPL(clk_set_phase);
b2476490e   Mike Turquette   clk: introduce th...
1856

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1857
1858
1859
  static int clk_core_get_phase(struct clk_core *core)
  {
  	int ret;
b2476490e   Mike Turquette   clk: introduce th...
1860

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1861
  	clk_prepare_lock();
2dc1d1a87   Shawn Lin   clk: Don't show t...
1862
1863
1864
  	/* Always try to update cached phase if possible */
  	if (core->ops->get_phase)
  		core->phase = core->ops->get_phase(core->hw);
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1865
1866
  	ret = core->phase;
  	clk_prepare_unlock();
71472c0c0   James Hogan   clk: add support ...
1867

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1868
  	return ret;
b2476490e   Mike Turquette   clk: introduce th...
1869
  }
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1870
1871
1872
1873
1874
1875
1876
1877
  /**
   * clk_get_phase - return the phase shift of a clock signal
   * @clk: clock signal source
   *
   * Returns the phase shift of a clock node in degrees, otherwise returns
   * -EERROR.
   */
  int clk_get_phase(struct clk *clk)
1c8e60044   Tomeu Vizoso   clk: Add rate con...
1878
  {
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1879
  	if (!clk)
1c8e60044   Tomeu Vizoso   clk: Add rate con...
1880
  		return 0;
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1881
1882
1883
  	return clk_core_get_phase(clk->core);
  }
  EXPORT_SYMBOL_GPL(clk_get_phase);
1c8e60044   Tomeu Vizoso   clk: Add rate con...
1884

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
  /**
   * 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;
1c8e60044   Tomeu Vizoso   clk: Add rate con...
1901

3fe003f94   Geert Uytterhoeven   clk: Spelling s/d...
1902
  	/* true if clk->core pointers match. Avoid dereferencing garbage */
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1903
1904
1905
  	if (!IS_ERR_OR_NULL(p) && !IS_ERR_OR_NULL(q))
  		if (p->core == q->core)
  			return true;
1c8e60044   Tomeu Vizoso   clk: Add rate con...
1906

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1907
1908
1909
  	return false;
  }
  EXPORT_SYMBOL_GPL(clk_is_match);
1c8e60044   Tomeu Vizoso   clk: Add rate con...
1910

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1911
  /***        debugfs support        ***/
1c8e60044   Tomeu Vizoso   clk: Add rate con...
1912

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1913
1914
  #ifdef CONFIG_DEBUG_FS
  #include <linux/debugfs.h>
1c8e60044   Tomeu Vizoso   clk: Add rate con...
1915

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1916
1917
1918
1919
  static struct dentry *rootdir;
  static int inited = 0;
  static DEFINE_MUTEX(clk_debug_lock);
  static HLIST_HEAD(clk_debug_list);
1c8e60044   Tomeu Vizoso   clk: Add rate con...
1920

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
  static struct hlist_head *all_lists[] = {
  	&clk_root_list,
  	&clk_orphan_list,
  	NULL,
  };
  
  static struct hlist_head *orphan_list[] = {
  	&clk_orphan_list,
  	NULL,
  };
  
  static void clk_summary_show_one(struct seq_file *s, struct clk_core *c,
  				 int level)
b2476490e   Mike Turquette   clk: introduce th...
1934
  {
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1935
1936
  	if (!c)
  		return;
b2476490e   Mike Turquette   clk: introduce th...
1937

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1938
1939
1940
1941
1942
1943
1944
  	seq_printf(s, "%*s%-*s %11d %12d %11lu %10lu %-3d
  ",
  		   level * 3 + 1, "",
  		   30 - level * 3, c->name,
  		   c->enable_count, c->prepare_count, clk_core_get_rate(c),
  		   clk_core_get_accuracy(c), clk_core_get_phase(c));
  }
89ac8d7ae   Mike Turquette   clk: handle NULL ...
1945

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1946
1947
1948
1949
  static void clk_summary_show_subtree(struct seq_file *s, struct clk_core *c,
  				     int level)
  {
  	struct clk_core *child;
b2476490e   Mike Turquette   clk: introduce th...
1950

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1951
1952
  	if (!c)
  		return;
b2476490e   Mike Turquette   clk: introduce th...
1953

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1954
  	clk_summary_show_one(s, c, level);
0e1c03017   Viresh Kumar   clk: clk_set_rate...
1955

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1956
1957
  	hlist_for_each_entry(child, &c->children, child_node)
  		clk_summary_show_subtree(s, child, level + 1);
1c8e60044   Tomeu Vizoso   clk: Add rate con...
1958
  }
b2476490e   Mike Turquette   clk: introduce th...
1959

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1960
  static int clk_summary_show(struct seq_file *s, void *data)
1c8e60044   Tomeu Vizoso   clk: Add rate con...
1961
  {
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1962
1963
  	struct clk_core *c;
  	struct hlist_head **lists = (struct hlist_head **)s->private;
1c8e60044   Tomeu Vizoso   clk: Add rate con...
1964

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1965
1966
1967
1968
  	seq_puts(s, "   clock                         enable_cnt  prepare_cnt        rate   accuracy   phase
  ");
  	seq_puts(s, "----------------------------------------------------------------------------------------
  ");
b2476490e   Mike Turquette   clk: introduce th...
1969

1c8e60044   Tomeu Vizoso   clk: Add rate con...
1970
  	clk_prepare_lock();
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1971
1972
1973
  	for (; *lists; lists++)
  		hlist_for_each_entry(c, *lists, child_node)
  			clk_summary_show_subtree(s, c, 0);
b2476490e   Mike Turquette   clk: introduce th...
1974

eab89f690   Mike Turquette   clk: abstract loc...
1975
  	clk_prepare_unlock();
b2476490e   Mike Turquette   clk: introduce th...
1976

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1977
  	return 0;
b2476490e   Mike Turquette   clk: introduce th...
1978
  }
1c8e60044   Tomeu Vizoso   clk: Add rate con...
1979

1c8e60044   Tomeu Vizoso   clk: Add rate con...
1980

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1981
  static int clk_summary_open(struct inode *inode, struct file *file)
1c8e60044   Tomeu Vizoso   clk: Add rate con...
1982
  {
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1983
  	return single_open(file, clk_summary_show, inode->i_private);
1c8e60044   Tomeu Vizoso   clk: Add rate con...
1984
  }
b2476490e   Mike Turquette   clk: introduce th...
1985

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1986
1987
1988
1989
1990
1991
  static const struct file_operations clk_summary_fops = {
  	.open		= clk_summary_open,
  	.read		= seq_read,
  	.llseek		= seq_lseek,
  	.release	= single_release,
  };
b2476490e   Mike Turquette   clk: introduce th...
1992

4dff95dc9   Stephen Boyd   clk: Remove forwa...
1993
1994
1995
1996
  static void clk_dump_one(struct seq_file *s, struct clk_core *c, int level)
  {
  	if (!c)
  		return;
b2476490e   Mike Turquette   clk: introduce th...
1997

7cb81136d   Stefan Wahren   clk: Fix JSON out...
1998
  	/* This should be JSON format, i.e. elements separated with a comma */
4dff95dc9   Stephen Boyd   clk: Remove forwa...
1999
2000
2001
  	seq_printf(s, "\"%s\": { ", c->name);
  	seq_printf(s, "\"enable_count\": %d,", c->enable_count);
  	seq_printf(s, "\"prepare_count\": %d,", c->prepare_count);
7cb81136d   Stefan Wahren   clk: Fix JSON out...
2002
2003
  	seq_printf(s, "\"rate\": %lu,", clk_core_get_rate(c));
  	seq_printf(s, "\"accuracy\": %lu,", clk_core_get_accuracy(c));
4dff95dc9   Stephen Boyd   clk: Remove forwa...
2004
  	seq_printf(s, "\"phase\": %d", clk_core_get_phase(c));
b2476490e   Mike Turquette   clk: introduce th...
2005
  }
b2476490e   Mike Turquette   clk: introduce th...
2006

4dff95dc9   Stephen Boyd   clk: Remove forwa...
2007
  static void clk_dump_subtree(struct seq_file *s, struct clk_core *c, int level)
b2476490e   Mike Turquette   clk: introduce th...
2008
  {
4dff95dc9   Stephen Boyd   clk: Remove forwa...
2009
  	struct clk_core *child;
b2476490e   Mike Turquette   clk: introduce th...
2010

4dff95dc9   Stephen Boyd   clk: Remove forwa...
2011
2012
  	if (!c)
  		return;
b2476490e   Mike Turquette   clk: introduce th...
2013

4dff95dc9   Stephen Boyd   clk: Remove forwa...
2014
  	clk_dump_one(s, c, level);
b2476490e   Mike Turquette   clk: introduce th...
2015

4dff95dc9   Stephen Boyd   clk: Remove forwa...
2016
  	hlist_for_each_entry(child, &c->children, child_node) {
4d3275867   Markus Elfring   clk: Replace four...
2017
  		seq_putc(s, ',');
4dff95dc9   Stephen Boyd   clk: Remove forwa...
2018
  		clk_dump_subtree(s, child, level + 1);
b2476490e   Mike Turquette   clk: introduce th...
2019
  	}
4d3275867   Markus Elfring   clk: Replace four...
2020
  	seq_putc(s, '}');
b2476490e   Mike Turquette   clk: introduce th...
2021
  }
4dff95dc9   Stephen Boyd   clk: Remove forwa...
2022
  static int clk_dump(struct seq_file *s, void *data)
4e88f3de8   Thierry Reding   clk: Introduce cl...
2023
  {
4dff95dc9   Stephen Boyd   clk: Remove forwa...
2024
2025
2026
  	struct clk_core *c;
  	bool first_node = true;
  	struct hlist_head **lists = (struct hlist_head **)s->private;
4e88f3de8   Thierry Reding   clk: Introduce cl...
2027

4d3275867   Markus Elfring   clk: Replace four...
2028
  	seq_putc(s, '{');
4dff95dc9   Stephen Boyd   clk: Remove forwa...
2029
  	clk_prepare_lock();
035a61c31   Tomeu Vizoso   clk: Make clk API...
2030

4dff95dc9   Stephen Boyd   clk: Remove forwa...
2031
2032
2033
  	for (; *lists; lists++) {
  		hlist_for_each_entry(c, *lists, child_node) {
  			if (!first_node)
4d3275867   Markus Elfring   clk: Replace four...
2034
  				seq_putc(s, ',');
4dff95dc9   Stephen Boyd   clk: Remove forwa...
2035
2036
2037
2038
  			first_node = false;
  			clk_dump_subtree(s, c, 0);
  		}
  	}
4e88f3de8   Thierry Reding   clk: Introduce cl...
2039

4dff95dc9   Stephen Boyd   clk: Remove forwa...
2040
  	clk_prepare_unlock();
4e88f3de8   Thierry Reding   clk: Introduce cl...
2041

70e9f4dde   Felipe Balbi   clk: add newline ...
2042
2043
  	seq_puts(s, "}
  ");
4dff95dc9   Stephen Boyd   clk: Remove forwa...
2044
  	return 0;
4e88f3de8   Thierry Reding   clk: Introduce cl...
2045
  }
4e88f3de8   Thierry Reding   clk: Introduce cl...
2046

4dff95dc9   Stephen Boyd   clk: Remove forwa...
2047
2048
  
  static int clk_dump_open(struct inode *inode, struct file *file)
b2476490e   Mike Turquette   clk: introduce th...
2049
  {
4dff95dc9   Stephen Boyd   clk: Remove forwa...
2050
2051
  	return single_open(file, clk_dump, inode->i_private);
  }
b2476490e   Mike Turquette   clk: introduce th...
2052

4dff95dc9   Stephen Boyd   clk: Remove forwa...
2053
2054
2055
2056
2057
2058
  static const struct file_operations clk_dump_fops = {
  	.open		= clk_dump_open,
  	.read		= seq_read,
  	.llseek		= seq_lseek,
  	.release	= single_release,
  };
89ac8d7ae   Mike Turquette   clk: handle NULL ...
2059

92031575c   Peter De Schrijver   clk: add clk_poss...
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
  static int possible_parents_dump(struct seq_file *s, void *data)
  {
  	struct clk_core *core = s->private;
  	int i;
  
  	for (i = 0; i < core->num_parents - 1; i++)
  		seq_printf(s, "%s ", core->parent_names[i]);
  
  	seq_printf(s, "%s
  ", core->parent_names[i]);
  
  	return 0;
  }
  
  static int possible_parents_open(struct inode *inode, struct file *file)
  {
  	return single_open(file, possible_parents_dump, inode->i_private);
  }
  
  static const struct file_operations possible_parents_fops = {
  	.open		= possible_parents_open,
  	.read		= seq_read,
  	.llseek		= seq_lseek,
  	.release	= single_release,
  };
4dff95dc9   Stephen Boyd   clk: Remove forwa...
2085
2086
2087
2088
  static int clk_debug_create_one(struct clk_core *core, struct dentry *pdentry)
  {
  	struct dentry *d;
  	int ret = -ENOMEM;
b2476490e   Mike Turquette   clk: introduce th...
2089

4dff95dc9   Stephen Boyd   clk: Remove forwa...
2090
2091
  	if (!core || !pdentry) {
  		ret = -EINVAL;
b2476490e   Mike Turquette   clk: introduce th...
2092
  		goto out;
4dff95dc9   Stephen Boyd   clk: Remove forwa...
2093
  	}
b2476490e   Mike Turquette   clk: introduce th...
2094

4dff95dc9   Stephen Boyd   clk: Remove forwa...
2095
2096
  	d = debugfs_create_dir(core->name, pdentry);
  	if (!d)
b61c43c09   Stephen Boyd   clk: clk_set_pare...
2097
  		goto out;
b61c43c09   Stephen Boyd   clk: clk_set_pare...
2098

4dff95dc9   Stephen Boyd   clk: Remove forwa...
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
  	core->dentry = d;
  
  	d = debugfs_create_u32("clk_rate", S_IRUGO, core->dentry,
  			(u32 *)&core->rate);
  	if (!d)
  		goto err_out;
  
  	d = debugfs_create_u32("clk_accuracy", S_IRUGO, core->dentry,
  			(u32 *)&core->accuracy);
  	if (!d)
  		goto err_out;
  
  	d = debugfs_create_u32("clk_phase", S_IRUGO, core->dentry,
  			(u32 *)&core->phase);
  	if (!d)
  		goto err_out;
031dcc9bd   Ulf Hansson   clk: Fixup errorh...
2115

4dff95dc9   Stephen Boyd   clk: Remove forwa...
2116
2117
2118
2119
  	d = debugfs_create_x32("clk_flags", S_IRUGO, core->dentry,
  			(u32 *)&core->flags);
  	if (!d)
  		goto err_out;
031dcc9bd   Ulf Hansson   clk: Fixup errorh...
2120

4dff95dc9   Stephen Boyd   clk: Remove forwa...
2121
2122
2123
2124
  	d = debugfs_create_u32("clk_prepare_count", S_IRUGO, core->dentry,
  			(u32 *)&core->prepare_count);
  	if (!d)
  		goto err_out;
b2476490e   Mike Turquette   clk: introduce th...
2125

4dff95dc9   Stephen Boyd   clk: Remove forwa...
2126
2127
2128
2129
  	d = debugfs_create_u32("clk_enable_count", S_IRUGO, core->dentry,
  			(u32 *)&core->enable_count);
  	if (!d)
  		goto err_out;
b2476490e   Mike Turquette   clk: introduce th...
2130

4dff95dc9   Stephen Boyd   clk: Remove forwa...
2131
2132
2133
2134
  	d = debugfs_create_u32("clk_notifier_count", S_IRUGO, core->dentry,
  			(u32 *)&core->notifier_count);
  	if (!d)
  		goto err_out;
b2476490e   Mike Turquette   clk: introduce th...
2135

92031575c   Peter De Schrijver   clk: add clk_poss...
2136
2137
2138
2139
2140
2141
  	if (core->num_parents > 1) {
  		d = debugfs_create_file("clk_possible_parents", S_IRUGO,
  				core->dentry, core, &possible_parents_fops);
  		if (!d)
  			goto err_out;
  	}
4dff95dc9   Stephen Boyd   clk: Remove forwa...
2142
2143
2144
2145
  	if (core->ops->debug_init) {
  		ret = core->ops->debug_init(core->hw, core->dentry);
  		if (ret)
  			goto err_out;
5279fc402   Boris BREZILLON   clk: add clk accu...
2146
  	}
b2476490e   Mike Turquette   clk: introduce th...
2147

4dff95dc9   Stephen Boyd   clk: Remove forwa...
2148
2149
  	ret = 0;
  	goto out;
b2476490e   Mike Turquette   clk: introduce th...
2150

4dff95dc9   Stephen Boyd   clk: Remove forwa...
2151
2152
2153
2154
  err_out:
  	debugfs_remove_recursive(core->dentry);
  	core->dentry = NULL;
  out:
b2476490e   Mike Turquette   clk: introduce th...
2155
2156
  	return ret;
  }
035a61c31   Tomeu Vizoso   clk: Make clk API...
2157
2158
  
  /**
6e5ab41b1   Stephen Boyd   clk: Update some ...
2159
2160
   * clk_debug_register - add a clk node to the debugfs clk directory
   * @core: the clk being added to the debugfs clk directory
035a61c31   Tomeu Vizoso   clk: Make clk API...
2161
   *
6e5ab41b1   Stephen Boyd   clk: Update some ...
2162
2163
   * Dynamically adds a clk to the debugfs clk directory if debugfs has been
   * initialized.  Otherwise it bails out early since the debugfs clk directory
4dff95dc9   Stephen Boyd   clk: Remove forwa...
2164
   * will be created lazily by clk_debug_init as part of a late_initcall.
035a61c31   Tomeu Vizoso   clk: Make clk API...
2165
   */
4dff95dc9   Stephen Boyd   clk: Remove forwa...
2166
  static int clk_debug_register(struct clk_core *core)
035a61c31   Tomeu Vizoso   clk: Make clk API...
2167
  {
4dff95dc9   Stephen Boyd   clk: Remove forwa...
2168
  	int ret = 0;
035a61c31   Tomeu Vizoso   clk: Make clk API...
2169

4dff95dc9   Stephen Boyd   clk: Remove forwa...
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
  	mutex_lock(&clk_debug_lock);
  	hlist_add_head(&core->debug_node, &clk_debug_list);
  
  	if (!inited)
  		goto unlock;
  
  	ret = clk_debug_create_one(core, rootdir);
  unlock:
  	mutex_unlock(&clk_debug_lock);
  
  	return ret;
035a61c31   Tomeu Vizoso   clk: Make clk API...
2181
  }
b2476490e   Mike Turquette   clk: introduce th...
2182

4dff95dc9   Stephen Boyd   clk: Remove forwa...
2183
   /**
6e5ab41b1   Stephen Boyd   clk: Update some ...
2184
2185
   * clk_debug_unregister - remove a clk node from the debugfs clk directory
   * @core: the clk being removed from the debugfs clk directory
e59c5371f   Mike Turquette   clk: introduce cl...
2186
   *
6e5ab41b1   Stephen Boyd   clk: Update some ...
2187
2188
   * Dynamically removes a clk and all its child nodes from the
   * debugfs clk directory if clk->dentry points to debugfs created by
706d5c73e   Stephen Boyd   clk: Update some ...
2189
   * clk_debug_register in __clk_core_init.
e59c5371f   Mike Turquette   clk: introduce cl...
2190
   */
4dff95dc9   Stephen Boyd   clk: Remove forwa...
2191
  static void clk_debug_unregister(struct clk_core *core)
e59c5371f   Mike Turquette   clk: introduce cl...
2192
  {
4dff95dc9   Stephen Boyd   clk: Remove forwa...
2193
2194
2195
2196
2197
2198
  	mutex_lock(&clk_debug_lock);
  	hlist_del_init(&core->debug_node);
  	debugfs_remove_recursive(core->dentry);
  	core->dentry = NULL;
  	mutex_unlock(&clk_debug_lock);
  }
e59c5371f   Mike Turquette   clk: introduce cl...
2199

4dff95dc9   Stephen Boyd   clk: Remove forwa...
2200
2201
2202
2203
  struct dentry *clk_debugfs_add_file(struct clk_hw *hw, char *name, umode_t mode,
  				void *data, const struct file_operations *fops)
  {
  	struct dentry *d = NULL;
e59c5371f   Mike Turquette   clk: introduce cl...
2204

4dff95dc9   Stephen Boyd   clk: Remove forwa...
2205
2206
2207
  	if (hw->core->dentry)
  		d = debugfs_create_file(name, mode, hw->core->dentry, data,
  					fops);
e59c5371f   Mike Turquette   clk: introduce cl...
2208

4dff95dc9   Stephen Boyd   clk: Remove forwa...
2209
2210
2211
  	return d;
  }
  EXPORT_SYMBOL_GPL(clk_debugfs_add_file);
e59c5371f   Mike Turquette   clk: introduce cl...
2212

4dff95dc9   Stephen Boyd   clk: Remove forwa...
2213
  /**
6e5ab41b1   Stephen Boyd   clk: Update some ...
2214
   * clk_debug_init - lazily populate the debugfs clk directory
4dff95dc9   Stephen Boyd   clk: Remove forwa...
2215
   *
6e5ab41b1   Stephen Boyd   clk: Update some ...
2216
2217
2218
2219
2220
   * clks are often initialized very early during boot before memory can be
   * dynamically allocated and well before debugfs is setup. This function
   * populates the debugfs clk directory once at boot-time when we know that
   * debugfs is setup. It should only be called once at boot-time, all other clks
   * added dynamically will be done so with clk_debug_register.
4dff95dc9   Stephen Boyd   clk: Remove forwa...
2221
2222
2223
2224
2225
   */
  static int __init clk_debug_init(void)
  {
  	struct clk_core *core;
  	struct dentry *d;
dfc202ead   Stephen Boyd   clk: Add tracepoi...
2226

4dff95dc9   Stephen Boyd   clk: Remove forwa...
2227
  	rootdir = debugfs_create_dir("clk", NULL);
e59c5371f   Mike Turquette   clk: introduce cl...
2228

4dff95dc9   Stephen Boyd   clk: Remove forwa...
2229
2230
  	if (!rootdir)
  		return -ENOMEM;
dfc202ead   Stephen Boyd   clk: Add tracepoi...
2231

4dff95dc9   Stephen Boyd   clk: Remove forwa...
2232
2233
2234
2235
  	d = debugfs_create_file("clk_summary", S_IRUGO, rootdir, &all_lists,
  				&clk_summary_fops);
  	if (!d)
  		return -ENOMEM;
e59c5371f   Mike Turquette   clk: introduce cl...
2236

4dff95dc9   Stephen Boyd   clk: Remove forwa...
2237
2238
2239
2240
  	d = debugfs_create_file("clk_dump", S_IRUGO, rootdir, &all_lists,
  				&clk_dump_fops);
  	if (!d)
  		return -ENOMEM;
e59c5371f   Mike Turquette   clk: introduce cl...
2241

4dff95dc9   Stephen Boyd   clk: Remove forwa...
2242
2243
2244
2245
  	d = debugfs_create_file("clk_orphan_summary", S_IRUGO, rootdir,
  				&orphan_list, &clk_summary_fops);
  	if (!d)
  		return -ENOMEM;
e59c5371f   Mike Turquette   clk: introduce cl...
2246

4dff95dc9   Stephen Boyd   clk: Remove forwa...
2247
2248
2249
2250
  	d = debugfs_create_file("clk_orphan_dump", S_IRUGO, rootdir,
  				&orphan_list, &clk_dump_fops);
  	if (!d)
  		return -ENOMEM;
e59c5371f   Mike Turquette   clk: introduce cl...
2251

4dff95dc9   Stephen Boyd   clk: Remove forwa...
2252
2253
2254
  	mutex_lock(&clk_debug_lock);
  	hlist_for_each_entry(core, &clk_debug_list, debug_node)
  		clk_debug_create_one(core, rootdir);
e59c5371f   Mike Turquette   clk: introduce cl...
2255

4dff95dc9   Stephen Boyd   clk: Remove forwa...
2256
2257
  	inited = 1;
  	mutex_unlock(&clk_debug_lock);
e59c5371f   Mike Turquette   clk: introduce cl...
2258

4dff95dc9   Stephen Boyd   clk: Remove forwa...
2259
2260
2261
2262
2263
2264
2265
  	return 0;
  }
  late_initcall(clk_debug_init);
  #else
  static inline int clk_debug_register(struct clk_core *core) { return 0; }
  static inline void clk_debug_reparent(struct clk_core *core,
  				      struct clk_core *new_parent)
035a61c31   Tomeu Vizoso   clk: Make clk API...
2266
  {
035a61c31   Tomeu Vizoso   clk: Make clk API...
2267
  }
4dff95dc9   Stephen Boyd   clk: Remove forwa...
2268
  static inline void clk_debug_unregister(struct clk_core *core)
3d3801eff   Michael Turquette   clk: introduce cl...
2269
  {
3d3801eff   Michael Turquette   clk: introduce cl...
2270
  }
4dff95dc9   Stephen Boyd   clk: Remove forwa...
2271
  #endif
3d3801eff   Michael Turquette   clk: introduce cl...
2272
2273
  
  /**
be45ebf25   Masahiro Yamada   clk: rename __clk...
2274
   * __clk_core_init - initialize the data structures in a struct clk_core
d35c80c24   Masahiro Yamada   clk: change the a...
2275
   * @core:	clk_core being initialized
b2476490e   Mike Turquette   clk: introduce th...
2276
   *
035a61c31   Tomeu Vizoso   clk: Make clk API...
2277
   * Initializes the lists in struct clk_core, queries the hardware for the
b2476490e   Mike Turquette   clk: introduce th...
2278
   * parent and rate and sets them both.
b2476490e   Mike Turquette   clk: introduce th...
2279
   */
be45ebf25   Masahiro Yamada   clk: rename __clk...
2280
  static int __clk_core_init(struct clk_core *core)
b2476490e   Mike Turquette   clk: introduce th...
2281
  {
d1302a36a   Mike Turquette   clk: core: copy p...
2282
  	int i, ret = 0;
035a61c31   Tomeu Vizoso   clk: Make clk API...
2283
  	struct clk_core *orphan;
b67bfe0d4   Sasha Levin   hlist: drop the n...
2284
  	struct hlist_node *tmp2;
1c8e60044   Tomeu Vizoso   clk: Add rate con...
2285
  	unsigned long rate;
b2476490e   Mike Turquette   clk: introduce th...
2286

d35c80c24   Masahiro Yamada   clk: change the a...
2287
  	if (!core)
d1302a36a   Mike Turquette   clk: core: copy p...
2288
  		return -EINVAL;
b2476490e   Mike Turquette   clk: introduce th...
2289

eab89f690   Mike Turquette   clk: abstract loc...
2290
  	clk_prepare_lock();
b2476490e   Mike Turquette   clk: introduce th...
2291
2292
  
  	/* check to see if a clock with this name is already registered */
d6968fca7   Stephen Boyd   clk: s/clk/core/ ...
2293
  	if (clk_core_lookup(core->name)) {
d1302a36a   Mike Turquette   clk: core: copy p...
2294
2295
  		pr_debug("%s: clk %s already initialized
  ",
d6968fca7   Stephen Boyd   clk: s/clk/core/ ...
2296
  				__func__, core->name);
d1302a36a   Mike Turquette   clk: core: copy p...
2297
  		ret = -EEXIST;
b2476490e   Mike Turquette   clk: introduce th...
2298
  		goto out;
d1302a36a   Mike Turquette   clk: core: copy p...
2299
  	}
b2476490e   Mike Turquette   clk: introduce th...
2300

d4d7e3ddc   Mike Turquette   clk: core: enforc...
2301
  	/* check that clk_ops are sane.  See Documentation/clk.txt */
d6968fca7   Stephen Boyd   clk: s/clk/core/ ...
2302
2303
2304
  	if (core->ops->set_rate &&
  	    !((core->ops->round_rate || core->ops->determine_rate) &&
  	      core->ops->recalc_rate)) {
c44fccb5f   Masahiro Yamada   clk: replace pr_w...
2305
2306
2307
  		pr_err("%s: %s must implement .round_rate or .determine_rate in addition to .recalc_rate
  ",
  		       __func__, core->name);
d1302a36a   Mike Turquette   clk: core: copy p...
2308
  		ret = -EINVAL;
d4d7e3ddc   Mike Turquette   clk: core: enforc...
2309
2310
  		goto out;
  	}
d6968fca7   Stephen Boyd   clk: s/clk/core/ ...
2311
  	if (core->ops->set_parent && !core->ops->get_parent) {
c44fccb5f   Masahiro Yamada   clk: replace pr_w...
2312
2313
2314
  		pr_err("%s: %s must implement .get_parent & .set_parent
  ",
  		       __func__, core->name);
d1302a36a   Mike Turquette   clk: core: copy p...
2315
  		ret = -EINVAL;
d4d7e3ddc   Mike Turquette   clk: core: enforc...
2316
2317
  		goto out;
  	}
3c8e77dd2   Masahiro Yamada   clk: move checkin...
2318
2319
2320
2321
2322
2323
2324
  	if (core->num_parents > 1 && !core->ops->get_parent) {
  		pr_err("%s: %s must implement .get_parent as it has multi parents
  ",
  		       __func__, core->name);
  		ret = -EINVAL;
  		goto out;
  	}
d6968fca7   Stephen Boyd   clk: s/clk/core/ ...
2325
2326
  	if (core->ops->set_rate_and_parent &&
  			!(core->ops->set_parent && core->ops->set_rate)) {
c44fccb5f   Masahiro Yamada   clk: replace pr_w...
2327
2328
  		pr_err("%s: %s must implement .set_parent & .set_rate
  ",
d6968fca7   Stephen Boyd   clk: s/clk/core/ ...
2329
  				__func__, core->name);
3fa2252b7   Stephen Boyd   clk: Add set_rate...
2330
2331
2332
  		ret = -EINVAL;
  		goto out;
  	}
b2476490e   Mike Turquette   clk: introduce th...
2333
  	/* throw a WARN if any entries in parent_names are NULL */
d6968fca7   Stephen Boyd   clk: s/clk/core/ ...
2334
2335
  	for (i = 0; i < core->num_parents; i++)
  		WARN(!core->parent_names[i],
b2476490e   Mike Turquette   clk: introduce th...
2336
2337
  				"%s: invalid NULL in %s's .parent_names
  ",
d6968fca7   Stephen Boyd   clk: s/clk/core/ ...
2338
  				__func__, core->name);
b2476490e   Mike Turquette   clk: introduce th...
2339

d6968fca7   Stephen Boyd   clk: s/clk/core/ ...
2340
  	core->parent = __clk_init_parent(core);
b2476490e   Mike Turquette   clk: introduce th...
2341
2342
  
  	/*
706d5c73e   Stephen Boyd   clk: Update some ...
2343
2344
  	 * Populate core->parent if parent has already been clk_core_init'd. If
  	 * parent has not yet been clk_core_init'd then place clk in the orphan
47b0eeb3d   Stephen Boyd   clk: Deprecate CL...
2345
  	 * list.  If clk doesn't have any parents then place it in the root
b2476490e   Mike Turquette   clk: introduce th...
2346
2347
2348
2349
2350
2351
  	 * clk list.
  	 *
  	 * Every time a new clk is clk_init'd then we walk the list of orphan
  	 * clocks and re-parent any that are children of the clock currently
  	 * being clk_init'd.
  	 */
e6500344e   Heiko Stuebner   clk: track the or...
2352
  	if (core->parent) {
d6968fca7   Stephen Boyd   clk: s/clk/core/ ...
2353
2354
  		hlist_add_head(&core->child_node,
  				&core->parent->children);
e6500344e   Heiko Stuebner   clk: track the or...
2355
  		core->orphan = core->parent->orphan;
47b0eeb3d   Stephen Boyd   clk: Deprecate CL...
2356
  	} else if (!core->num_parents) {
d6968fca7   Stephen Boyd   clk: s/clk/core/ ...
2357
  		hlist_add_head(&core->child_node, &clk_root_list);
e6500344e   Heiko Stuebner   clk: track the or...
2358
2359
  		core->orphan = false;
  	} else {
d6968fca7   Stephen Boyd   clk: s/clk/core/ ...
2360
  		hlist_add_head(&core->child_node, &clk_orphan_list);
e6500344e   Heiko Stuebner   clk: track the or...
2361
2362
  		core->orphan = true;
  	}
b2476490e   Mike Turquette   clk: introduce th...
2363
2364
  
  	/*
5279fc402   Boris BREZILLON   clk: add clk accu...
2365
2366
2367
2368
2369
2370
  	 * Set clk's accuracy.  The preferred method is to use
  	 * .recalc_accuracy. For simple clocks and lazy developers the default
  	 * fallback is to use the parent's accuracy.  If a clock doesn't have a
  	 * parent (or is orphaned) then accuracy is set to zero (perfect
  	 * clock).
  	 */
d6968fca7   Stephen Boyd   clk: s/clk/core/ ...
2371
2372
2373
2374
2375
  	if (core->ops->recalc_accuracy)
  		core->accuracy = core->ops->recalc_accuracy(core->hw,
  					__clk_get_accuracy(core->parent));
  	else if (core->parent)
  		core->accuracy = core->parent->accuracy;
5279fc402   Boris BREZILLON   clk: add clk accu...
2376
  	else
d6968fca7   Stephen Boyd   clk: s/clk/core/ ...
2377
  		core->accuracy = 0;
5279fc402   Boris BREZILLON   clk: add clk accu...
2378
2379
  
  	/*
9824cf73c   Maxime Ripard   clk: Add a functi...
2380
2381
2382
2383
  	 * Set clk's phase.
  	 * Since a phase is by definition relative to its parent, just
  	 * query the current clock phase, or just assume it's in phase.
  	 */
d6968fca7   Stephen Boyd   clk: s/clk/core/ ...
2384
2385
  	if (core->ops->get_phase)
  		core->phase = core->ops->get_phase(core->hw);
9824cf73c   Maxime Ripard   clk: Add a functi...
2386
  	else
d6968fca7   Stephen Boyd   clk: s/clk/core/ ...
2387
  		core->phase = 0;
9824cf73c   Maxime Ripard   clk: Add a functi...
2388
2389
  
  	/*
b2476490e   Mike Turquette   clk: introduce th...
2390
2391
2392
2393
2394
  	 * Set clk's rate.  The preferred method is to use .recalc_rate.  For
  	 * simple clocks and lazy developers the default fallback is to use the
  	 * parent's rate.  If a clock doesn't have a parent (or is orphaned)
  	 * then rate is set to zero.
  	 */
d6968fca7   Stephen Boyd   clk: s/clk/core/ ...
2395
2396
2397
2398
2399
  	if (core->ops->recalc_rate)
  		rate = core->ops->recalc_rate(core->hw,
  				clk_core_get_rate_nolock(core->parent));
  	else if (core->parent)
  		rate = core->parent->rate;
b2476490e   Mike Turquette   clk: introduce th...
2400
  	else
1c8e60044   Tomeu Vizoso   clk: Add rate con...
2401
  		rate = 0;
d6968fca7   Stephen Boyd   clk: s/clk/core/ ...
2402
  	core->rate = core->req_rate = rate;
b2476490e   Mike Turquette   clk: introduce th...
2403
2404
  
  	/*
712b442c6   Jerome Brunet   clk: migrate the ...
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
  	 * 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);
  	}
  
  	/*
fb2588934   Dong Aisheng   MLK-17491-36 clk:...
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
  	 * optional platform-specific magic
  	 *
  	 * The .init callback is not used by any of the basic clock types, but
  	 * exists for weird hardware that must perform initialization magic.
  	 * Please consider other ways of solving initialization problems before
  	 * using this callback, as its use is discouraged.
  	 */
  	if (core->ops->init)
  		core->ops->init(core->hw);
  
  	kref_init(&core->ref);
  
  	/*
0e8f6e499   Masahiro Yamada   clk: walk the orp...
2433
2434
  	 * walk the list of orphan clocks and reparent any that newly finds a
  	 * parent.
b2476490e   Mike Turquette   clk: introduce th...
2435
  	 */
b67bfe0d4   Sasha Levin   hlist: drop the n...
2436
  	hlist_for_each_entry_safe(orphan, tmp2, &clk_orphan_list, child_node) {
0e8f6e499   Masahiro Yamada   clk: walk the orp...
2437
  		struct clk_core *parent = __clk_init_parent(orphan);
1f61e5f14   Martin Fuzzey   clk: clock multip...
2438

904e6ead0   Michael Turquette   clk: migrate ref ...
2439
  		/*
712b442c6   Jerome Brunet   clk: migrate the ...
2440
2441
2442
2443
  		 * 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.
904e6ead0   Michael Turquette   clk: migrate ref ...
2444
2445
  		 */
  		if (parent) {
9e9d9b1a3   Stephen Boyd   clk: Don't touch ...
2446
  			/* update the clk tree topology */
712b442c6   Jerome Brunet   clk: migrate the ...
2447
2448
  			__clk_set_parent_before(orphan, parent);
  			__clk_set_parent_after(orphan, parent, NULL);
904e6ead0   Michael Turquette   clk: migrate ref ...
2449
2450
2451
  			__clk_recalc_accuracies(orphan);
  			__clk_recalc_rates(orphan, 0);
  		}
0e8f6e499   Masahiro Yamada   clk: walk the orp...
2452
  	}
b2476490e   Mike Turquette   clk: introduce th...
2453

b2476490e   Mike Turquette   clk: introduce th...
2454
  out:
eab89f690   Mike Turquette   clk: abstract loc...
2455
  	clk_prepare_unlock();
b2476490e   Mike Turquette   clk: introduce th...
2456

89f7e9de5   Stephen Boyd   clk: Really fix d...
2457
  	if (!ret)
d6968fca7   Stephen Boyd   clk: s/clk/core/ ...
2458
  		clk_debug_register(core);
89f7e9de5   Stephen Boyd   clk: Really fix d...
2459

d1302a36a   Mike Turquette   clk: core: copy p...
2460
  	return ret;
b2476490e   Mike Turquette   clk: introduce th...
2461
  }
035a61c31   Tomeu Vizoso   clk: Make clk API...
2462
2463
  struct clk *__clk_create_clk(struct clk_hw *hw, const char *dev_id,
  			     const char *con_id)
0197b3ea0   Saravana Kannan   clk: Use a separa...
2464
  {
0197b3ea0   Saravana Kannan   clk: Use a separa...
2465
  	struct clk *clk;
035a61c31   Tomeu Vizoso   clk: Make clk API...
2466
  	/* This is to allow this function to be chained to others */
c1de13574   Masahiro Yamada   clk: use IS_ERR_O...
2467
  	if (IS_ERR_OR_NULL(hw))
8a23133c7   Masahiro Yamada   clk: use ERR_CAST...
2468
  		return ERR_CAST(hw);
0197b3ea0   Saravana Kannan   clk: Use a separa...
2469

035a61c31   Tomeu Vizoso   clk: Make clk API...
2470
2471
2472
2473
2474
2475
  	clk = kzalloc(sizeof(*clk), GFP_KERNEL);
  	if (!clk)
  		return ERR_PTR(-ENOMEM);
  
  	clk->core = hw->core;
  	clk->dev_id = dev_id;
253160a8a   Leonard Crestez   clk: core: Copy c...
2476
  	clk->con_id = kstrdup_const(con_id, GFP_KERNEL);
1c8e60044   Tomeu Vizoso   clk: Add rate con...
2477
2478
2479
  	clk->max_rate = ULONG_MAX;
  
  	clk_prepare_lock();
50595f8b9   Stephen Boyd   clk: Rename child...
2480
  	hlist_add_head(&clk->clks_node, &hw->core->clks);
1c8e60044   Tomeu Vizoso   clk: Add rate con...
2481
  	clk_prepare_unlock();
0197b3ea0   Saravana Kannan   clk: Use a separa...
2482
2483
2484
  
  	return clk;
  }
035a61c31   Tomeu Vizoso   clk: Make clk API...
2485

d8e7792fa   Mikko Perttunen   clk: core: Potent...
2486
  /* keep in sync with __clk_put */
73e0e496a   Stephen Boyd   clkdev: Always al...
2487
  void __clk_free_clk(struct clk *clk)
1c8e60044   Tomeu Vizoso   clk: Add rate con...
2488
2489
  {
  	clk_prepare_lock();
50595f8b9   Stephen Boyd   clk: Rename child...
2490
  	hlist_del(&clk->clks_node);
1c8e60044   Tomeu Vizoso   clk: Add rate con...
2491
  	clk_prepare_unlock();
253160a8a   Leonard Crestez   clk: core: Copy c...
2492
  	kfree_const(clk->con_id);
1c8e60044   Tomeu Vizoso   clk: Add rate con...
2493
2494
  	kfree(clk);
  }
0197b3ea0   Saravana Kannan   clk: Use a separa...
2495

293ba3b4a   Stephen Boyd   clk: Fix double f...
2496
2497
2498
2499
2500
2501
2502
  /**
   * clk_register - allocate a new clock, register it and return an opaque cookie
   * @dev: device that is registering this clock
   * @hw: link to hardware-specific clock data
   *
   * clk_register is the primary interface for populating the clock tree with new
   * clock nodes.  It returns a pointer to the newly allocated struct clk which
a59a51639   Shailendra Verma   clk: Fix typo in ...
2503
   * cannot be dereferenced by driver code but may be used in conjunction with the
293ba3b4a   Stephen Boyd   clk: Fix double f...
2504
2505
2506
2507
   * rest of the clock API.  In the event of an error clk_register will return an
   * error code; drivers must test for an error code after calling clk_register.
   */
  struct clk *clk_register(struct device *dev, struct clk_hw *hw)
b2476490e   Mike Turquette   clk: introduce th...
2508
  {
d1302a36a   Mike Turquette   clk: core: copy p...
2509
  	int i, ret;
d6968fca7   Stephen Boyd   clk: s/clk/core/ ...
2510
  	struct clk_core *core;
293ba3b4a   Stephen Boyd   clk: Fix double f...
2511

d6968fca7   Stephen Boyd   clk: s/clk/core/ ...
2512
2513
  	core = kzalloc(sizeof(*core), GFP_KERNEL);
  	if (!core) {
293ba3b4a   Stephen Boyd   clk: Fix double f...
2514
2515
2516
  		ret = -ENOMEM;
  		goto fail_out;
  	}
b2476490e   Mike Turquette   clk: introduce th...
2517

d6968fca7   Stephen Boyd   clk: s/clk/core/ ...
2518
2519
  	core->name = kstrdup_const(hw->init->name, GFP_KERNEL);
  	if (!core->name) {
0197b3ea0   Saravana Kannan   clk: Use a separa...
2520
2521
2522
  		ret = -ENOMEM;
  		goto fail_name;
  	}
d6968fca7   Stephen Boyd   clk: s/clk/core/ ...
2523
  	core->ops = hw->init->ops;
ac2df527f   Sylwester Nawrocki   clk: Add common _...
2524
  	if (dev && dev->driver)
d6968fca7   Stephen Boyd   clk: s/clk/core/ ...
2525
2526
2527
2528
  		core->owner = dev->driver->owner;
  	core->hw = hw;
  	core->flags = hw->init->flags;
  	core->num_parents = hw->init->num_parents;
9783c0d98   Stephen Boyd   clk: Allow provid...
2529
2530
  	core->min_rate = 0;
  	core->max_rate = ULONG_MAX;
d6968fca7   Stephen Boyd   clk: s/clk/core/ ...
2531
  	hw->core = core;
b2476490e   Mike Turquette   clk: introduce th...
2532

d1302a36a   Mike Turquette   clk: core: copy p...
2533
  	/* allocate local copy in case parent_names is __initdata */
d6968fca7   Stephen Boyd   clk: s/clk/core/ ...
2534
  	core->parent_names = kcalloc(core->num_parents, sizeof(char *),
96a7ed907   Tomasz Figa   clk: Use kcalloc(...
2535
  					GFP_KERNEL);
d1302a36a   Mike Turquette   clk: core: copy p...
2536

d6968fca7   Stephen Boyd   clk: s/clk/core/ ...
2537
  	if (!core->parent_names) {
d1302a36a   Mike Turquette   clk: core: copy p...
2538
2539
2540
2541
2542
2543
  		ret = -ENOMEM;
  		goto fail_parent_names;
  	}
  
  
  	/* copy each string name in case parent_names is __initdata */
d6968fca7   Stephen Boyd   clk: s/clk/core/ ...
2544
2545
  	for (i = 0; i < core->num_parents; i++) {
  		core->parent_names[i] = kstrdup_const(hw->init->parent_names[i],
0197b3ea0   Saravana Kannan   clk: Use a separa...
2546
  						GFP_KERNEL);
d6968fca7   Stephen Boyd   clk: s/clk/core/ ...
2547
  		if (!core->parent_names[i]) {
d1302a36a   Mike Turquette   clk: core: copy p...
2548
2549
2550
2551
  			ret = -ENOMEM;
  			goto fail_parent_names_copy;
  		}
  	}
176d11690   Masahiro Yamada   clk: move core->p...
2552
2553
2554
2555
2556
2557
2558
  	/* avoid unnecessary string look-ups of clk_core's possible parents. */
  	core->parents = kcalloc(core->num_parents, sizeof(*core->parents),
  				GFP_KERNEL);
  	if (!core->parents) {
  		ret = -ENOMEM;
  		goto fail_parents;
  	};
d6968fca7   Stephen Boyd   clk: s/clk/core/ ...
2559
  	INIT_HLIST_HEAD(&core->clks);
1c8e60044   Tomeu Vizoso   clk: Add rate con...
2560

035a61c31   Tomeu Vizoso   clk: Make clk API...
2561
2562
  	hw->clk = __clk_create_clk(hw, NULL, NULL);
  	if (IS_ERR(hw->clk)) {
035a61c31   Tomeu Vizoso   clk: Make clk API...
2563
  		ret = PTR_ERR(hw->clk);
176d11690   Masahiro Yamada   clk: move core->p...
2564
  		goto fail_parents;
035a61c31   Tomeu Vizoso   clk: Make clk API...
2565
  	}
be45ebf25   Masahiro Yamada   clk: rename __clk...
2566
  	ret = __clk_core_init(core);
d1302a36a   Mike Turquette   clk: core: copy p...
2567
  	if (!ret)
035a61c31   Tomeu Vizoso   clk: Make clk API...
2568
  		return hw->clk;
b2476490e   Mike Turquette   clk: introduce th...
2569

1c8e60044   Tomeu Vizoso   clk: Add rate con...
2570
  	__clk_free_clk(hw->clk);
035a61c31   Tomeu Vizoso   clk: Make clk API...
2571
  	hw->clk = NULL;
b2476490e   Mike Turquette   clk: introduce th...
2572

176d11690   Masahiro Yamada   clk: move core->p...
2573
2574
  fail_parents:
  	kfree(core->parents);
d1302a36a   Mike Turquette   clk: core: copy p...
2575
2576
  fail_parent_names_copy:
  	while (--i >= 0)
d6968fca7   Stephen Boyd   clk: s/clk/core/ ...
2577
2578
  		kfree_const(core->parent_names[i]);
  	kfree(core->parent_names);
d1302a36a   Mike Turquette   clk: core: copy p...
2579
  fail_parent_names:
d6968fca7   Stephen Boyd   clk: s/clk/core/ ...
2580
  	kfree_const(core->name);
0197b3ea0   Saravana Kannan   clk: Use a separa...
2581
  fail_name:
d6968fca7   Stephen Boyd   clk: s/clk/core/ ...
2582
  	kfree(core);
d1302a36a   Mike Turquette   clk: core: copy p...
2583
2584
  fail_out:
  	return ERR_PTR(ret);
b2476490e   Mike Turquette   clk: introduce th...
2585
2586
  }
  EXPORT_SYMBOL_GPL(clk_register);
4143804c4   Stephen Boyd   clk: Add {devm_}c...
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
  /**
   * clk_hw_register - register a clk_hw and return an error code
   * @dev: device that is registering this clock
   * @hw: link to hardware-specific clock data
   *
   * clk_hw_register is the primary interface for populating the clock tree with
   * new clock nodes. It returns an integer equal to zero indicating success or
   * less than zero indicating failure. Drivers must test for an error code after
   * calling clk_hw_register().
   */
  int clk_hw_register(struct device *dev, struct clk_hw *hw)
  {
  	return PTR_ERR_OR_ZERO(clk_register(dev, hw));
  }
  EXPORT_SYMBOL_GPL(clk_hw_register);
6e5ab41b1   Stephen Boyd   clk: Update some ...
2602
  /* Free memory allocated for a clock. */
fcb0ee6a3   Sylwester Nawrocki   clk: Implement cl...
2603
2604
  static void __clk_release(struct kref *ref)
  {
d6968fca7   Stephen Boyd   clk: s/clk/core/ ...
2605
2606
  	struct clk_core *core = container_of(ref, struct clk_core, ref);
  	int i = core->num_parents;
fcb0ee6a3   Sylwester Nawrocki   clk: Implement cl...
2607

496eadf82   Krzysztof Kozlowski   clk: Use lockdep ...
2608
  	lockdep_assert_held(&prepare_lock);
d6968fca7   Stephen Boyd   clk: s/clk/core/ ...
2609
  	kfree(core->parents);
fcb0ee6a3   Sylwester Nawrocki   clk: Implement cl...
2610
  	while (--i >= 0)
d6968fca7   Stephen Boyd   clk: s/clk/core/ ...
2611
  		kfree_const(core->parent_names[i]);
fcb0ee6a3   Sylwester Nawrocki   clk: Implement cl...
2612

d6968fca7   Stephen Boyd   clk: s/clk/core/ ...
2613
2614
2615
  	kfree(core->parent_names);
  	kfree_const(core->name);
  	kfree(core);
fcb0ee6a3   Sylwester Nawrocki   clk: Implement cl...
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
  }
  
  /*
   * Empty clk_ops for unregistered clocks. These are used temporarily
   * after clk_unregister() was called on a clock and until last clock
   * consumer calls clk_put() and the struct clk object is freed.
   */
  static int clk_nodrv_prepare_enable(struct clk_hw *hw)
  {
  	return -ENXIO;
  }
  
  static void clk_nodrv_disable_unprepare(struct clk_hw *hw)
  {
  	WARN_ON_ONCE(1);
  }
  
  static int clk_nodrv_set_rate(struct clk_hw *hw, unsigned long rate,
  					unsigned long parent_rate)
  {
  	return -ENXIO;
  }
  
  static int clk_nodrv_set_parent(struct clk_hw *hw, u8 index)
  {
  	return -ENXIO;
  }
  
  static const struct clk_ops clk_nodrv_ops = {
  	.enable		= clk_nodrv_prepare_enable,
  	.disable	= clk_nodrv_disable_unprepare,
  	.prepare	= clk_nodrv_prepare_enable,
  	.unprepare	= clk_nodrv_disable_unprepare,
  	.set_rate	= clk_nodrv_set_rate,
  	.set_parent	= clk_nodrv_set_parent,
  };
1df5c939f   Mark Brown   clk: Provide dumm...
2652
2653
2654
  /**
   * clk_unregister - unregister a currently registered clock
   * @clk: clock to unregister
1df5c939f   Mark Brown   clk: Provide dumm...
2655
   */
fcb0ee6a3   Sylwester Nawrocki   clk: Implement cl...
2656
2657
2658
  void clk_unregister(struct clk *clk)
  {
  	unsigned long flags;
6314b6796   Stephen Boyd   clk: Don't hold p...
2659
2660
  	if (!clk || WARN_ON_ONCE(IS_ERR(clk)))
  		return;
035a61c31   Tomeu Vizoso   clk: Make clk API...
2661
  	clk_debug_unregister(clk->core);
fcb0ee6a3   Sylwester Nawrocki   clk: Implement cl...
2662
2663
  
  	clk_prepare_lock();
035a61c31   Tomeu Vizoso   clk: Make clk API...
2664
2665
2666
2667
  	if (clk->core->ops == &clk_nodrv_ops) {
  		pr_err("%s: unregistered clock: %s
  ", __func__,
  		       clk->core->name);
4106a3d9e   Insu Yun   clk: unlock for h...
2668
  		goto unlock;
fcb0ee6a3   Sylwester Nawrocki   clk: Implement cl...
2669
2670
2671
2672
2673
2674
  	}
  	/*
  	 * Assign empty clock ops for consumers that might still hold
  	 * a reference to this clock.
  	 */
  	flags = clk_enable_lock();
035a61c31   Tomeu Vizoso   clk: Make clk API...
2675
  	clk->core->ops = &clk_nodrv_ops;
fcb0ee6a3   Sylwester Nawrocki   clk: Implement cl...
2676
  	clk_enable_unlock(flags);
035a61c31   Tomeu Vizoso   clk: Make clk API...
2677
2678
  	if (!hlist_empty(&clk->core->children)) {
  		struct clk_core *child;
874f224cc   Stephen Boyd   clk: Fix slab cor...
2679
  		struct hlist_node *t;
fcb0ee6a3   Sylwester Nawrocki   clk: Implement cl...
2680
2681
  
  		/* Reparent all children to the orphan list. */
035a61c31   Tomeu Vizoso   clk: Make clk API...
2682
2683
2684
  		hlist_for_each_entry_safe(child, t, &clk->core->children,
  					  child_node)
  			clk_core_set_parent(child, NULL);
fcb0ee6a3   Sylwester Nawrocki   clk: Implement cl...
2685
  	}
035a61c31   Tomeu Vizoso   clk: Make clk API...
2686
  	hlist_del_init(&clk->core->child_node);
fcb0ee6a3   Sylwester Nawrocki   clk: Implement cl...
2687

035a61c31   Tomeu Vizoso   clk: Make clk API...
2688
  	if (clk->core->prepare_count)
fcb0ee6a3   Sylwester Nawrocki   clk: Implement cl...
2689
2690
  		pr_warn("%s: unregistering prepared clock: %s
  ",
035a61c31   Tomeu Vizoso   clk: Make clk API...
2691
2692
  					__func__, clk->core->name);
  	kref_put(&clk->core->ref, __clk_release);
4106a3d9e   Insu Yun   clk: unlock for h...
2693
  unlock:
fcb0ee6a3   Sylwester Nawrocki   clk: Implement cl...
2694
2695
  	clk_prepare_unlock();
  }
1df5c939f   Mark Brown   clk: Provide dumm...
2696
  EXPORT_SYMBOL_GPL(clk_unregister);
4143804c4   Stephen Boyd   clk: Add {devm_}c...
2697
2698
2699
2700
2701
2702
2703
2704
2705
  /**
   * clk_hw_unregister - unregister a currently registered clk_hw
   * @hw: hardware-specific clock data to unregister
   */
  void clk_hw_unregister(struct clk_hw *hw)
  {
  	clk_unregister(hw->clk);
  }
  EXPORT_SYMBOL_GPL(clk_hw_unregister);
46c8773a5   Stephen Boyd   clk: Add devm_clk...
2706
2707
  static void devm_clk_release(struct device *dev, void *res)
  {
293ba3b4a   Stephen Boyd   clk: Fix double f...
2708
  	clk_unregister(*(struct clk **)res);
46c8773a5   Stephen Boyd   clk: Add devm_clk...
2709
  }
4143804c4   Stephen Boyd   clk: Add {devm_}c...
2710
2711
2712
2713
  static void devm_clk_hw_release(struct device *dev, void *res)
  {
  	clk_hw_unregister(*(struct clk_hw **)res);
  }
46c8773a5   Stephen Boyd   clk: Add devm_clk...
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
  /**
   * devm_clk_register - resource managed clk_register()
   * @dev: device that is registering this clock
   * @hw: link to hardware-specific clock data
   *
   * Managed clk_register(). Clocks returned from this function are
   * automatically clk_unregister()ed on driver detach. See clk_register() for
   * more information.
   */
  struct clk *devm_clk_register(struct device *dev, struct clk_hw *hw)
  {
  	struct clk *clk;
293ba3b4a   Stephen Boyd   clk: Fix double f...
2726
  	struct clk **clkp;
46c8773a5   Stephen Boyd   clk: Add devm_clk...
2727

293ba3b4a   Stephen Boyd   clk: Fix double f...
2728
2729
  	clkp = devres_alloc(devm_clk_release, sizeof(*clkp), GFP_KERNEL);
  	if (!clkp)
46c8773a5   Stephen Boyd   clk: Add devm_clk...
2730
  		return ERR_PTR(-ENOMEM);
293ba3b4a   Stephen Boyd   clk: Fix double f...
2731
2732
2733
2734
  	clk = clk_register(dev, hw);
  	if (!IS_ERR(clk)) {
  		*clkp = clk;
  		devres_add(dev, clkp);
46c8773a5   Stephen Boyd   clk: Add devm_clk...
2735
  	} else {
293ba3b4a   Stephen Boyd   clk: Fix double f...
2736
  		devres_free(clkp);
46c8773a5   Stephen Boyd   clk: Add devm_clk...
2737
2738
2739
2740
2741
  	}
  
  	return clk;
  }
  EXPORT_SYMBOL_GPL(devm_clk_register);
4143804c4   Stephen Boyd   clk: Add {devm_}c...
2742
2743
2744
2745
2746
  /**
   * devm_clk_hw_register - resource managed clk_hw_register()
   * @dev: device that is registering this clock
   * @hw: link to hardware-specific clock data
   *
c47265ad6   Masahiro Yamada   clk: fix comment ...
2747
   * Managed clk_hw_register(). Clocks registered by this function are
4143804c4   Stephen Boyd   clk: Add {devm_}c...
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
   * automatically clk_hw_unregister()ed on driver detach. See clk_hw_register()
   * for more information.
   */
  int devm_clk_hw_register(struct device *dev, struct clk_hw *hw)
  {
  	struct clk_hw **hwp;
  	int ret;
  
  	hwp = devres_alloc(devm_clk_hw_release, sizeof(*hwp), GFP_KERNEL);
  	if (!hwp)
  		return -ENOMEM;
  
  	ret = clk_hw_register(dev, hw);
  	if (!ret) {
  		*hwp = hw;
  		devres_add(dev, hwp);
  	} else {
  		devres_free(hwp);
  	}
  
  	return ret;
  }
  EXPORT_SYMBOL_GPL(devm_clk_hw_register);
46c8773a5   Stephen Boyd   clk: Add devm_clk...
2771
2772
2773
2774
2775
2776
2777
  static int devm_clk_match(struct device *dev, void *res, void *data)
  {
  	struct clk *c = res;
  	if (WARN_ON(!c))
  		return 0;
  	return c == data;
  }
4143804c4   Stephen Boyd   clk: Add {devm_}c...
2778
2779
2780
2781
2782
2783
2784
2785
  static int devm_clk_hw_match(struct device *dev, void *res, void *data)
  {
  	struct clk_hw *hw = res;
  
  	if (WARN_ON(!hw))
  		return 0;
  	return hw == data;
  }
46c8773a5   Stephen Boyd   clk: Add devm_clk...
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
  /**
   * devm_clk_unregister - resource managed clk_unregister()
   * @clk: clock to unregister
   *
   * Deallocate a clock allocated with devm_clk_register(). Normally
   * this function will not need to be called and the resource management
   * code will ensure that the resource is freed.
   */
  void devm_clk_unregister(struct device *dev, struct clk *clk)
  {
  	WARN_ON(devres_release(dev, devm_clk_release, devm_clk_match, clk));
  }
  EXPORT_SYMBOL_GPL(devm_clk_unregister);
4143804c4   Stephen Boyd   clk: Add {devm_}c...
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
  /**
   * devm_clk_hw_unregister - resource managed clk_hw_unregister()
   * @dev: device that is unregistering the hardware-specific clock data
   * @hw: link to hardware-specific clock data
   *
   * Unregister a clk_hw registered with devm_clk_hw_register(). Normally
   * this function will not need to be called and the resource management
   * code will ensure that the resource is freed.
   */
  void devm_clk_hw_unregister(struct device *dev, struct clk_hw *hw)
  {
  	WARN_ON(devres_release(dev, devm_clk_hw_release, devm_clk_hw_match,
  				hw));
  }
  EXPORT_SYMBOL_GPL(devm_clk_hw_unregister);
ac2df527f   Sylwester Nawrocki   clk: Add common _...
2814
2815
2816
2817
2818
  /*
   * clkdev helpers
   */
  int __clk_get(struct clk *clk)
  {
035a61c31   Tomeu Vizoso   clk: Make clk API...
2819
2820
2821
2822
  	struct clk_core *core = !clk ? NULL : clk->core;
  
  	if (core) {
  		if (!try_module_get(core->owner))
00efcb1c8   Sylwester Nawrocki   clk: Correct hand...
2823
  			return 0;
ac2df527f   Sylwester Nawrocki   clk: Add common _...
2824

035a61c31   Tomeu Vizoso   clk: Make clk API...
2825
  		kref_get(&core->ref);
00efcb1c8   Sylwester Nawrocki   clk: Correct hand...
2826
  	}
ac2df527f   Sylwester Nawrocki   clk: Add common _...
2827
2828
  	return 1;
  }
d8e7792fa   Mikko Perttunen   clk: core: Potent...
2829
  /* keep in sync with __clk_free_clk */
ac2df527f   Sylwester Nawrocki   clk: Add common _...
2830
2831
  void __clk_put(struct clk *clk)
  {
10cdfe54d   Tomeu Vizoso   clk: Don't try to...
2832
  	struct module *owner;
00efcb1c8   Sylwester Nawrocki   clk: Correct hand...
2833
  	if (!clk || WARN_ON_ONCE(IS_ERR(clk)))
ac2df527f   Sylwester Nawrocki   clk: Add common _...
2834
  		return;
fcb0ee6a3   Sylwester Nawrocki   clk: Implement cl...
2835
  	clk_prepare_lock();
1c8e60044   Tomeu Vizoso   clk: Add rate con...
2836

50595f8b9   Stephen Boyd   clk: Rename child...
2837
  	hlist_del(&clk->clks_node);
ec02ace8c   Tomeu Vizoso   clk: Only recalcu...
2838
2839
2840
  	if (clk->min_rate > clk->core->req_rate ||
  	    clk->max_rate < clk->core->req_rate)
  		clk_core_set_rate_nolock(clk->core, clk->core->req_rate);
1c8e60044   Tomeu Vizoso   clk: Add rate con...
2841
2842
  	owner = clk->core->owner;
  	kref_put(&clk->core->ref, __clk_release);
fcb0ee6a3   Sylwester Nawrocki   clk: Implement cl...
2843
  	clk_prepare_unlock();
10cdfe54d   Tomeu Vizoso   clk: Don't try to...
2844
  	module_put(owner);
035a61c31   Tomeu Vizoso   clk: Make clk API...
2845

d8e7792fa   Mikko Perttunen   clk: core: Potent...
2846
  	kfree_const(clk->con_id);
035a61c31   Tomeu Vizoso   clk: Make clk API...
2847
  	kfree(clk);
ac2df527f   Sylwester Nawrocki   clk: Add common _...
2848
  }
b2476490e   Mike Turquette   clk: introduce th...
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
  /***        clk rate change notifiers        ***/
  
  /**
   * clk_notifier_register - add a clk rate change notifier
   * @clk: struct clk * to watch
   * @nb: struct notifier_block * with callback info
   *
   * Request notification when clk's rate changes.  This uses an SRCU
   * notifier because we want it to block and notifier unregistrations are
   * uncommon.  The callbacks associated with the notifier must not
   * re-enter into the clk framework by calling any top-level clk APIs;
   * this will cause a nested prepare_lock mutex.
   *
198bb5949   Masahiro Yamada   clk: fix a typo i...
2862
2863
2864
   * In all notification cases (pre, post and abort rate change) the original
   * clock rate is passed to the callback via struct clk_notifier_data.old_rate
   * and the new frequency is passed via struct clk_notifier_data.new_rate.
b2476490e   Mike Turquette   clk: introduce th...
2865
   *
b2476490e   Mike Turquette   clk: introduce th...
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
   * clk_notifier_register() must be called from non-atomic context.
   * Returns -EINVAL if called with null arguments, -ENOMEM upon
   * allocation failure; otherwise, passes along the return value of
   * srcu_notifier_chain_register().
   */
  int clk_notifier_register(struct clk *clk, struct notifier_block *nb)
  {
  	struct clk_notifier *cn;
  	int ret = -ENOMEM;
  
  	if (!clk || !nb)
  		return -EINVAL;
eab89f690   Mike Turquette   clk: abstract loc...
2878
  	clk_prepare_lock();
b2476490e   Mike Turquette   clk: introduce th...
2879
2880
2881
2882
2883
2884
2885
2886
  
  	/* search the list of notifiers for this clk */
  	list_for_each_entry(cn, &clk_notifier_list, node)
  		if (cn->clk == clk)
  			break;
  
  	/* if clk wasn't in the notifier list, allocate new clk_notifier */
  	if (cn->clk != clk) {
1808a3201   Markus Elfring   clk: Improve a si...
2887
  		cn = kzalloc(sizeof(*cn), GFP_KERNEL);
b2476490e   Mike Turquette   clk: introduce th...
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
  		if (!cn)
  			goto out;
  
  		cn->clk = clk;
  		srcu_init_notifier_head(&cn->notifier_head);
  
  		list_add(&cn->node, &clk_notifier_list);
  	}
  
  	ret = srcu_notifier_chain_register(&cn->notifier_head, nb);
035a61c31   Tomeu Vizoso   clk: Make clk API...
2898
  	clk->core->notifier_count++;
b2476490e   Mike Turquette   clk: introduce th...
2899
2900
  
  out:
eab89f690   Mike Turquette   clk: abstract loc...
2901
  	clk_prepare_unlock();
b2476490e   Mike Turquette   clk: introduce th...
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
  
  	return ret;
  }
  EXPORT_SYMBOL_GPL(clk_notifier_register);
  
  /**
   * clk_notifier_unregister - remove a clk rate change notifier
   * @clk: struct clk *
   * @nb: struct notifier_block * with callback info
   *
   * Request no further notification for changes to 'clk' and frees memory
   * allocated in clk_notifier_register.
   *
   * Returns -EINVAL if called with null arguments; otherwise, passes
   * along the return value of srcu_notifier_chain_unregister().
   */
  int clk_notifier_unregister(struct clk *clk, struct notifier_block *nb)
  {
  	struct clk_notifier *cn = NULL;
  	int ret = -EINVAL;
  
  	if (!clk || !nb)
  		return -EINVAL;
eab89f690   Mike Turquette   clk: abstract loc...
2925
  	clk_prepare_lock();
b2476490e   Mike Turquette   clk: introduce th...
2926
2927
2928
2929
2930
2931
2932
  
  	list_for_each_entry(cn, &clk_notifier_list, node)
  		if (cn->clk == clk)
  			break;
  
  	if (cn->clk == clk) {
  		ret = srcu_notifier_chain_unregister(&cn->notifier_head, nb);
035a61c31   Tomeu Vizoso   clk: Make clk API...
2933
  		clk->core->notifier_count--;
b2476490e   Mike Turquette   clk: introduce th...
2934
2935
2936
2937
  
  		/* XXX the notifier code should handle this better */
  		if (!cn->notifier_head.head) {
  			srcu_cleanup_notifier_head(&cn->notifier_head);
72b5322f1   Lai Jiangshan   clk: remove notif...
2938
  			list_del(&cn->node);
b2476490e   Mike Turquette   clk: introduce th...
2939
2940
2941
2942
2943
2944
  			kfree(cn);
  		}
  
  	} else {
  		ret = -ENOENT;
  	}
eab89f690   Mike Turquette   clk: abstract loc...
2945
  	clk_prepare_unlock();
b2476490e   Mike Turquette   clk: introduce th...
2946
2947
2948
2949
  
  	return ret;
  }
  EXPORT_SYMBOL_GPL(clk_notifier_unregister);
766e6a4ec   Grant Likely   clk: add DT clock...
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
  
  #ifdef CONFIG_OF
  /**
   * struct of_clk_provider - Clock provider registration structure
   * @link: Entry in global list of clock providers
   * @node: Pointer to device tree node of clock provider
   * @get: Get clock callback.  Returns NULL or a struct clk for the
   *       given clock specifier
   * @data: context pointer to be passed into @get callback
   */
  struct of_clk_provider {
  	struct list_head link;
  
  	struct device_node *node;
  	struct clk *(*get)(struct of_phandle_args *clkspec, void *data);
0861e5b8c   Stephen Boyd   clk: Add clk_hw O...
2965
  	struct clk_hw *(*get_hw)(struct of_phandle_args *clkspec, void *data);
766e6a4ec   Grant Likely   clk: add DT clock...
2966
2967
  	void *data;
  };
f2f6c2556   Prashant Gaikwad   clk: add common o...
2968
2969
  static const struct of_device_id __clk_of_table_sentinel
  	__used __section(__clk_of_table_end);
766e6a4ec   Grant Likely   clk: add DT clock...
2970
  static LIST_HEAD(of_clk_providers);
d6782c263   Sylwester Nawrocki   clk: Provide not ...
2971
  static DEFINE_MUTEX(of_clk_mutex);
766e6a4ec   Grant Likely   clk: add DT clock...
2972
2973
2974
2975
2976
2977
  struct clk *of_clk_src_simple_get(struct of_phandle_args *clkspec,
  				     void *data)
  {
  	return data;
  }
  EXPORT_SYMBOL_GPL(of_clk_src_simple_get);
0861e5b8c   Stephen Boyd   clk: Add clk_hw O...
2978
2979
2980
2981
2982
  struct clk_hw *of_clk_hw_simple_get(struct of_phandle_args *clkspec, void *data)
  {
  	return data;
  }
  EXPORT_SYMBOL_GPL(of_clk_hw_simple_get);
494bfec99   Shawn Guo   clk: add of_clk_s...
2983
2984
2985
2986
2987
2988
  struct clk *of_clk_src_onecell_get(struct of_phandle_args *clkspec, void *data)
  {
  	struct clk_onecell_data *clk_data = data;
  	unsigned int idx = clkspec->args[0];
  
  	if (idx >= clk_data->clk_num) {
7e96353c3   Geert Uytterhoeven   clk: Use %u to fo...
2989
2990
  		pr_err("%s: invalid clock index %u
  ", __func__, idx);
494bfec99   Shawn Guo   clk: add of_clk_s...
2991
2992
2993
2994
2995
2996
  		return ERR_PTR(-EINVAL);
  	}
  
  	return clk_data->clks[idx];
  }
  EXPORT_SYMBOL_GPL(of_clk_src_onecell_get);
0861e5b8c   Stephen Boyd   clk: Add clk_hw O...
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
  struct clk_hw *
  of_clk_hw_onecell_get(struct of_phandle_args *clkspec, void *data)
  {
  	struct clk_hw_onecell_data *hw_data = data;
  	unsigned int idx = clkspec->args[0];
  
  	if (idx >= hw_data->num) {
  		pr_err("%s: invalid index %u
  ", __func__, idx);
  		return ERR_PTR(-EINVAL);
  	}
  
  	return hw_data->hws[idx];
  }
  EXPORT_SYMBOL_GPL(of_clk_hw_onecell_get);
766e6a4ec   Grant Likely   clk: add DT clock...
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
  /**
   * of_clk_add_provider() - Register a clock provider for a node
   * @np: Device node pointer associated with clock provider
   * @clk_src_get: callback for decoding clock
   * @data: context pointer for @clk_src_get callback.
   */
  int of_clk_add_provider(struct device_node *np,
  			struct clk *(*clk_src_get)(struct of_phandle_args *clkspec,
  						   void *data),
  			void *data)
  {
  	struct of_clk_provider *cp;
86be408bf   Sylwester Nawrocki   clk: Support for ...
3024
  	int ret;
766e6a4ec   Grant Likely   clk: add DT clock...
3025

1808a3201   Markus Elfring   clk: Improve a si...
3026
  	cp = kzalloc(sizeof(*cp), GFP_KERNEL);
766e6a4ec   Grant Likely   clk: add DT clock...
3027
3028
3029
3030
3031
3032
  	if (!cp)
  		return -ENOMEM;
  
  	cp->node = of_node_get(np);
  	cp->data = data;
  	cp->get = clk_src_get;
d6782c263   Sylwester Nawrocki   clk: Provide not ...
3033
  	mutex_lock(&of_clk_mutex);
766e6a4ec   Grant Likely   clk: add DT clock...
3034
  	list_add(&cp->link, &of_clk_providers);
d6782c263   Sylwester Nawrocki   clk: Provide not ...
3035
  	mutex_unlock(&of_clk_mutex);
166739312   Rob Herring   clk: Convert to u...
3036
3037
  	pr_debug("Added clock from %pOF
  ", np);
766e6a4ec   Grant Likely   clk: add DT clock...
3038

86be408bf   Sylwester Nawrocki   clk: Support for ...
3039
3040
3041
3042
3043
  	ret = of_clk_set_defaults(np, true);
  	if (ret < 0)
  		of_clk_del_provider(np);
  
  	return ret;
766e6a4ec   Grant Likely   clk: add DT clock...
3044
3045
3046
3047
  }
  EXPORT_SYMBOL_GPL(of_clk_add_provider);
  
  /**
0861e5b8c   Stephen Boyd   clk: Add clk_hw O...
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
   * of_clk_add_hw_provider() - Register a clock provider for a node
   * @np: Device node pointer associated with clock provider
   * @get: callback for decoding clk_hw
   * @data: context pointer for @get callback.
   */
  int of_clk_add_hw_provider(struct device_node *np,
  			   struct clk_hw *(*get)(struct of_phandle_args *clkspec,
  						 void *data),
  			   void *data)
  {
  	struct of_clk_provider *cp;
  	int ret;
  
  	cp = kzalloc(sizeof(*cp), GFP_KERNEL);
  	if (!cp)
  		return -ENOMEM;
  
  	cp->node = of_node_get(np);
  	cp->data = data;
  	cp->get_hw = get;
  
  	mutex_lock(&of_clk_mutex);
  	list_add(&cp->link, &of_clk_providers);
  	mutex_unlock(&of_clk_mutex);
166739312   Rob Herring   clk: Convert to u...
3072
3073
  	pr_debug("Added clk_hw provider from %pOF
  ", np);
0861e5b8c   Stephen Boyd   clk: Add clk_hw O...
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
  
  	ret = of_clk_set_defaults(np, true);
  	if (ret < 0)
  		of_clk_del_provider(np);
  
  	return ret;
  }
  EXPORT_SYMBOL_GPL(of_clk_add_hw_provider);
  
  /**
766e6a4ec   Grant Likely   clk: add DT clock...
3084
3085
3086
3087
3088
3089
   * of_clk_del_provider() - Remove a previously registered clock provider
   * @np: Device node pointer associated with clock provider
   */
  void of_clk_del_provider(struct device_node *np)
  {
  	struct of_clk_provider *cp;
d6782c263   Sylwester Nawrocki   clk: Provide not ...
3090
  	mutex_lock(&of_clk_mutex);
766e6a4ec   Grant Likely   clk: add DT clock...
3091
3092
3093
3094
3095
3096
3097
3098
  	list_for_each_entry(cp, &of_clk_providers, link) {
  		if (cp->node == np) {
  			list_del(&cp->link);
  			of_node_put(cp->node);
  			kfree(cp);
  			break;
  		}
  	}
d6782c263   Sylwester Nawrocki   clk: Provide not ...
3099
  	mutex_unlock(&of_clk_mutex);
766e6a4ec   Grant Likely   clk: add DT clock...
3100
3101
  }
  EXPORT_SYMBOL_GPL(of_clk_del_provider);
0861e5b8c   Stephen Boyd   clk: Add clk_hw O...
3102
3103
3104
3105
3106
  static struct clk_hw *
  __of_clk_get_hw_from_provider(struct of_clk_provider *provider,
  			      struct of_phandle_args *clkspec)
  {
  	struct clk *clk;
0861e5b8c   Stephen Boyd   clk: Add clk_hw O...
3107

74002fcde   Stephen Boyd   clk: Simplify __o...
3108
3109
  	if (provider->get_hw)
  		return provider->get_hw(clkspec, provider->data);
0861e5b8c   Stephen Boyd   clk: Add clk_hw O...
3110

74002fcde   Stephen Boyd   clk: Simplify __o...
3111
3112
3113
3114
  	clk = provider->get(clkspec, provider->data);
  	if (IS_ERR(clk))
  		return ERR_CAST(clk);
  	return __clk_get_hw(clk);
0861e5b8c   Stephen Boyd   clk: Add clk_hw O...
3115
  }
73e0e496a   Stephen Boyd   clkdev: Always al...
3116
3117
  struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec,
  				       const char *dev_id, const char *con_id)
766e6a4ec   Grant Likely   clk: add DT clock...
3118
3119
  {
  	struct of_clk_provider *provider;
a34cd4666   Jean-Francois Moine   clk: return probe...
3120
  	struct clk *clk = ERR_PTR(-EPROBE_DEFER);
f155d15b6   Stephen Boyd   clk: Return error...
3121
  	struct clk_hw *hw;
766e6a4ec   Grant Likely   clk: add DT clock...
3122

306c342f9   Stephen Boyd   clk: Replace of_c...
3123
3124
  	if (!clkspec)
  		return ERR_PTR(-EINVAL);
766e6a4ec   Grant Likely   clk: add DT clock...
3125
  	/* Check if we have such a provider in our array */
306c342f9   Stephen Boyd   clk: Replace of_c...
3126
  	mutex_lock(&of_clk_mutex);
766e6a4ec   Grant Likely   clk: add DT clock...
3127
  	list_for_each_entry(provider, &of_clk_providers, link) {
f155d15b6   Stephen Boyd   clk: Return error...
3128
  		if (provider->node == clkspec->np) {
0861e5b8c   Stephen Boyd   clk: Add clk_hw O...
3129
  			hw = __of_clk_get_hw_from_provider(provider, clkspec);
0861e5b8c   Stephen Boyd   clk: Add clk_hw O...
3130
  			clk = __clk_create_clk(hw, dev_id, con_id);
f155d15b6   Stephen Boyd   clk: Return error...
3131
  		}
73e0e496a   Stephen Boyd   clkdev: Always al...
3132

f155d15b6   Stephen Boyd   clk: Return error...
3133
3134
  		if (!IS_ERR(clk)) {
  			if (!__clk_get(clk)) {
73e0e496a   Stephen Boyd   clkdev: Always al...
3135
3136
3137
  				__clk_free_clk(clk);
  				clk = ERR_PTR(-ENOENT);
  			}
766e6a4ec   Grant Likely   clk: add DT clock...
3138
  			break;
73e0e496a   Stephen Boyd   clkdev: Always al...
3139
  		}
766e6a4ec   Grant Likely   clk: add DT clock...
3140
  	}
306c342f9   Stephen Boyd   clk: Replace of_c...
3141
  	mutex_unlock(&of_clk_mutex);
d6782c263   Sylwester Nawrocki   clk: Provide not ...
3142
3143
3144
  
  	return clk;
  }
306c342f9   Stephen Boyd   clk: Replace of_c...
3145
3146
3147
3148
3149
3150
3151
3152
  /**
   * of_clk_get_from_provider() - Lookup a clock from a clock provider
   * @clkspec: pointer to a clock specifier data structure
   *
   * This function looks up a struct clk from the registered list of clock
   * providers, an input is a clock specifier data structure as returned
   * from the of_parse_phandle_with_args() function call.
   */
d6782c263   Sylwester Nawrocki   clk: Provide not ...
3153
3154
  struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec)
  {
306c342f9   Stephen Boyd   clk: Replace of_c...
3155
  	return __of_clk_get_from_provider(clkspec, NULL, __func__);
766e6a4ec   Grant Likely   clk: add DT clock...
3156
  }
fb4dd2220   Andrew F. Davis   clk: Make of_clk_...
3157
  EXPORT_SYMBOL_GPL(of_clk_get_from_provider);
766e6a4ec   Grant Likely   clk: add DT clock...
3158

929e7f3bc   Stephen Boyd   clk: Make of_clk_...
3159
3160
3161
3162
3163
3164
3165
  /**
   * of_clk_get_parent_count() - Count the number of clocks a device node has
   * @np: device node to count
   *
   * Returns: The number of clocks that are possible parents of this node
   */
  unsigned int of_clk_get_parent_count(struct device_node *np)
f61027426   Mike Turquette   clk: of: helper f...
3166
  {
929e7f3bc   Stephen Boyd   clk: Make of_clk_...
3167
3168
3169
3170
3171
3172
3173
  	int count;
  
  	count = of_count_phandle_with_args(np, "clocks", "#clock-cells");
  	if (count < 0)
  		return 0;
  
  	return count;
f61027426   Mike Turquette   clk: of: helper f...
3174
3175
  }
  EXPORT_SYMBOL_GPL(of_clk_get_parent_count);
766e6a4ec   Grant Likely   clk: add DT clock...
3176
3177
3178
  const char *of_clk_get_parent_name(struct device_node *np, int index)
  {
  	struct of_phandle_args clkspec;
7a0fc1a3d   Ben Dooks   clk: add clock-in...
3179
  	struct property *prop;
766e6a4ec   Grant Likely   clk: add DT clock...
3180
  	const char *clk_name;
7a0fc1a3d   Ben Dooks   clk: add clock-in...
3181
3182
  	const __be32 *vp;
  	u32 pv;
766e6a4ec   Grant Likely   clk: add DT clock...
3183
  	int rc;
7a0fc1a3d   Ben Dooks   clk: add clock-in...
3184
  	int count;
0a4807c2f   Stephen Boyd   clk: Make of_clk_...
3185
  	struct clk *clk;
766e6a4ec   Grant Likely   clk: add DT clock...
3186

766e6a4ec   Grant Likely   clk: add DT clock...
3187
3188
3189
3190
  	rc = of_parse_phandle_with_args(np, "clocks", "#clock-cells", index,
  					&clkspec);
  	if (rc)
  		return NULL;
7a0fc1a3d   Ben Dooks   clk: add clock-in...
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
  	index = clkspec.args_count ? clkspec.args[0] : 0;
  	count = 0;
  
  	/* if there is an indices property, use it to transfer the index
  	 * specified into an array offset for the clock-output-names property.
  	 */
  	of_property_for_each_u32(clkspec.np, "clock-indices", prop, vp, pv) {
  		if (index == pv) {
  			index = count;
  			break;
  		}
  		count++;
  	}
8da411cc1   Masahiro Yamada   clk: let of_clk_g...
3204
3205
3206
  	/* We went off the end of 'clock-indices' without finding it */
  	if (prop && !vp)
  		return NULL;
7a0fc1a3d   Ben Dooks   clk: add clock-in...
3207

766e6a4ec   Grant Likely   clk: add DT clock...
3208
  	if (of_property_read_string_index(clkspec.np, "clock-output-names",
7a0fc1a3d   Ben Dooks   clk: add clock-in...
3209
  					  index,
0a4807c2f   Stephen Boyd   clk: Make of_clk_...
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
  					  &clk_name) < 0) {
  		/*
  		 * Best effort to get the name if the clock has been
  		 * registered with the framework. If the clock isn't
  		 * registered, we return the node name as the name of
  		 * the clock as long as #clock-cells = 0.
  		 */
  		clk = of_clk_get_from_provider(&clkspec);
  		if (IS_ERR(clk)) {
  			if (clkspec.args_count == 0)
  				clk_name = clkspec.np->name;
  			else
  				clk_name = NULL;
  		} else {
  			clk_name = __clk_get_name(clk);
  			clk_put(clk);
  		}
  	}
766e6a4ec   Grant Likely   clk: add DT clock...
3228
3229
3230
3231
3232
  
  	of_node_put(clkspec.np);
  	return clk_name;
  }
  EXPORT_SYMBOL_GPL(of_clk_get_parent_name);
2e61dfb36   Dinh Nguyen   clk: of: helper f...
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
  /**
   * of_clk_parent_fill() - Fill @parents with names of @np's parents and return
   * number of parents
   * @np: Device node pointer associated with clock provider
   * @parents: pointer to char array that hold the parents' names
   * @size: size of the @parents array
   *
   * Return: number of parents for the clock node.
   */
  int of_clk_parent_fill(struct device_node *np, const char **parents,
  		       unsigned int size)
  {
  	unsigned int i = 0;
  
  	while (i < size && (parents[i] = of_clk_get_parent_name(np, i)) != NULL)
  		i++;
  
  	return i;
  }
  EXPORT_SYMBOL_GPL(of_clk_parent_fill);
1771b10d6   Gregory CLEMENT   clk: respect the ...
3253
3254
3255
3256
3257
  struct clock_provider {
  	of_clk_init_cb_t clk_init_cb;
  	struct device_node *np;
  	struct list_head node;
  };
1771b10d6   Gregory CLEMENT   clk: respect the ...
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
  /*
   * This function looks for a parent clock. If there is one, then it
   * checks that the provider for this parent clock was initialized, in
   * this case the parent clock will be ready.
   */
  static int parent_ready(struct device_node *np)
  {
  	int i = 0;
  
  	while (true) {
  		struct clk *clk = of_clk_get(np, i);
  
  		/* this parent is ready we can check the next one */
  		if (!IS_ERR(clk)) {
  			clk_put(clk);
  			i++;
  			continue;
  		}
  
  		/* at least one parent is not ready, we exit now */
  		if (PTR_ERR(clk) == -EPROBE_DEFER)
  			return 0;
  
  		/*
  		 * Here we make assumption that the device tree is
  		 * written correctly. So an error means that there is
  		 * no more parent. As we didn't exit yet, then the
  		 * previous parent are ready. If there is no clock
  		 * parent, no need to wait for them, then we can
  		 * consider their absence as being ready
  		 */
  		return 1;
  	}
  }
766e6a4ec   Grant Likely   clk: add DT clock...
3292
  /**
d56f8994b   Lee Jones   clk: Provide OF h...
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
   * of_clk_detect_critical() - set CLK_IS_CRITICAL flag from Device Tree
   * @np: Device node pointer associated with clock provider
   * @index: clock index
   * @flags: pointer to clk_core->flags
   *
   * Detects if the clock-critical property exists and, if so, sets the
   * corresponding CLK_IS_CRITICAL flag.
   *
   * Do not use this function. It exists only for legacy Device Tree
   * bindings, such as the one-clock-per-node style that are outdated.
   * Those bindings typically put all clock data into .dts and the Linux
   * driver has no clock data, thus making it impossible to set this flag
   * correctly from the driver. Only those drivers may call
   * of_clk_detect_critical from their setup functions.
   *
   * Return: error code or zero on success
   */
  int of_clk_detect_critical(struct device_node *np,
  					  int index, unsigned long *flags)
  {
  	struct property *prop;
  	const __be32 *cur;
  	uint32_t idx;
  
  	if (!np || !flags)
  		return -EINVAL;
  
  	of_property_for_each_u32(np, "clock-critical", prop, cur, idx)
  		if (index == idx)
  			*flags |= CLK_IS_CRITICAL;
  
  	return 0;
  }
  
  /**
766e6a4ec   Grant Likely   clk: add DT clock...
3328
3329
3330
   * of_clk_init() - Scan and init clock providers from the DT
   * @matches: array of compatible values and init functions for providers.
   *
1771b10d6   Gregory CLEMENT   clk: respect the ...
3331
   * This function scans the device tree for matching clock providers
e5ca8fb4c   Sylwester Nawrocki   clk: Fix minor er...
3332
   * and calls their initialization functions. It also does it by trying
1771b10d6   Gregory CLEMENT   clk: respect the ...
3333
   * to follow the dependencies.
766e6a4ec   Grant Likely   clk: add DT clock...
3334
3335
3336
   */
  void __init of_clk_init(const struct of_device_id *matches)
  {
7f7ed584d   Alex Elder   clk: get matching...
3337
  	const struct of_device_id *match;
766e6a4ec   Grant Likely   clk: add DT clock...
3338
  	struct device_node *np;
1771b10d6   Gregory CLEMENT   clk: respect the ...
3339
3340
3341
  	struct clock_provider *clk_provider, *next;
  	bool is_init_done;
  	bool force = false;
2573a02aa   Stephen Boyd   clk: Move clk_pro...
3342
  	LIST_HEAD(clk_provider_list);
766e6a4ec   Grant Likely   clk: add DT clock...
3343

f2f6c2556   Prashant Gaikwad   clk: add common o...
3344
  	if (!matches)
819b4861c   Tero Kristo   CLK: ti: add init...
3345
  		matches = &__clk_of_table;
f2f6c2556   Prashant Gaikwad   clk: add common o...
3346

1771b10d6   Gregory CLEMENT   clk: respect the ...
3347
  	/* First prepare the list of the clocks providers */
7f7ed584d   Alex Elder   clk: get matching...
3348
  	for_each_matching_node_and_match(np, matches, &match) {
2e3b19f13   Stephen Boyd   clk: Check for al...
3349
  		struct clock_provider *parent;
3e5dd6f6e   Geert Uytterhoeven   clk: Ignore disab...
3350
3351
  		if (!of_device_is_available(np))
  			continue;
2e3b19f13   Stephen Boyd   clk: Check for al...
3352
3353
3354
3355
3356
  		parent = kzalloc(sizeof(*parent), GFP_KERNEL);
  		if (!parent) {
  			list_for_each_entry_safe(clk_provider, next,
  						 &clk_provider_list, node) {
  				list_del(&clk_provider->node);
6bc9d9d62   Julia Lawall   clk: add missing ...
3357
  				of_node_put(clk_provider->np);
2e3b19f13   Stephen Boyd   clk: Check for al...
3358
3359
  				kfree(clk_provider);
  			}
6bc9d9d62   Julia Lawall   clk: add missing ...
3360
  			of_node_put(np);
2e3b19f13   Stephen Boyd   clk: Check for al...
3361
3362
  			return;
  		}
1771b10d6   Gregory CLEMENT   clk: respect the ...
3363
3364
  
  		parent->clk_init_cb = match->data;
6bc9d9d62   Julia Lawall   clk: add missing ...
3365
  		parent->np = of_node_get(np);
3f6d439f2   Sylwester Nawrocki   clk: reverse defa...
3366
  		list_add_tail(&parent->node, &clk_provider_list);
1771b10d6   Gregory CLEMENT   clk: respect the ...
3367
3368
3369
3370
3371
3372
3373
  	}
  
  	while (!list_empty(&clk_provider_list)) {
  		is_init_done = false;
  		list_for_each_entry_safe(clk_provider, next,
  					&clk_provider_list, node) {
  			if (force || parent_ready(clk_provider->np)) {
86be408bf   Sylwester Nawrocki   clk: Support for ...
3374

989eafd0b   Ricardo Ribalda Delgado   clk: core: Avoid ...
3375
3376
3377
  				/* Don't populate platform devices */
  				of_node_set_flag(clk_provider->np,
  						 OF_POPULATED);
1771b10d6   Gregory CLEMENT   clk: respect the ...
3378
  				clk_provider->clk_init_cb(clk_provider->np);
86be408bf   Sylwester Nawrocki   clk: Support for ...
3379
  				of_clk_set_defaults(clk_provider->np, true);
1771b10d6   Gregory CLEMENT   clk: respect the ...
3380
  				list_del(&clk_provider->node);
6bc9d9d62   Julia Lawall   clk: add missing ...
3381
  				of_node_put(clk_provider->np);
1771b10d6   Gregory CLEMENT   clk: respect the ...
3382
3383
3384
3385
3386
3387
  				kfree(clk_provider);
  				is_init_done = true;
  			}
  		}
  
  		/*
e5ca8fb4c   Sylwester Nawrocki   clk: Fix minor er...
3388
  		 * We didn't manage to initialize any of the
1771b10d6   Gregory CLEMENT   clk: respect the ...
3389
3390
3391
3392
3393
3394
  		 * remaining providers during the last loop, so now we
  		 * initialize all the remaining ones unconditionally
  		 * in case the clock parent was not mandatory
  		 */
  		if (!is_init_done)
  			force = true;
766e6a4ec   Grant Likely   clk: add DT clock...
3395
3396
3397
  	}
  }
  #endif