diff options
| -rw-r--r-- | drivers/base/power/opp.c | 59 |
1 files changed, 34 insertions, 25 deletions
diff --git a/drivers/base/power/opp.c b/drivers/base/power/opp.c index a333e2ef5cb2..b249b0127eff 100644 --- a/drivers/base/power/opp.c +++ b/drivers/base/power/opp.c | |||
| @@ -49,6 +49,7 @@ | |||
| 49 | * are protected by the dev_opp_list_lock for integrity. | 49 | * are protected by the dev_opp_list_lock for integrity. |
| 50 | * IMPORTANT: the opp nodes should be maintained in increasing | 50 | * IMPORTANT: the opp nodes should be maintained in increasing |
| 51 | * order. | 51 | * order. |
| 52 | * @dynamic: not-created from static DT entries. | ||
| 52 | * @available: true/false - marks if this OPP as available or not | 53 | * @available: true/false - marks if this OPP as available or not |
| 53 | * @rate: Frequency in hertz | 54 | * @rate: Frequency in hertz |
| 54 | * @u_volt: Nominal voltage in microvolts corresponding to this OPP | 55 | * @u_volt: Nominal voltage in microvolts corresponding to this OPP |
| @@ -61,6 +62,7 @@ struct dev_pm_opp { | |||
| 61 | struct list_head node; | 62 | struct list_head node; |
| 62 | 63 | ||
| 63 | bool available; | 64 | bool available; |
| 65 | bool dynamic; | ||
| 64 | unsigned long rate; | 66 | unsigned long rate; |
| 65 | unsigned long u_volt; | 67 | unsigned long u_volt; |
| 66 | 68 | ||
| @@ -378,30 +380,8 @@ struct dev_pm_opp *dev_pm_opp_find_freq_floor(struct device *dev, | |||
| 378 | } | 380 | } |
| 379 | EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_floor); | 381 | EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_floor); |
| 380 | 382 | ||
| 381 | /** | 383 | static int dev_pm_opp_add_dynamic(struct device *dev, unsigned long freq, |
| 382 | * dev_pm_opp_add() - Add an OPP table from a table definitions | 384 | unsigned long u_volt, bool dynamic) |
| 383 | * @dev: device for which we do this operation | ||
| 384 | * @freq: Frequency in Hz for this OPP | ||
| 385 | * @u_volt: Voltage in uVolts for this OPP | ||
| 386 | * | ||
| 387 | * This function adds an opp definition to the opp list and returns status. | ||
| 388 | * The opp is made available by default and it can be controlled using | ||
| 389 | * dev_pm_opp_enable/disable functions. | ||
| 390 | * | ||
| 391 | * Locking: The internal device_opp and opp structures are RCU protected. | ||
| 392 | * Hence this function internally uses RCU updater strategy with mutex locks | ||
| 393 | * to keep the integrity of the internal data structures. Callers should ensure | ||
| 394 | * that this function is *NOT* called under RCU protection or in contexts where | ||
| 395 | * mutex cannot be locked. | ||
| 396 | * | ||
| 397 | * Return: | ||
| 398 | * 0: On success OR | ||
| 399 | * Duplicate OPPs (both freq and volt are same) and opp->available | ||
| 400 | * -EEXIST: Freq are same and volt are different OR | ||
| 401 | * Duplicate OPPs (both freq and volt are same) and !opp->available | ||
| 402 | * -ENOMEM: Memory allocation failure | ||
| 403 | */ | ||
| 404 | int dev_pm_opp_add(struct device *dev, unsigned long freq, unsigned long u_volt) | ||
| 405 | { | 385 | { |
| 406 | struct device_opp *dev_opp = NULL; | 386 | struct device_opp *dev_opp = NULL; |
| 407 | struct dev_pm_opp *opp, *new_opp; | 387 | struct dev_pm_opp *opp, *new_opp; |
| @@ -422,6 +402,7 @@ int dev_pm_opp_add(struct device *dev, unsigned long freq, unsigned long u_volt) | |||
| 422 | new_opp->rate = freq; | 402 | new_opp->rate = freq; |
| 423 | new_opp->u_volt = u_volt; | 403 | new_opp->u_volt = u_volt; |
| 424 | new_opp->available = true; | 404 | new_opp->available = true; |
| 405 | new_opp->dynamic = dynamic; | ||
| 425 | 406 | ||
| 426 | /* Check for existing list for 'dev' */ | 407 | /* Check for existing list for 'dev' */ |
| 427 | dev_opp = find_device_opp(dev); | 408 | dev_opp = find_device_opp(dev); |
| @@ -487,6 +468,34 @@ list_add: | |||
| 487 | srcu_notifier_call_chain(&dev_opp->srcu_head, OPP_EVENT_ADD, new_opp); | 468 | srcu_notifier_call_chain(&dev_opp->srcu_head, OPP_EVENT_ADD, new_opp); |
| 488 | return 0; | 469 | return 0; |
| 489 | } | 470 | } |
| 471 | |||
| 472 | /** | ||
| 473 | * dev_pm_opp_add() - Add an OPP table from a table definitions | ||
| 474 | * @dev: device for which we do this operation | ||
| 475 | * @freq: Frequency in Hz for this OPP | ||
| 476 | * @u_volt: Voltage in uVolts for this OPP | ||
| 477 | * | ||
| 478 | * This function adds an opp definition to the opp list and returns status. | ||
| 479 | * The opp is made available by default and it can be controlled using | ||
| 480 | * dev_pm_opp_enable/disable functions. | ||
| 481 | * | ||
| 482 | * Locking: The internal device_opp and opp structures are RCU protected. | ||
| 483 | * Hence this function internally uses RCU updater strategy with mutex locks | ||
| 484 | * to keep the integrity of the internal data structures. Callers should ensure | ||
| 485 | * that this function is *NOT* called under RCU protection or in contexts where | ||
| 486 | * mutex cannot be locked. | ||
| 487 | * | ||
| 488 | * Return: | ||
| 489 | * 0: On success OR | ||
| 490 | * Duplicate OPPs (both freq and volt are same) and opp->available | ||
| 491 | * -EEXIST: Freq are same and volt are different OR | ||
| 492 | * Duplicate OPPs (both freq and volt are same) and !opp->available | ||
| 493 | * -ENOMEM: Memory allocation failure | ||
| 494 | */ | ||
| 495 | int dev_pm_opp_add(struct device *dev, unsigned long freq, unsigned long u_volt) | ||
| 496 | { | ||
| 497 | return dev_pm_opp_add_dynamic(dev, freq, u_volt, true); | ||
| 498 | } | ||
| 490 | EXPORT_SYMBOL_GPL(dev_pm_opp_add); | 499 | EXPORT_SYMBOL_GPL(dev_pm_opp_add); |
| 491 | 500 | ||
| 492 | /** | 501 | /** |
| @@ -669,7 +678,7 @@ int of_init_opp_table(struct device *dev) | |||
| 669 | unsigned long freq = be32_to_cpup(val++) * 1000; | 678 | unsigned long freq = be32_to_cpup(val++) * 1000; |
| 670 | unsigned long volt = be32_to_cpup(val++); | 679 | unsigned long volt = be32_to_cpup(val++); |
| 671 | 680 | ||
| 672 | if (dev_pm_opp_add(dev, freq, volt)) | 681 | if (dev_pm_opp_add_dynamic(dev, freq, volt, false)) |
| 673 | dev_warn(dev, "%s: Failed to add OPP %ld\n", | 682 | dev_warn(dev, "%s: Failed to add OPP %ld\n", |
| 674 | __func__, freq); | 683 | __func__, freq); |
| 675 | nr -= 2; | 684 | nr -= 2; |
