diff options
author | Viresh Kumar <viresh.kumar@linaro.org> | 2017-05-23 00:02:10 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2017-06-21 21:15:29 -0400 |
commit | c74b32fadc00f2412d86a19295eb867b1a772948 (patch) | |
tree | e9eca6b6a1e54604931c3e4f7a4ca83d3c9ec5cc | |
parent | 41f1830f5a7af77cf5c86359aba3cbd706687e52 (diff) |
PM / OPP: Reorganize _generic_set_opp_regulator()
The code was overly complicated here because of the limitations that we
had with RCUs (Couldn't use opp-table and OPPs outside RCU protected
section and can't call sleep-able routines from within that). But that
is long gone now.
Reorganize _generic_set_opp_regulator() in order to avoid using "struct
dev_pm_set_opp_data" and copying data into it for the case where
opp_table->set_opp is not set.
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r-- | drivers/base/power/opp/core.c | 73 |
1 files changed, 34 insertions, 39 deletions
diff --git a/drivers/base/power/opp/core.c b/drivers/base/power/opp/core.c index dae61720b314..c4590fc017ba 100644 --- a/drivers/base/power/opp/core.c +++ b/drivers/base/power/opp/core.c | |||
@@ -543,17 +543,18 @@ _generic_set_opp_clk_only(struct device *dev, struct clk *clk, | |||
543 | return ret; | 543 | return ret; |
544 | } | 544 | } |
545 | 545 | ||
546 | static int _generic_set_opp(struct dev_pm_set_opp_data *data) | 546 | static int _generic_set_opp_regulator(const struct opp_table *opp_table, |
547 | struct device *dev, | ||
548 | unsigned long old_freq, | ||
549 | unsigned long freq, | ||
550 | struct dev_pm_opp_supply *old_supply, | ||
551 | struct dev_pm_opp_supply *new_supply) | ||
547 | { | 552 | { |
548 | struct dev_pm_opp_supply *old_supply = data->old_opp.supplies; | 553 | struct regulator *reg = opp_table->regulators[0]; |
549 | struct dev_pm_opp_supply *new_supply = data->new_opp.supplies; | ||
550 | unsigned long old_freq = data->old_opp.rate, freq = data->new_opp.rate; | ||
551 | struct regulator *reg = data->regulators[0]; | ||
552 | struct device *dev= data->dev; | ||
553 | int ret; | 554 | int ret; |
554 | 555 | ||
555 | /* This function only supports single regulator per device */ | 556 | /* This function only supports single regulator per device */ |
556 | if (WARN_ON(data->regulator_count > 1)) { | 557 | if (WARN_ON(opp_table->regulator_count > 1)) { |
557 | dev_err(dev, "multiple regulators are not supported\n"); | 558 | dev_err(dev, "multiple regulators are not supported\n"); |
558 | return -EINVAL; | 559 | return -EINVAL; |
559 | } | 560 | } |
@@ -566,7 +567,7 @@ static int _generic_set_opp(struct dev_pm_set_opp_data *data) | |||
566 | } | 567 | } |
567 | 568 | ||
568 | /* Change frequency */ | 569 | /* Change frequency */ |
569 | ret = _generic_set_opp_clk_only(dev, data->clk, old_freq, freq); | 570 | ret = _generic_set_opp_clk_only(dev, opp_table->clk, old_freq, freq); |
570 | if (ret) | 571 | if (ret) |
571 | goto restore_voltage; | 572 | goto restore_voltage; |
572 | 573 | ||
@@ -580,12 +581,12 @@ static int _generic_set_opp(struct dev_pm_set_opp_data *data) | |||
580 | return 0; | 581 | return 0; |
581 | 582 | ||
582 | restore_freq: | 583 | restore_freq: |
583 | if (_generic_set_opp_clk_only(dev, data->clk, freq, old_freq)) | 584 | if (_generic_set_opp_clk_only(dev, opp_table->clk, freq, old_freq)) |
584 | dev_err(dev, "%s: failed to restore old-freq (%lu Hz)\n", | 585 | dev_err(dev, "%s: failed to restore old-freq (%lu Hz)\n", |
585 | __func__, old_freq); | 586 | __func__, old_freq); |
586 | restore_voltage: | 587 | restore_voltage: |
587 | /* This shouldn't harm even if the voltages weren't updated earlier */ | 588 | /* This shouldn't harm even if the voltages weren't updated earlier */ |
588 | if (old_supply->u_volt) | 589 | if (old_supply) |
589 | _set_opp_voltage(dev, reg, old_supply); | 590 | _set_opp_voltage(dev, reg, old_supply); |
590 | 591 | ||
591 | return ret; | 592 | return ret; |
@@ -603,10 +604,7 @@ int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq) | |||
603 | { | 604 | { |
604 | struct opp_table *opp_table; | 605 | struct opp_table *opp_table; |
605 | unsigned long freq, old_freq; | 606 | unsigned long freq, old_freq; |
606 | int (*set_opp)(struct dev_pm_set_opp_data *data); | ||
607 | struct dev_pm_opp *old_opp, *opp; | 607 | struct dev_pm_opp *old_opp, *opp; |
608 | struct regulator **regulators; | ||
609 | struct dev_pm_set_opp_data *data; | ||
610 | struct clk *clk; | 608 | struct clk *clk; |
611 | int ret, size; | 609 | int ret, size; |
612 | 610 | ||
@@ -661,38 +659,35 @@ int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq) | |||
661 | dev_dbg(dev, "%s: switching OPP: %lu Hz --> %lu Hz\n", __func__, | 659 | dev_dbg(dev, "%s: switching OPP: %lu Hz --> %lu Hz\n", __func__, |
662 | old_freq, freq); | 660 | old_freq, freq); |
663 | 661 | ||
664 | regulators = opp_table->regulators; | ||
665 | |||
666 | /* Only frequency scaling */ | 662 | /* Only frequency scaling */ |
667 | if (!regulators) { | 663 | if (!opp_table->regulators) { |
668 | ret = _generic_set_opp_clk_only(dev, clk, old_freq, freq); | 664 | ret = _generic_set_opp_clk_only(dev, clk, old_freq, freq); |
669 | goto put_opps; | 665 | } else if (!opp_table->set_opp) { |
670 | } | 666 | ret = _generic_set_opp_regulator(opp_table, dev, old_freq, freq, |
667 | IS_ERR(old_opp) ? NULL : old_opp->supplies, | ||
668 | opp->supplies); | ||
669 | } else { | ||
670 | struct dev_pm_set_opp_data *data; | ||
671 | 671 | ||
672 | if (opp_table->set_opp) | 672 | data = opp_table->set_opp_data; |
673 | set_opp = opp_table->set_opp; | 673 | data->regulators = opp_table->regulators; |
674 | else | 674 | data->regulator_count = opp_table->regulator_count; |
675 | set_opp = _generic_set_opp; | 675 | data->clk = clk; |
676 | 676 | data->dev = dev; | |
677 | data = opp_table->set_opp_data; | ||
678 | data->regulators = regulators; | ||
679 | data->regulator_count = opp_table->regulator_count; | ||
680 | data->clk = clk; | ||
681 | data->dev = dev; | ||
682 | |||
683 | data->old_opp.rate = old_freq; | ||
684 | size = sizeof(*opp->supplies) * opp_table->regulator_count; | ||
685 | if (IS_ERR(old_opp)) | ||
686 | memset(data->old_opp.supplies, 0, size); | ||
687 | else | ||
688 | memcpy(data->old_opp.supplies, old_opp->supplies, size); | ||
689 | 677 | ||
690 | data->new_opp.rate = freq; | 678 | data->old_opp.rate = old_freq; |
691 | memcpy(data->new_opp.supplies, opp->supplies, size); | 679 | size = sizeof(*opp->supplies) * opp_table->regulator_count; |
680 | if (IS_ERR(old_opp)) | ||
681 | memset(data->old_opp.supplies, 0, size); | ||
682 | else | ||
683 | memcpy(data->old_opp.supplies, old_opp->supplies, size); | ||
692 | 684 | ||
693 | ret = set_opp(data); | 685 | data->new_opp.rate = freq; |
686 | memcpy(data->new_opp.supplies, opp->supplies, size); | ||
687 | |||
688 | ret = opp_table->set_opp(data); | ||
689 | } | ||
694 | 690 | ||
695 | put_opps: | ||
696 | dev_pm_opp_put(opp); | 691 | dev_pm_opp_put(opp); |
697 | put_old_opp: | 692 | put_old_opp: |
698 | if (!IS_ERR(old_opp)) | 693 | if (!IS_ERR(old_opp)) |