diff options
author | Viresh Kumar <viresh.kumar@linaro.org> | 2017-04-26 01:15:46 -0400 |
---|---|---|
committer | Viresh Kumar <viresh.kumar@linaro.org> | 2018-05-09 00:45:18 -0400 |
commit | fa9b274f8aeffb97787b055b8cfbf9062e158551 (patch) | |
tree | 83f39df6994b292ef978ee6d514648d934f93aca /drivers/opp | |
parent | a1e8c13600bfd96c51580732ccf31f69bc6de4d1 (diff) |
PM / OPP: Implement dev_pm_opp_of_add_table_indexed()
The "operating-points-v2" property can contain a list of phandles now,
specifically for the power domain providers that provide multiple
domains.
Add support to parse that.
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
Diffstat (limited to 'drivers/opp')
-rw-r--r-- | drivers/opp/of.c | 50 |
1 files changed, 41 insertions, 9 deletions
diff --git a/drivers/opp/of.c b/drivers/opp/of.c index c5c5afcaa2e3..cba669cd00c5 100644 --- a/drivers/opp/of.c +++ b/drivers/opp/of.c | |||
@@ -250,20 +250,17 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_of_remove_table); | |||
250 | 250 | ||
251 | /* Returns opp descriptor node for a device node, caller must | 251 | /* Returns opp descriptor node for a device node, caller must |
252 | * do of_node_put() */ | 252 | * do of_node_put() */ |
253 | static struct device_node *_opp_of_get_opp_desc_node(struct device_node *np) | 253 | static struct device_node *_opp_of_get_opp_desc_node(struct device_node *np, |
254 | int index) | ||
254 | { | 255 | { |
255 | /* | 256 | /* "operating-points-v2" can be an array for power domain providers */ |
256 | * There should be only ONE phandle present in "operating-points-v2" | 257 | return of_parse_phandle(np, "operating-points-v2", index); |
257 | * property. | ||
258 | */ | ||
259 | |||
260 | return of_parse_phandle(np, "operating-points-v2", 0); | ||
261 | } | 258 | } |
262 | 259 | ||
263 | /* Returns opp descriptor node for a device, caller must do of_node_put() */ | 260 | /* Returns opp descriptor node for a device, caller must do of_node_put() */ |
264 | struct device_node *dev_pm_opp_of_get_opp_desc_node(struct device *dev) | 261 | struct device_node *dev_pm_opp_of_get_opp_desc_node(struct device *dev) |
265 | { | 262 | { |
266 | return _opp_of_get_opp_desc_node(dev->of_node); | 263 | return _opp_of_get_opp_desc_node(dev->of_node, 0); |
267 | } | 264 | } |
268 | EXPORT_SYMBOL_GPL(dev_pm_opp_of_get_opp_desc_node); | 265 | EXPORT_SYMBOL_GPL(dev_pm_opp_of_get_opp_desc_node); |
269 | 266 | ||
@@ -517,6 +514,41 @@ int dev_pm_opp_of_add_table(struct device *dev) | |||
517 | } | 514 | } |
518 | EXPORT_SYMBOL_GPL(dev_pm_opp_of_add_table); | 515 | EXPORT_SYMBOL_GPL(dev_pm_opp_of_add_table); |
519 | 516 | ||
517 | /** | ||
518 | * dev_pm_opp_of_add_table_indexed() - Initialize indexed opp table from device tree | ||
519 | * @dev: device pointer used to lookup OPP table. | ||
520 | * @index: Index number. | ||
521 | * | ||
522 | * Register the initial OPP table with the OPP library for given device only | ||
523 | * using the "operating-points-v2" property. | ||
524 | * | ||
525 | * Return: | ||
526 | * 0 On success OR | ||
527 | * Duplicate OPPs (both freq and volt are same) and opp->available | ||
528 | * -EEXIST Freq are same and volt are different OR | ||
529 | * Duplicate OPPs (both freq and volt are same) and !opp->available | ||
530 | * -ENOMEM Memory allocation failure | ||
531 | * -ENODEV when 'operating-points' property is not found or is invalid data | ||
532 | * in device node. | ||
533 | * -ENODATA when empty 'operating-points' property is found | ||
534 | * -EINVAL when invalid entries are found in opp-v2 table | ||
535 | */ | ||
536 | int dev_pm_opp_of_add_table_indexed(struct device *dev, int index) | ||
537 | { | ||
538 | struct device_node *opp_np; | ||
539 | int ret; | ||
540 | |||
541 | opp_np = _opp_of_get_opp_desc_node(dev->of_node, index); | ||
542 | if (!opp_np) | ||
543 | return -ENODEV; | ||
544 | |||
545 | ret = _of_add_opp_table_v2(dev, opp_np); | ||
546 | of_node_put(opp_np); | ||
547 | |||
548 | return ret; | ||
549 | } | ||
550 | EXPORT_SYMBOL_GPL(dev_pm_opp_of_add_table_indexed); | ||
551 | |||
520 | /* CPU device specific helpers */ | 552 | /* CPU device specific helpers */ |
521 | 553 | ||
522 | /** | 554 | /** |
@@ -621,7 +653,7 @@ int dev_pm_opp_of_get_sharing_cpus(struct device *cpu_dev, | |||
621 | } | 653 | } |
622 | 654 | ||
623 | /* Get OPP descriptor node */ | 655 | /* Get OPP descriptor node */ |
624 | tmp_np = _opp_of_get_opp_desc_node(cpu_np); | 656 | tmp_np = _opp_of_get_opp_desc_node(cpu_np, 0); |
625 | of_node_put(cpu_np); | 657 | of_node_put(cpu_np); |
626 | if (!tmp_np) { | 658 | if (!tmp_np) { |
627 | pr_err("%pOF: Couldn't find opp node\n", cpu_np); | 659 | pr_err("%pOF: Couldn't find opp node\n", cpu_np); |