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