Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v4.10 652 lines 18 kB view raw
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.h> 20#include <linux/slab.h> 21#include <linux/export.h> 22 23#include "opp.h" 24 25static struct opp_table *_managed_opp(const struct device_node *np) 26{ 27 struct opp_table *opp_table; 28 29 list_for_each_entry_rcu(opp_table, &opp_tables, node) { 30 if (opp_table->np == np) { 31 /* 32 * Multiple devices can point to the same OPP table and 33 * so will have same node-pointer, np. 34 * 35 * But the OPPs will be considered as shared only if the 36 * OPP table contains a "opp-shared" property. 37 */ 38 if (opp_table->shared_opp == OPP_TABLE_ACCESS_SHARED) 39 return opp_table; 40 41 return NULL; 42 } 43 } 44 45 return NULL; 46} 47 48void _of_init_opp_table(struct opp_table *opp_table, struct device *dev) 49{ 50 struct device_node *np; 51 52 /* 53 * Only required for backward compatibility with v1 bindings, but isn't 54 * harmful for other cases. And so we do it unconditionally. 55 */ 56 np = of_node_get(dev->of_node); 57 if (np) { 58 u32 val; 59 60 if (!of_property_read_u32(np, "clock-latency", &val)) 61 opp_table->clock_latency_ns_max = val; 62 of_property_read_u32(np, "voltage-tolerance", 63 &opp_table->voltage_tolerance_v1); 64 of_node_put(np); 65 } 66} 67 68static bool _opp_is_supported(struct device *dev, struct opp_table *opp_table, 69 struct device_node *np) 70{ 71 unsigned int count = opp_table->supported_hw_count; 72 u32 version; 73 int ret; 74 75 if (!opp_table->supported_hw) { 76 /* 77 * In the case that no supported_hw has been set by the 78 * platform but there is an opp-supported-hw value set for 79 * an OPP then the OPP should not be enabled as there is 80 * no way to see if the hardware supports it. 81 */ 82 if (of_find_property(np, "opp-supported-hw", NULL)) 83 return false; 84 else 85 return true; 86 } 87 88 while (count--) { 89 ret = of_property_read_u32_index(np, "opp-supported-hw", count, 90 &version); 91 if (ret) { 92 dev_warn(dev, "%s: failed to read opp-supported-hw property at index %d: %d\n", 93 __func__, count, ret); 94 return false; 95 } 96 97 /* Both of these are bitwise masks of the versions */ 98 if (!(version & opp_table->supported_hw[count])) 99 return false; 100 } 101 102 return true; 103} 104 105static int opp_parse_supplies(struct dev_pm_opp *opp, struct device *dev, 106 struct opp_table *opp_table) 107{ 108 u32 *microvolt, *microamp = NULL; 109 int supplies, vcount, icount, ret, i, j; 110 struct property *prop = NULL; 111 char name[NAME_MAX]; 112 113 supplies = opp_table->regulator_count ? opp_table->regulator_count : 1; 114 115 /* Search for "opp-microvolt-<name>" */ 116 if (opp_table->prop_name) { 117 snprintf(name, sizeof(name), "opp-microvolt-%s", 118 opp_table->prop_name); 119 prop = of_find_property(opp->np, name, NULL); 120 } 121 122 if (!prop) { 123 /* Search for "opp-microvolt" */ 124 sprintf(name, "opp-microvolt"); 125 prop = of_find_property(opp->np, name, NULL); 126 127 /* Missing property isn't a problem, but an invalid entry is */ 128 if (!prop) 129 return 0; 130 } 131 132 vcount = of_property_count_u32_elems(opp->np, name); 133 if (vcount < 0) { 134 dev_err(dev, "%s: Invalid %s property (%d)\n", 135 __func__, name, vcount); 136 return vcount; 137 } 138 139 /* There can be one or three elements per supply */ 140 if (vcount != supplies && vcount != supplies * 3) { 141 dev_err(dev, "%s: Invalid number of elements in %s property (%d) with supplies (%d)\n", 142 __func__, name, vcount, supplies); 143 return -EINVAL; 144 } 145 146 microvolt = kmalloc_array(vcount, sizeof(*microvolt), GFP_KERNEL); 147 if (!microvolt) 148 return -ENOMEM; 149 150 ret = of_property_read_u32_array(opp->np, name, microvolt, vcount); 151 if (ret) { 152 dev_err(dev, "%s: error parsing %s: %d\n", __func__, name, ret); 153 ret = -EINVAL; 154 goto free_microvolt; 155 } 156 157 /* Search for "opp-microamp-<name>" */ 158 prop = NULL; 159 if (opp_table->prop_name) { 160 snprintf(name, sizeof(name), "opp-microamp-%s", 161 opp_table->prop_name); 162 prop = of_find_property(opp->np, name, NULL); 163 } 164 165 if (!prop) { 166 /* Search for "opp-microamp" */ 167 sprintf(name, "opp-microamp"); 168 prop = of_find_property(opp->np, name, NULL); 169 } 170 171 if (prop) { 172 icount = of_property_count_u32_elems(opp->np, name); 173 if (icount < 0) { 174 dev_err(dev, "%s: Invalid %s property (%d)\n", __func__, 175 name, icount); 176 ret = icount; 177 goto free_microvolt; 178 } 179 180 if (icount != supplies) { 181 dev_err(dev, "%s: Invalid number of elements in %s property (%d) with supplies (%d)\n", 182 __func__, name, icount, supplies); 183 ret = -EINVAL; 184 goto free_microvolt; 185 } 186 187 microamp = kmalloc_array(icount, sizeof(*microamp), GFP_KERNEL); 188 if (!microamp) { 189 ret = -EINVAL; 190 goto free_microvolt; 191 } 192 193 ret = of_property_read_u32_array(opp->np, name, microamp, 194 icount); 195 if (ret) { 196 dev_err(dev, "%s: error parsing %s: %d\n", __func__, 197 name, ret); 198 ret = -EINVAL; 199 goto free_microamp; 200 } 201 } 202 203 for (i = 0, j = 0; i < supplies; i++) { 204 opp->supplies[i].u_volt = microvolt[j++]; 205 206 if (vcount == supplies) { 207 opp->supplies[i].u_volt_min = opp->supplies[i].u_volt; 208 opp->supplies[i].u_volt_max = opp->supplies[i].u_volt; 209 } else { 210 opp->supplies[i].u_volt_min = microvolt[j++]; 211 opp->supplies[i].u_volt_max = microvolt[j++]; 212 } 213 214 if (microamp) 215 opp->supplies[i].u_amp = microamp[i]; 216 } 217 218free_microamp: 219 kfree(microamp); 220free_microvolt: 221 kfree(microvolt); 222 223 return ret; 224} 225 226/** 227 * dev_pm_opp_of_remove_table() - Free OPP table entries created from static DT 228 * entries 229 * @dev: device pointer used to lookup OPP table. 230 * 231 * Free OPPs created using static entries present in DT. 232 * 233 * Locking: The internal opp_table and opp structures are RCU protected. 234 * Hence this function indirectly uses RCU updater strategy with mutex locks 235 * to keep the integrity of the internal data structures. Callers should ensure 236 * that this function is *NOT* called under RCU protection or in contexts where 237 * mutex cannot be locked. 238 */ 239void dev_pm_opp_of_remove_table(struct device *dev) 240{ 241 _dev_pm_opp_remove_table(dev, false); 242} 243EXPORT_SYMBOL_GPL(dev_pm_opp_of_remove_table); 244 245/* Returns opp descriptor node for a device, caller must do of_node_put() */ 246static struct device_node *_of_get_opp_desc_node(struct device *dev) 247{ 248 /* 249 * TODO: Support for multiple OPP tables. 250 * 251 * There should be only ONE phandle present in "operating-points-v2" 252 * property. 253 */ 254 255 return of_parse_phandle(dev->of_node, "operating-points-v2", 0); 256} 257 258/** 259 * _opp_add_static_v2() - Allocate static OPPs (As per 'v2' DT bindings) 260 * @dev: device for which we do this operation 261 * @np: device node 262 * 263 * This function adds an opp definition to the opp table and returns status. The 264 * opp can be controlled using dev_pm_opp_enable/disable functions and may be 265 * removed by dev_pm_opp_remove. 266 * 267 * Locking: The internal opp_table and opp structures are RCU protected. 268 * Hence this function internally uses RCU updater strategy with mutex locks 269 * to keep the integrity of the internal data structures. Callers should ensure 270 * that this function is *NOT* called under RCU protection or in contexts where 271 * mutex cannot be locked. 272 * 273 * Return: 274 * 0 On success OR 275 * Duplicate OPPs (both freq and volt are same) and opp->available 276 * -EEXIST Freq are same and volt are different OR 277 * Duplicate OPPs (both freq and volt are same) and !opp->available 278 * -ENOMEM Memory allocation failure 279 * -EINVAL Failed parsing the OPP node 280 */ 281static int _opp_add_static_v2(struct device *dev, struct device_node *np) 282{ 283 struct opp_table *opp_table; 284 struct dev_pm_opp *new_opp; 285 u64 rate; 286 u32 val; 287 int ret; 288 289 /* Hold our table modification lock here */ 290 mutex_lock(&opp_table_lock); 291 292 new_opp = _allocate_opp(dev, &opp_table); 293 if (!new_opp) { 294 ret = -ENOMEM; 295 goto unlock; 296 } 297 298 ret = of_property_read_u64(np, "opp-hz", &rate); 299 if (ret < 0) { 300 dev_err(dev, "%s: opp-hz not found\n", __func__); 301 goto free_opp; 302 } 303 304 /* Check if the OPP supports hardware's hierarchy of versions or not */ 305 if (!_opp_is_supported(dev, opp_table, np)) { 306 dev_dbg(dev, "OPP not supported by hardware: %llu\n", rate); 307 goto free_opp; 308 } 309 310 /* 311 * Rate is defined as an unsigned long in clk API, and so casting 312 * explicitly to its type. Must be fixed once rate is 64 bit 313 * guaranteed in clk API. 314 */ 315 new_opp->rate = (unsigned long)rate; 316 new_opp->turbo = of_property_read_bool(np, "turbo-mode"); 317 318 new_opp->np = np; 319 new_opp->dynamic = false; 320 new_opp->available = true; 321 322 if (!of_property_read_u32(np, "clock-latency-ns", &val)) 323 new_opp->clock_latency_ns = val; 324 325 ret = opp_parse_supplies(new_opp, dev, opp_table); 326 if (ret) 327 goto free_opp; 328 329 ret = _opp_add(dev, new_opp, opp_table); 330 if (ret) 331 goto free_opp; 332 333 /* OPP to select on device suspend */ 334 if (of_property_read_bool(np, "opp-suspend")) { 335 if (opp_table->suspend_opp) { 336 dev_warn(dev, "%s: Multiple suspend OPPs found (%lu %lu)\n", 337 __func__, opp_table->suspend_opp->rate, 338 new_opp->rate); 339 } else { 340 new_opp->suspend = true; 341 opp_table->suspend_opp = new_opp; 342 } 343 } 344 345 if (new_opp->clock_latency_ns > opp_table->clock_latency_ns_max) 346 opp_table->clock_latency_ns_max = new_opp->clock_latency_ns; 347 348 mutex_unlock(&opp_table_lock); 349 350 pr_debug("%s: turbo:%d rate:%lu uv:%lu uvmin:%lu uvmax:%lu latency:%lu\n", 351 __func__, new_opp->turbo, new_opp->rate, 352 new_opp->supplies[0].u_volt, new_opp->supplies[0].u_volt_min, 353 new_opp->supplies[0].u_volt_max, new_opp->clock_latency_ns); 354 355 /* 356 * Notify the changes in the availability of the operable 357 * frequency/voltage list. 358 */ 359 srcu_notifier_call_chain(&opp_table->srcu_head, OPP_EVENT_ADD, new_opp); 360 return 0; 361 362free_opp: 363 _opp_remove(opp_table, new_opp, false); 364unlock: 365 mutex_unlock(&opp_table_lock); 366 return ret; 367} 368 369/* Initializes OPP tables based on new bindings */ 370static int _of_add_opp_table_v2(struct device *dev, struct device_node *opp_np) 371{ 372 struct device_node *np; 373 struct opp_table *opp_table; 374 int ret = 0, count = 0; 375 376 mutex_lock(&opp_table_lock); 377 378 opp_table = _managed_opp(opp_np); 379 if (opp_table) { 380 /* OPPs are already managed */ 381 if (!_add_opp_dev(dev, opp_table)) 382 ret = -ENOMEM; 383 mutex_unlock(&opp_table_lock); 384 return ret; 385 } 386 mutex_unlock(&opp_table_lock); 387 388 /* We have opp-table node now, iterate over it and add OPPs */ 389 for_each_available_child_of_node(opp_np, np) { 390 count++; 391 392 ret = _opp_add_static_v2(dev, np); 393 if (ret) { 394 dev_err(dev, "%s: Failed to add OPP, %d\n", __func__, 395 ret); 396 goto free_table; 397 } 398 } 399 400 /* There should be one of more OPP defined */ 401 if (WARN_ON(!count)) 402 return -ENOENT; 403 404 mutex_lock(&opp_table_lock); 405 406 opp_table = _find_opp_table(dev); 407 if (WARN_ON(IS_ERR(opp_table))) { 408 ret = PTR_ERR(opp_table); 409 mutex_unlock(&opp_table_lock); 410 goto free_table; 411 } 412 413 opp_table->np = opp_np; 414 if (of_property_read_bool(opp_np, "opp-shared")) 415 opp_table->shared_opp = OPP_TABLE_ACCESS_SHARED; 416 else 417 opp_table->shared_opp = OPP_TABLE_ACCESS_EXCLUSIVE; 418 419 mutex_unlock(&opp_table_lock); 420 421 return 0; 422 423free_table: 424 dev_pm_opp_of_remove_table(dev); 425 426 return ret; 427} 428 429/* Initializes OPP tables based on old-deprecated bindings */ 430static int _of_add_opp_table_v1(struct device *dev) 431{ 432 const struct property *prop; 433 const __be32 *val; 434 int nr; 435 436 prop = of_find_property(dev->of_node, "operating-points", NULL); 437 if (!prop) 438 return -ENODEV; 439 if (!prop->value) 440 return -ENODATA; 441 442 /* 443 * Each OPP is a set of tuples consisting of frequency and 444 * voltage like <freq-kHz vol-uV>. 445 */ 446 nr = prop->length / sizeof(u32); 447 if (nr % 2) { 448 dev_err(dev, "%s: Invalid OPP table\n", __func__); 449 return -EINVAL; 450 } 451 452 val = prop->value; 453 while (nr) { 454 unsigned long freq = be32_to_cpup(val++) * 1000; 455 unsigned long volt = be32_to_cpup(val++); 456 457 if (_opp_add_v1(dev, freq, volt, false)) 458 dev_warn(dev, "%s: Failed to add OPP %ld\n", 459 __func__, freq); 460 nr -= 2; 461 } 462 463 return 0; 464} 465 466/** 467 * dev_pm_opp_of_add_table() - Initialize opp table from device tree 468 * @dev: device pointer used to lookup OPP table. 469 * 470 * Register the initial OPP table with the OPP library for given device. 471 * 472 * Locking: The internal opp_table and opp structures are RCU protected. 473 * Hence this function indirectly uses RCU updater strategy with mutex locks 474 * to keep the integrity of the internal data structures. Callers should ensure 475 * that this function is *NOT* called under RCU protection or in contexts where 476 * mutex cannot be locked. 477 * 478 * Return: 479 * 0 On success OR 480 * Duplicate OPPs (both freq and volt are same) and opp->available 481 * -EEXIST Freq are same and volt are different OR 482 * Duplicate OPPs (both freq and volt are same) and !opp->available 483 * -ENOMEM Memory allocation failure 484 * -ENODEV when 'operating-points' property is not found or is invalid data 485 * in device node. 486 * -ENODATA when empty 'operating-points' property is found 487 * -EINVAL when invalid entries are found in opp-v2 table 488 */ 489int dev_pm_opp_of_add_table(struct device *dev) 490{ 491 struct device_node *opp_np; 492 int ret; 493 494 /* 495 * OPPs have two version of bindings now. The older one is deprecated, 496 * try for the new binding first. 497 */ 498 opp_np = _of_get_opp_desc_node(dev); 499 if (!opp_np) { 500 /* 501 * Try old-deprecated bindings for backward compatibility with 502 * older dtbs. 503 */ 504 return _of_add_opp_table_v1(dev); 505 } 506 507 ret = _of_add_opp_table_v2(dev, opp_np); 508 of_node_put(opp_np); 509 510 return ret; 511} 512EXPORT_SYMBOL_GPL(dev_pm_opp_of_add_table); 513 514/* CPU device specific helpers */ 515 516/** 517 * dev_pm_opp_of_cpumask_remove_table() - Removes OPP table for @cpumask 518 * @cpumask: cpumask for which OPP table needs to be removed 519 * 520 * This removes the OPP tables for CPUs present in the @cpumask. 521 * This should be used only to remove static entries created from DT. 522 * 523 * Locking: The internal opp_table and opp structures are RCU protected. 524 * Hence this function internally uses RCU updater strategy with mutex locks 525 * to keep the integrity of the internal data structures. Callers should ensure 526 * that this function is *NOT* called under RCU protection or in contexts where 527 * mutex cannot be locked. 528 */ 529void dev_pm_opp_of_cpumask_remove_table(const struct cpumask *cpumask) 530{ 531 _dev_pm_opp_cpumask_remove_table(cpumask, true); 532} 533EXPORT_SYMBOL_GPL(dev_pm_opp_of_cpumask_remove_table); 534 535/** 536 * dev_pm_opp_of_cpumask_add_table() - Adds OPP table for @cpumask 537 * @cpumask: cpumask for which OPP table needs to be added. 538 * 539 * This adds the OPP tables for CPUs present in the @cpumask. 540 * 541 * Locking: The internal opp_table and opp structures are RCU protected. 542 * Hence this function internally uses RCU updater strategy with mutex locks 543 * to keep the integrity of the internal data structures. Callers should ensure 544 * that this function is *NOT* called under RCU protection or in contexts where 545 * mutex cannot be locked. 546 */ 547int dev_pm_opp_of_cpumask_add_table(const struct cpumask *cpumask) 548{ 549 struct device *cpu_dev; 550 int cpu, ret = 0; 551 552 WARN_ON(cpumask_empty(cpumask)); 553 554 for_each_cpu(cpu, cpumask) { 555 cpu_dev = get_cpu_device(cpu); 556 if (!cpu_dev) { 557 pr_err("%s: failed to get cpu%d device\n", __func__, 558 cpu); 559 continue; 560 } 561 562 ret = dev_pm_opp_of_add_table(cpu_dev); 563 if (ret) { 564 pr_err("%s: couldn't find opp table for cpu:%d, %d\n", 565 __func__, cpu, ret); 566 567 /* Free all other OPPs */ 568 dev_pm_opp_of_cpumask_remove_table(cpumask); 569 break; 570 } 571 } 572 573 return ret; 574} 575EXPORT_SYMBOL_GPL(dev_pm_opp_of_cpumask_add_table); 576 577/* 578 * Works only for OPP v2 bindings. 579 * 580 * Returns -ENOENT if operating-points-v2 bindings aren't supported. 581 */ 582/** 583 * dev_pm_opp_of_get_sharing_cpus() - Get cpumask of CPUs sharing OPPs with 584 * @cpu_dev using operating-points-v2 585 * bindings. 586 * 587 * @cpu_dev: CPU device for which we do this operation 588 * @cpumask: cpumask to update with information of sharing CPUs 589 * 590 * This updates the @cpumask with CPUs that are sharing OPPs with @cpu_dev. 591 * 592 * Returns -ENOENT if operating-points-v2 isn't present for @cpu_dev. 593 * 594 * Locking: The internal opp_table and opp structures are RCU protected. 595 * Hence this function internally uses RCU updater strategy with mutex locks 596 * to keep the integrity of the internal data structures. Callers should ensure 597 * that this function is *NOT* called under RCU protection or in contexts where 598 * mutex cannot be locked. 599 */ 600int dev_pm_opp_of_get_sharing_cpus(struct device *cpu_dev, 601 struct cpumask *cpumask) 602{ 603 struct device_node *np, *tmp_np; 604 struct device *tcpu_dev; 605 int cpu, ret = 0; 606 607 /* Get OPP descriptor node */ 608 np = _of_get_opp_desc_node(cpu_dev); 609 if (!np) { 610 dev_dbg(cpu_dev, "%s: Couldn't find opp node.\n", __func__); 611 return -ENOENT; 612 } 613 614 cpumask_set_cpu(cpu_dev->id, cpumask); 615 616 /* OPPs are shared ? */ 617 if (!of_property_read_bool(np, "opp-shared")) 618 goto put_cpu_node; 619 620 for_each_possible_cpu(cpu) { 621 if (cpu == cpu_dev->id) 622 continue; 623 624 tcpu_dev = get_cpu_device(cpu); 625 if (!tcpu_dev) { 626 dev_err(cpu_dev, "%s: failed to get cpu%d device\n", 627 __func__, cpu); 628 ret = -ENODEV; 629 goto put_cpu_node; 630 } 631 632 /* Get OPP descriptor node */ 633 tmp_np = _of_get_opp_desc_node(tcpu_dev); 634 if (!tmp_np) { 635 dev_err(tcpu_dev, "%s: Couldn't find opp node.\n", 636 __func__); 637 ret = -ENOENT; 638 goto put_cpu_node; 639 } 640 641 /* CPUs are sharing opp node */ 642 if (np == tmp_np) 643 cpumask_set_cpu(cpu, cpumask); 644 645 of_node_put(tmp_np); 646 } 647 648put_cpu_node: 649 of_node_put(np); 650 return ret; 651} 652EXPORT_SYMBOL_GPL(dev_pm_opp_of_get_sharing_cpus);