diff options
| -rw-r--r-- | drivers/base/power/opp.c | 55 |
1 files changed, 28 insertions, 27 deletions
diff --git a/drivers/base/power/opp.c b/drivers/base/power/opp.c index 25538675d59e..38b43bb20878 100644 --- a/drivers/base/power/opp.c +++ b/drivers/base/power/opp.c | |||
| @@ -617,53 +617,54 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_disable); | |||
| 617 | * the table if any of the mentioned functions have been invoked in the interim. | 617 | * the table if any of the mentioned functions have been invoked in the interim. |
| 618 | * | 618 | * |
| 619 | * Locking: The internal device_opp and opp structures are RCU protected. | 619 | * Locking: The internal device_opp and opp structures are RCU protected. |
| 620 | * To simplify the logic, we pretend we are updater and hold relevant mutex here | 620 | * Since we just use the regular accessor functions to access the internal data |
| 621 | * Callers should ensure that this function is *NOT* called under RCU protection | 621 | * structures, we use RCU read lock inside this function. As a result, users of |
| 622 | * or in contexts where mutex locking cannot be used. | 622 | * this function DONOT need to use explicit locks for invoking. |
| 623 | */ | 623 | */ |
| 624 | int dev_pm_opp_init_cpufreq_table(struct device *dev, | 624 | int dev_pm_opp_init_cpufreq_table(struct device *dev, |
| 625 | struct cpufreq_frequency_table **table) | 625 | struct cpufreq_frequency_table **table) |
| 626 | { | 626 | { |
| 627 | struct device_opp *dev_opp; | ||
| 628 | struct dev_pm_opp *opp; | 627 | struct dev_pm_opp *opp; |
| 629 | struct cpufreq_frequency_table *freq_table; | 628 | struct cpufreq_frequency_table *freq_table = NULL; |
| 630 | int i = 0; | 629 | int i, max_opps, ret = 0; |
| 630 | unsigned long rate; | ||
| 631 | 631 | ||
| 632 | /* Pretend as if I am an updater */ | 632 | rcu_read_lock(); |
| 633 | mutex_lock(&dev_opp_list_lock); | ||
| 634 | 633 | ||
| 635 | dev_opp = find_device_opp(dev); | 634 | max_opps = dev_pm_opp_get_opp_count(dev); |
| 636 | if (IS_ERR(dev_opp)) { | 635 | if (max_opps <= 0) { |
| 637 | int r = PTR_ERR(dev_opp); | 636 | ret = max_opps ? max_opps : -ENODATA; |
| 638 | mutex_unlock(&dev_opp_list_lock); | 637 | goto out; |
| 639 | dev_err(dev, "%s: Device OPP not found (%d)\n", __func__, r); | ||
| 640 | return r; | ||
| 641 | } | 638 | } |
| 642 | 639 | ||
| 643 | freq_table = kzalloc(sizeof(struct cpufreq_frequency_table) * | 640 | freq_table = kzalloc(sizeof(*freq_table) * (max_opps + 1), GFP_KERNEL); |
| 644 | (dev_pm_opp_get_opp_count(dev) + 1), GFP_KERNEL); | ||
| 645 | if (!freq_table) { | 641 | if (!freq_table) { |
| 646 | mutex_unlock(&dev_opp_list_lock); | 642 | ret = -ENOMEM; |
| 647 | dev_warn(dev, "%s: Unable to allocate frequency table\n", | 643 | goto out; |
| 648 | __func__); | ||
| 649 | return -ENOMEM; | ||
| 650 | } | 644 | } |
| 651 | 645 | ||
| 652 | list_for_each_entry(opp, &dev_opp->opp_list, node) { | 646 | for (i = 0, rate = 0; i < max_opps; i++, rate++) { |
| 653 | if (opp->available) { | 647 | /* find next rate */ |
| 654 | freq_table[i].driver_data = i; | 648 | opp = dev_pm_opp_find_freq_ceil(dev, &rate); |
| 655 | freq_table[i].frequency = opp->rate / 1000; | 649 | if (IS_ERR(opp)) { |
| 656 | i++; | 650 | ret = PTR_ERR(opp); |
| 651 | goto out; | ||
| 657 | } | 652 | } |
| 653 | freq_table[i].driver_data = i; | ||
| 654 | freq_table[i].frequency = rate / 1000; | ||
| 658 | } | 655 | } |
| 659 | mutex_unlock(&dev_opp_list_lock); | ||
| 660 | 656 | ||
| 661 | freq_table[i].driver_data = i; | 657 | freq_table[i].driver_data = i; |
| 662 | freq_table[i].frequency = CPUFREQ_TABLE_END; | 658 | freq_table[i].frequency = CPUFREQ_TABLE_END; |
| 663 | 659 | ||
| 664 | *table = &freq_table[0]; | 660 | *table = &freq_table[0]; |
| 665 | 661 | ||
| 666 | return 0; | 662 | out: |
| 663 | rcu_read_unlock(); | ||
| 664 | if (ret) | ||
| 665 | kfree(freq_table); | ||
| 666 | |||
| 667 | return ret; | ||
| 667 | } | 668 | } |
| 668 | EXPORT_SYMBOL_GPL(dev_pm_opp_init_cpufreq_table); | 669 | EXPORT_SYMBOL_GPL(dev_pm_opp_init_cpufreq_table); |
| 669 | 670 | ||
