• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Generic OPP OF helpers
3  *
4  * Copyright (C) 2009-2010 Texas Instruments Incorporated.
5  *	Nishanth Menon
6  *	Romit Dasgupta
7  *	Kevin Hilman
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License version 2 as
11  * published by the Free Software Foundation.
12  */
13 
14 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
15 
16 #include <linux/cpu.h>
17 #include <linux/errno.h>
18 #include <linux/device.h>
19 #include <linux/of_device.h>
20 #include <linux/pm_domain.h>
21 #include <linux/slab.h>
22 #include <linux/export.h>
23 
24 #include "opp.h"
25 
_managed_opp(const struct device_node * np)26 static struct opp_table *_managed_opp(const struct device_node *np)
27 {
28 	struct opp_table *opp_table, *managed_table = NULL;
29 
30 	mutex_lock(&opp_table_lock);
31 
32 	list_for_each_entry(opp_table, &opp_tables, node) {
33 		if (opp_table->np == np) {
34 			/*
35 			 * Multiple devices can point to the same OPP table and
36 			 * so will have same node-pointer, np.
37 			 *
38 			 * But the OPPs will be considered as shared only if the
39 			 * OPP table contains a "opp-shared" property.
40 			 */
41 			if (opp_table->shared_opp == OPP_TABLE_ACCESS_SHARED) {
42 				_get_opp_table_kref(opp_table);
43 				managed_table = opp_table;
44 			}
45 
46 			break;
47 		}
48 	}
49 
50 	mutex_unlock(&opp_table_lock);
51 
52 	return managed_table;
53 }
54 
_of_init_opp_table(struct opp_table * opp_table,struct device * dev)55 void _of_init_opp_table(struct opp_table *opp_table, struct device *dev)
56 {
57 	struct device_node *np;
58 
59 	/*
60 	 * Only required for backward compatibility with v1 bindings, but isn't
61 	 * harmful for other cases. And so we do it unconditionally.
62 	 */
63 	np = of_node_get(dev->of_node);
64 	if (np) {
65 		u32 val;
66 
67 		if (!of_property_read_u32(np, "clock-latency", &val))
68 			opp_table->clock_latency_ns_max = val;
69 		of_property_read_u32(np, "voltage-tolerance",
70 				     &opp_table->voltage_tolerance_v1);
71 		of_node_put(np);
72 	}
73 }
74 
_opp_is_supported(struct device * dev,struct opp_table * opp_table,struct device_node * np)75 static bool _opp_is_supported(struct device *dev, struct opp_table *opp_table,
76 			      struct device_node *np)
77 {
78 	unsigned int count = opp_table->supported_hw_count;
79 	u32 version;
80 	int ret;
81 
82 	if (!opp_table->supported_hw) {
83 		/*
84 		 * In the case that no supported_hw has been set by the
85 		 * platform but there is an opp-supported-hw value set for
86 		 * an OPP then the OPP should not be enabled as there is
87 		 * no way to see if the hardware supports it.
88 		 */
89 		if (of_find_property(np, "opp-supported-hw", NULL))
90 			return false;
91 		else
92 			return true;
93 	}
94 
95 	while (count--) {
96 		ret = of_property_read_u32_index(np, "opp-supported-hw", count,
97 						 &version);
98 		if (ret) {
99 			dev_warn(dev, "%s: failed to read opp-supported-hw property at index %d: %d\n",
100 				 __func__, count, ret);
101 			return false;
102 		}
103 
104 		/* Both of these are bitwise masks of the versions */
105 		if (!(version & opp_table->supported_hw[count]))
106 			return false;
107 	}
108 
109 	return true;
110 }
111 
opp_parse_supplies(struct dev_pm_opp * opp,struct device * dev,struct opp_table * opp_table)112 static int opp_parse_supplies(struct dev_pm_opp *opp, struct device *dev,
113 			      struct opp_table *opp_table)
114 {
115 	u32 *microvolt, *microamp = NULL;
116 	int supplies = opp_table->regulator_count, vcount, icount, ret, i, j;
117 	struct property *prop = NULL;
118 	char name[NAME_MAX];
119 
120 	/* Search for "opp-microvolt-<name>" */
121 	if (opp_table->prop_name) {
122 		snprintf(name, sizeof(name), "opp-microvolt-%s",
123 			 opp_table->prop_name);
124 		prop = of_find_property(opp->np, name, NULL);
125 	}
126 
127 	if (!prop) {
128 		/* Search for "opp-microvolt" */
129 		sprintf(name, "opp-microvolt");
130 		prop = of_find_property(opp->np, name, NULL);
131 
132 		/* Missing property isn't a problem, but an invalid entry is */
133 		if (!prop) {
134 			if (unlikely(supplies == -1)) {
135 				/* Initialize regulator_count */
136 				opp_table->regulator_count = 0;
137 				return 0;
138 			}
139 
140 			if (!supplies)
141 				return 0;
142 
143 			dev_err(dev, "%s: opp-microvolt missing although OPP managing regulators\n",
144 				__func__);
145 			return -EINVAL;
146 		}
147 	}
148 
149 	if (unlikely(supplies == -1)) {
150 		/* Initialize regulator_count */
151 		supplies = opp_table->regulator_count = 1;
152 	} else if (unlikely(!supplies)) {
153 		dev_err(dev, "%s: opp-microvolt wasn't expected\n", __func__);
154 		return -EINVAL;
155 	}
156 
157 	vcount = of_property_count_u32_elems(opp->np, name);
158 	if (vcount < 0) {
159 		dev_err(dev, "%s: Invalid %s property (%d)\n",
160 			__func__, name, vcount);
161 		return vcount;
162 	}
163 
164 	/* There can be one or three elements per supply */
165 	if (vcount != supplies && vcount != supplies * 3) {
166 		dev_err(dev, "%s: Invalid number of elements in %s property (%d) with supplies (%d)\n",
167 			__func__, name, vcount, supplies);
168 		return -EINVAL;
169 	}
170 
171 	microvolt = kmalloc_array(vcount, sizeof(*microvolt), GFP_KERNEL);
172 	if (!microvolt)
173 		return -ENOMEM;
174 
175 	ret = of_property_read_u32_array(opp->np, name, microvolt, vcount);
176 	if (ret) {
177 		dev_err(dev, "%s: error parsing %s: %d\n", __func__, name, ret);
178 		ret = -EINVAL;
179 		goto free_microvolt;
180 	}
181 
182 	/* Search for "opp-microamp-<name>" */
183 	prop = NULL;
184 	if (opp_table->prop_name) {
185 		snprintf(name, sizeof(name), "opp-microamp-%s",
186 			 opp_table->prop_name);
187 		prop = of_find_property(opp->np, name, NULL);
188 	}
189 
190 	if (!prop) {
191 		/* Search for "opp-microamp" */
192 		sprintf(name, "opp-microamp");
193 		prop = of_find_property(opp->np, name, NULL);
194 	}
195 
196 	if (prop) {
197 		icount = of_property_count_u32_elems(opp->np, name);
198 		if (icount < 0) {
199 			dev_err(dev, "%s: Invalid %s property (%d)\n", __func__,
200 				name, icount);
201 			ret = icount;
202 			goto free_microvolt;
203 		}
204 
205 		if (icount != supplies) {
206 			dev_err(dev, "%s: Invalid number of elements in %s property (%d) with supplies (%d)\n",
207 				__func__, name, icount, supplies);
208 			ret = -EINVAL;
209 			goto free_microvolt;
210 		}
211 
212 		microamp = kmalloc_array(icount, sizeof(*microamp), GFP_KERNEL);
213 		if (!microamp) {
214 			ret = -EINVAL;
215 			goto free_microvolt;
216 		}
217 
218 		ret = of_property_read_u32_array(opp->np, name, microamp,
219 						 icount);
220 		if (ret) {
221 			dev_err(dev, "%s: error parsing %s: %d\n", __func__,
222 				name, ret);
223 			ret = -EINVAL;
224 			goto free_microamp;
225 		}
226 	}
227 
228 	for (i = 0, j = 0; i < supplies; i++) {
229 		opp->supplies[i].u_volt = microvolt[j++];
230 
231 		if (vcount == supplies) {
232 			opp->supplies[i].u_volt_min = opp->supplies[i].u_volt;
233 			opp->supplies[i].u_volt_max = opp->supplies[i].u_volt;
234 		} else {
235 			opp->supplies[i].u_volt_min = microvolt[j++];
236 			opp->supplies[i].u_volt_max = microvolt[j++];
237 		}
238 
239 		if (microamp)
240 			opp->supplies[i].u_amp = microamp[i];
241 	}
242 
243 free_microamp:
244 	kfree(microamp);
245 free_microvolt:
246 	kfree(microvolt);
247 
248 	return ret;
249 }
250 
251 /**
252  * dev_pm_opp_of_remove_table() - Free OPP table entries created from static DT
253  *				  entries
254  * @dev:	device pointer used to lookup OPP table.
255  *
256  * Free OPPs created using static entries present in DT.
257  */
dev_pm_opp_of_remove_table(struct device * dev)258 void dev_pm_opp_of_remove_table(struct device *dev)
259 {
260 	_dev_pm_opp_find_and_remove_table(dev, false);
261 }
262 EXPORT_SYMBOL_GPL(dev_pm_opp_of_remove_table);
263 
264 /* Returns opp descriptor node for a device node, caller must
265  * do of_node_put() */
_opp_of_get_opp_desc_node(struct device_node * np,int index)266 static struct device_node *_opp_of_get_opp_desc_node(struct device_node *np,
267 						     int index)
268 {
269 	/* "operating-points-v2" can be an array for power domain providers */
270 	return of_parse_phandle(np, "operating-points-v2", index);
271 }
272 
273 /* Returns opp descriptor node for a device, caller must do of_node_put() */
dev_pm_opp_of_get_opp_desc_node(struct device * dev)274 struct device_node *dev_pm_opp_of_get_opp_desc_node(struct device *dev)
275 {
276 	return _opp_of_get_opp_desc_node(dev->of_node, 0);
277 }
278 EXPORT_SYMBOL_GPL(dev_pm_opp_of_get_opp_desc_node);
279 
280 /**
281  * _opp_add_static_v2() - Allocate static OPPs (As per 'v2' DT bindings)
282  * @opp_table:	OPP table
283  * @dev:	device for which we do this operation
284  * @np:		device node
285  *
286  * This function adds an opp definition to the opp table and returns status. The
287  * opp can be controlled using dev_pm_opp_enable/disable functions and may be
288  * removed by dev_pm_opp_remove.
289  *
290  * Return:
291  * 0		On success OR
292  *		Duplicate OPPs (both freq and volt are same) and opp->available
293  * -EEXIST	Freq are same and volt are different OR
294  *		Duplicate OPPs (both freq and volt are same) and !opp->available
295  * -ENOMEM	Memory allocation failure
296  * -EINVAL	Failed parsing the OPP node
297  */
_opp_add_static_v2(struct opp_table * opp_table,struct device * dev,struct device_node * np)298 static int _opp_add_static_v2(struct opp_table *opp_table, struct device *dev,
299 			      struct device_node *np)
300 {
301 	struct dev_pm_opp *new_opp;
302 	u64 rate = 0;
303 	u32 val;
304 	int ret;
305 	bool rate_not_available = false;
306 
307 	new_opp = _opp_allocate(opp_table);
308 	if (!new_opp)
309 		return -ENOMEM;
310 
311 	ret = of_property_read_u64(np, "opp-hz", &rate);
312 	if (ret < 0) {
313 		/* "opp-hz" is optional for devices like power domains. */
314 		if (!of_find_property(dev->of_node, "#power-domain-cells",
315 				      NULL)) {
316 			dev_err(dev, "%s: opp-hz not found\n", __func__);
317 			goto free_opp;
318 		}
319 
320 		rate_not_available = true;
321 	} else {
322 		/*
323 		 * Rate is defined as an unsigned long in clk API, and so
324 		 * casting explicitly to its type. Must be fixed once rate is 64
325 		 * bit guaranteed in clk API.
326 		 */
327 		new_opp->rate = (unsigned long)rate;
328 	}
329 
330 	/* Check if the OPP supports hardware's hierarchy of versions or not */
331 	if (!_opp_is_supported(dev, opp_table, np)) {
332 		dev_dbg(dev, "OPP not supported by hardware: %llu\n", rate);
333 		goto free_opp;
334 	}
335 
336 	new_opp->turbo = of_property_read_bool(np, "turbo-mode");
337 
338 	new_opp->np = np;
339 	new_opp->dynamic = false;
340 	new_opp->available = true;
341 
342 	if (!of_property_read_u32(np, "clock-latency-ns", &val))
343 		new_opp->clock_latency_ns = val;
344 
345 	new_opp->pstate = of_genpd_opp_to_performance_state(dev, np);
346 
347 	ret = opp_parse_supplies(new_opp, dev, opp_table);
348 	if (ret)
349 		goto free_opp;
350 
351 	ret = _opp_add(dev, new_opp, opp_table, rate_not_available);
352 	if (ret) {
353 		/* Don't return error for duplicate OPPs */
354 		if (ret == -EBUSY)
355 			ret = 0;
356 		goto free_opp;
357 	}
358 
359 	/* OPP to select on device suspend */
360 	if (of_property_read_bool(np, "opp-suspend")) {
361 		if (opp_table->suspend_opp) {
362 			dev_warn(dev, "%s: Multiple suspend OPPs found (%lu %lu)\n",
363 				 __func__, opp_table->suspend_opp->rate,
364 				 new_opp->rate);
365 		} else {
366 			new_opp->suspend = true;
367 			opp_table->suspend_opp = new_opp;
368 		}
369 	}
370 
371 	if (new_opp->clock_latency_ns > opp_table->clock_latency_ns_max)
372 		opp_table->clock_latency_ns_max = new_opp->clock_latency_ns;
373 
374 	pr_debug("%s: turbo:%d rate:%lu uv:%lu uvmin:%lu uvmax:%lu latency:%lu\n",
375 		 __func__, new_opp->turbo, new_opp->rate,
376 		 new_opp->supplies[0].u_volt, new_opp->supplies[0].u_volt_min,
377 		 new_opp->supplies[0].u_volt_max, new_opp->clock_latency_ns);
378 
379 	/*
380 	 * Notify the changes in the availability of the operable
381 	 * frequency/voltage list.
382 	 */
383 	blocking_notifier_call_chain(&opp_table->head, OPP_EVENT_ADD, new_opp);
384 	return 0;
385 
386 free_opp:
387 	_opp_free(new_opp);
388 
389 	return ret;
390 }
391 
392 /* Initializes OPP tables based on new bindings */
_of_add_opp_table_v2(struct device * dev,struct device_node * opp_np)393 static int _of_add_opp_table_v2(struct device *dev, struct device_node *opp_np)
394 {
395 	struct device_node *np;
396 	struct opp_table *opp_table;
397 	int ret = 0, count = 0, pstate_count = 0;
398 	struct dev_pm_opp *opp;
399 
400 	opp_table = _managed_opp(opp_np);
401 	if (opp_table) {
402 		/* OPPs are already managed */
403 		if (!_add_opp_dev(dev, opp_table))
404 			ret = -ENOMEM;
405 		goto put_opp_table;
406 	}
407 
408 	opp_table = dev_pm_opp_get_opp_table(dev);
409 	if (!opp_table)
410 		return -ENOMEM;
411 
412 	/* We have opp-table node now, iterate over it and add OPPs */
413 	for_each_available_child_of_node(opp_np, np) {
414 		count++;
415 
416 		ret = _opp_add_static_v2(opp_table, dev, np);
417 		if (ret) {
418 			dev_err(dev, "%s: Failed to add OPP, %d\n", __func__,
419 				ret);
420 			_dev_pm_opp_remove_table(opp_table, dev, false);
421 			of_node_put(np);
422 			goto put_opp_table;
423 		}
424 	}
425 
426 	/* There should be one of more OPP defined */
427 	if (WARN_ON(!count)) {
428 		ret = -ENOENT;
429 		goto put_opp_table;
430 	}
431 
432 	list_for_each_entry(opp, &opp_table->opp_list, node)
433 		pstate_count += !!opp->pstate;
434 
435 	/* Either all or none of the nodes shall have performance state set */
436 	if (pstate_count && pstate_count != count) {
437 		dev_err(dev, "Not all nodes have performance state set (%d: %d)\n",
438 			count, pstate_count);
439 		ret = -ENOENT;
440 		_dev_pm_opp_remove_table(opp_table, dev, false);
441 		goto put_opp_table;
442 	}
443 
444 	if (pstate_count)
445 		opp_table->genpd_performance_state = true;
446 
447 	opp_table->np = opp_np;
448 	if (of_property_read_bool(opp_np, "opp-shared"))
449 		opp_table->shared_opp = OPP_TABLE_ACCESS_SHARED;
450 	else
451 		opp_table->shared_opp = OPP_TABLE_ACCESS_EXCLUSIVE;
452 
453 put_opp_table:
454 	dev_pm_opp_put_opp_table(opp_table);
455 
456 	return ret;
457 }
458 
459 /* Initializes OPP tables based on old-deprecated bindings */
_of_add_opp_table_v1(struct device * dev)460 static int _of_add_opp_table_v1(struct device *dev)
461 {
462 	struct opp_table *opp_table;
463 	const struct property *prop;
464 	const __be32 *val;
465 	int nr, ret = 0;
466 
467 	prop = of_find_property(dev->of_node, "operating-points", NULL);
468 	if (!prop)
469 		return -ENODEV;
470 	if (!prop->value)
471 		return -ENODATA;
472 
473 	/*
474 	 * Each OPP is a set of tuples consisting of frequency and
475 	 * voltage like <freq-kHz vol-uV>.
476 	 */
477 	nr = prop->length / sizeof(u32);
478 	if (nr % 2) {
479 		dev_err(dev, "%s: Invalid OPP table\n", __func__);
480 		return -EINVAL;
481 	}
482 
483 	opp_table = dev_pm_opp_get_opp_table(dev);
484 	if (!opp_table)
485 		return -ENOMEM;
486 
487 	val = prop->value;
488 	while (nr) {
489 		unsigned long freq = be32_to_cpup(val++) * 1000;
490 		unsigned long volt = be32_to_cpup(val++);
491 
492 		ret = _opp_add_v1(opp_table, dev, freq, volt, false);
493 		if (ret) {
494 			dev_err(dev, "%s: Failed to add OPP %ld (%d)\n",
495 				__func__, freq, ret);
496 			_dev_pm_opp_remove_table(opp_table, dev, false);
497 			break;
498 		}
499 		nr -= 2;
500 	}
501 
502 	dev_pm_opp_put_opp_table(opp_table);
503 	return ret;
504 }
505 
506 /**
507  * dev_pm_opp_of_add_table() - Initialize opp table from device tree
508  * @dev:	device pointer used to lookup OPP table.
509  *
510  * Register the initial OPP table with the OPP library for given device.
511  *
512  * Return:
513  * 0		On success OR
514  *		Duplicate OPPs (both freq and volt are same) and opp->available
515  * -EEXIST	Freq are same and volt are different OR
516  *		Duplicate OPPs (both freq and volt are same) and !opp->available
517  * -ENOMEM	Memory allocation failure
518  * -ENODEV	when 'operating-points' property is not found or is invalid data
519  *		in device node.
520  * -ENODATA	when empty 'operating-points' property is found
521  * -EINVAL	when invalid entries are found in opp-v2 table
522  */
dev_pm_opp_of_add_table(struct device * dev)523 int dev_pm_opp_of_add_table(struct device *dev)
524 {
525 	struct device_node *opp_np;
526 	int ret;
527 
528 	/*
529 	 * OPPs have two version of bindings now. The older one is deprecated,
530 	 * try for the new binding first.
531 	 */
532 	opp_np = dev_pm_opp_of_get_opp_desc_node(dev);
533 	if (!opp_np) {
534 		/*
535 		 * Try old-deprecated bindings for backward compatibility with
536 		 * older dtbs.
537 		 */
538 		return _of_add_opp_table_v1(dev);
539 	}
540 
541 	ret = _of_add_opp_table_v2(dev, opp_np);
542 	of_node_put(opp_np);
543 
544 	return ret;
545 }
546 EXPORT_SYMBOL_GPL(dev_pm_opp_of_add_table);
547 
548 /**
549  * dev_pm_opp_of_add_table_indexed() - Initialize indexed opp table from device tree
550  * @dev:	device pointer used to lookup OPP table.
551  * @index:	Index number.
552  *
553  * Register the initial OPP table with the OPP library for given device only
554  * using the "operating-points-v2" property.
555  *
556  * Return:
557  * 0		On success OR
558  *		Duplicate OPPs (both freq and volt are same) and opp->available
559  * -EEXIST	Freq are same and volt are different OR
560  *		Duplicate OPPs (both freq and volt are same) and !opp->available
561  * -ENOMEM	Memory allocation failure
562  * -ENODEV	when 'operating-points' property is not found or is invalid data
563  *		in device node.
564  * -ENODATA	when empty 'operating-points' property is found
565  * -EINVAL	when invalid entries are found in opp-v2 table
566  */
dev_pm_opp_of_add_table_indexed(struct device * dev,int index)567 int dev_pm_opp_of_add_table_indexed(struct device *dev, int index)
568 {
569 	struct device_node *opp_np;
570 	int ret, count;
571 
572 again:
573 	opp_np = _opp_of_get_opp_desc_node(dev->of_node, index);
574 	if (!opp_np) {
575 		/*
576 		 * If only one phandle is present, then the same OPP table
577 		 * applies for all index requests.
578 		 */
579 		count = of_count_phandle_with_args(dev->of_node,
580 						   "operating-points-v2", NULL);
581 		if (count == 1 && index) {
582 			index = 0;
583 			goto again;
584 		}
585 
586 		return -ENODEV;
587 	}
588 
589 	ret = _of_add_opp_table_v2(dev, opp_np);
590 	of_node_put(opp_np);
591 
592 	return ret;
593 }
594 EXPORT_SYMBOL_GPL(dev_pm_opp_of_add_table_indexed);
595 
596 /* CPU device specific helpers */
597 
598 /**
599  * dev_pm_opp_of_cpumask_remove_table() - Removes OPP table for @cpumask
600  * @cpumask:	cpumask for which OPP table needs to be removed
601  *
602  * This removes the OPP tables for CPUs present in the @cpumask.
603  * This should be used only to remove static entries created from DT.
604  */
dev_pm_opp_of_cpumask_remove_table(const struct cpumask * cpumask)605 void dev_pm_opp_of_cpumask_remove_table(const struct cpumask *cpumask)
606 {
607 	_dev_pm_opp_cpumask_remove_table(cpumask, true);
608 }
609 EXPORT_SYMBOL_GPL(dev_pm_opp_of_cpumask_remove_table);
610 
611 /**
612  * dev_pm_opp_of_cpumask_add_table() - Adds OPP table for @cpumask
613  * @cpumask:	cpumask for which OPP table needs to be added.
614  *
615  * This adds the OPP tables for CPUs present in the @cpumask.
616  */
dev_pm_opp_of_cpumask_add_table(const struct cpumask * cpumask)617 int dev_pm_opp_of_cpumask_add_table(const struct cpumask *cpumask)
618 {
619 	struct device *cpu_dev;
620 	int cpu, ret = 0;
621 
622 	WARN_ON(cpumask_empty(cpumask));
623 
624 	for_each_cpu(cpu, cpumask) {
625 		cpu_dev = get_cpu_device(cpu);
626 		if (!cpu_dev) {
627 			pr_err("%s: failed to get cpu%d device\n", __func__,
628 			       cpu);
629 			continue;
630 		}
631 
632 		ret = dev_pm_opp_of_add_table(cpu_dev);
633 		if (ret) {
634 			/*
635 			 * OPP may get registered dynamically, don't print error
636 			 * message here.
637 			 */
638 			pr_debug("%s: couldn't find opp table for cpu:%d, %d\n",
639 				 __func__, cpu, ret);
640 
641 			/* Free all other OPPs */
642 			dev_pm_opp_of_cpumask_remove_table(cpumask);
643 			break;
644 		}
645 	}
646 
647 	return ret;
648 }
649 EXPORT_SYMBOL_GPL(dev_pm_opp_of_cpumask_add_table);
650 
651 /*
652  * Works only for OPP v2 bindings.
653  *
654  * Returns -ENOENT if operating-points-v2 bindings aren't supported.
655  */
656 /**
657  * dev_pm_opp_of_get_sharing_cpus() - Get cpumask of CPUs sharing OPPs with
658  *				      @cpu_dev using operating-points-v2
659  *				      bindings.
660  *
661  * @cpu_dev:	CPU device for which we do this operation
662  * @cpumask:	cpumask to update with information of sharing CPUs
663  *
664  * This updates the @cpumask with CPUs that are sharing OPPs with @cpu_dev.
665  *
666  * Returns -ENOENT if operating-points-v2 isn't present for @cpu_dev.
667  */
dev_pm_opp_of_get_sharing_cpus(struct device * cpu_dev,struct cpumask * cpumask)668 int dev_pm_opp_of_get_sharing_cpus(struct device *cpu_dev,
669 				   struct cpumask *cpumask)
670 {
671 	struct device_node *np, *tmp_np, *cpu_np;
672 	int cpu, ret = 0;
673 
674 	/* Get OPP descriptor node */
675 	np = dev_pm_opp_of_get_opp_desc_node(cpu_dev);
676 	if (!np) {
677 		dev_dbg(cpu_dev, "%s: Couldn't find opp node.\n", __func__);
678 		return -ENOENT;
679 	}
680 
681 	cpumask_set_cpu(cpu_dev->id, cpumask);
682 
683 	/* OPPs are shared ? */
684 	if (!of_property_read_bool(np, "opp-shared"))
685 		goto put_cpu_node;
686 
687 	for_each_possible_cpu(cpu) {
688 		if (cpu == cpu_dev->id)
689 			continue;
690 
691 		cpu_np = of_cpu_device_node_get(cpu);
692 		if (!cpu_np) {
693 			dev_err(cpu_dev, "%s: failed to get cpu%d node\n",
694 				__func__, cpu);
695 			ret = -ENOENT;
696 			goto put_cpu_node;
697 		}
698 
699 		/* Get OPP descriptor node */
700 		tmp_np = _opp_of_get_opp_desc_node(cpu_np, 0);
701 		of_node_put(cpu_np);
702 		if (!tmp_np) {
703 			pr_err("%pOF: Couldn't find opp node\n", cpu_np);
704 			ret = -ENOENT;
705 			goto put_cpu_node;
706 		}
707 
708 		/* CPUs are sharing opp node */
709 		if (np == tmp_np)
710 			cpumask_set_cpu(cpu, cpumask);
711 
712 		of_node_put(tmp_np);
713 	}
714 
715 put_cpu_node:
716 	of_node_put(np);
717 	return ret;
718 }
719 EXPORT_SYMBOL_GPL(dev_pm_opp_of_get_sharing_cpus);
720 
721 /**
722  * of_dev_pm_opp_find_required_opp() - Search for required OPP.
723  * @dev: The device whose OPP node is referenced by the 'np' DT node.
724  * @np: Node that contains the "required-opps" property.
725  *
726  * Returns the OPP of the device 'dev', whose phandle is present in the "np"
727  * node. Although the "required-opps" property supports having multiple
728  * phandles, this helper routine only parses the very first phandle in the list.
729  *
730  * Return: Matching opp, else returns ERR_PTR in case of error and should be
731  * handled using IS_ERR.
732  *
733  * The callers are required to call dev_pm_opp_put() for the returned OPP after
734  * use.
735  */
of_dev_pm_opp_find_required_opp(struct device * dev,struct device_node * np)736 struct dev_pm_opp *of_dev_pm_opp_find_required_opp(struct device *dev,
737 						   struct device_node *np)
738 {
739 	struct dev_pm_opp *temp_opp, *opp = ERR_PTR(-ENODEV);
740 	struct device_node *required_np;
741 	struct opp_table *opp_table;
742 
743 	opp_table = _find_opp_table(dev);
744 	if (IS_ERR(opp_table))
745 		return ERR_CAST(opp_table);
746 
747 	required_np = of_parse_phandle(np, "required-opps", 0);
748 	if (unlikely(!required_np)) {
749 		dev_err(dev, "Unable to parse required-opps\n");
750 		goto put_opp_table;
751 	}
752 
753 	mutex_lock(&opp_table->lock);
754 
755 	list_for_each_entry(temp_opp, &opp_table->opp_list, node) {
756 		if (temp_opp->available && temp_opp->np == required_np) {
757 			opp = temp_opp;
758 
759 			/* Increment the reference count of OPP */
760 			dev_pm_opp_get(opp);
761 			break;
762 		}
763 	}
764 
765 	mutex_unlock(&opp_table->lock);
766 
767 	of_node_put(required_np);
768 put_opp_table:
769 	dev_pm_opp_put_opp_table(opp_table);
770 
771 	return opp;
772 }
773 EXPORT_SYMBOL_GPL(of_dev_pm_opp_find_required_opp);
774 
775 /**
776  * dev_pm_opp_get_of_node() - Gets the DT node corresponding to an opp
777  * @opp:	opp for which DT node has to be returned for
778  *
779  * Return: DT node corresponding to the opp, else 0 on success.
780  *
781  * The caller needs to put the node with of_node_put() after using it.
782  */
dev_pm_opp_get_of_node(struct dev_pm_opp * opp)783 struct device_node *dev_pm_opp_get_of_node(struct dev_pm_opp *opp)
784 {
785 	if (IS_ERR_OR_NULL(opp)) {
786 		pr_err("%s: Invalid parameters\n", __func__);
787 		return NULL;
788 	}
789 
790 	return of_node_get(opp->np);
791 }
792 EXPORT_SYMBOL_GPL(dev_pm_opp_get_of_node);
793