diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2023-04-25 18:44:10 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2023-04-25 18:44:10 -0700 |
commit | 0cfd8703e7da687924371e9bc77a025bdeba9637 (patch) | |
tree | b1cbcd250948e3cc9ea6a9f813535fc07c70efe6 /drivers/opp/core.c | |
parent | 793582ff47f8b73be8d3d925d750bf3ef79f33c7 (diff) | |
parent | d3f2c402e44887e507b65d65f0d0515d46575bf5 (diff) | |
download | linux-0cfd8703e7da687924371e9bc77a025bdeba9637.tar.gz linux-0cfd8703e7da687924371e9bc77a025bdeba9637.tar.bz2 linux-0cfd8703e7da687924371e9bc77a025bdeba9637.zip |
Merge tag 'pm-6.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull power management updates from Rafael Wysocki:
"These update several cpufreq drivers and the cpufreq core, add sysfs
interface for exposing the time really spent in the platform low-power
state during suspend-to-idle, update devfreq (core and drivers) and
the pm-graph suite of tools and clean up code.
Specifics:
- Fix the frequency unit in cpufreq_verify_current_freq checks()
Sanjay Chandrashekara)
- Make mode_state_machine in amd-pstate static (Tom Rix)
- Make the cpufreq core require drivers with target_index() to set
freq_table (Viresh Kumar)
- Fix typo in the ARM_BRCMSTB_AVS_CPUFREQ Kconfig entry (Jingyu Wang)
- Use of_property_read_bool() for boolean properties in the pmac32
cpufreq driver (Rob Herring)
- Make the cpufreq sysfs interface return proper error codes on
obviously invalid input (qinyu)
- Add guided autonomous mode support to the AMD P-state driver (Wyes
Karny)
- Make the Intel P-state driver enable HWP IO boost on all server
platforms (Srinivas Pandruvada)
- Add opp and bandwidth support to tegra194 cpufreq driver (Sumit
Gupta)
- Use of_property_present() for testing DT property presence (Rob
Herring)
- Remove MODULE_LICENSE in non-modules (Nick Alcock)
- Add SM7225 to cpufreq-dt-platdev blocklist (Luca Weiss)
- Optimizations and fixes for qcom-cpufreq-hw driver (Krzysztof
Kozlowski, Konrad Dybcio, and Bjorn Andersson)
- DT binding updates for qcom-cpufreq-hw driver (Konrad Dybcio and
Bartosz Golaszewski)
- Updates and fixes for mediatek driver (Jia-Wei Chang and
AngeloGioacchino Del Regno)
- Use of_property_present() for testing DT property presence in the
cpuidle code (Rob Herring)
- Drop unnecessary (void *) conversions from the PM core (Li zeming)
- Add sysfs files to represent time spent in a platform sleep state
during suspend-to-idle and make AMD and Intel PMC drivers use them
Mario Limonciello)
- Use of_property_present() for testing DT property presence (Rob
Herring)
- Add set_required_opps() callback to the 'struct opp_table', to make
the code paths cleaner (Viresh Kumar)
- Update the pm-graph siute of utilities to v5.11 with the following
changes:
* New script which allows users to install the latest pm-graph
from the upstream github repo.
* Update all the dmesg suspend/resume PM print formats to be able
to process recent timelines using dmesg only.
* Add ethtool output to the log for the system's ethernet device
if ethtool exists.
* Make the tool more robustly handle events where mangled dmesg
or ftrace outputs do not include all the requisite data.
- Make the sleepgraph utility recognize "CPU killed" messages (Xueqin
Luo)
- Remove unneeded SRCU selection in Kconfig because it's always set
from devfreq core (Paul E. McKenney)
- Drop of_match_ptr() macro from exynos-bus.c because this driver is
always using the DT table for driver probe (Krzysztof Kozlowski)
- Use the preferred of_property_present() instead of the low-level
of_get_property() on exynos-bus.c (Rob Herring)
- Use devm_platform_get_and_ioream_resource() in exyno-ppmu.c (Yang
Li)"
* tag 'pm-6.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (44 commits)
platform/x86/intel/pmc: core: Report duration of time in HW sleep state
platform/x86/intel/pmc: core: Always capture counters on suspend
platform/x86/amd: pmc: Report duration of time in hw sleep state
PM: Add sysfs files to represent time spent in hardware sleep state
cpufreq: use correct unit when verify cur freq
cpufreq: tegra194: add OPP support and set bandwidth
cpufreq: amd-pstate: Make varaiable mode_state_machine static
PM: core: Remove unnecessary (void *) conversions
cpufreq: drivers with target_index() must set freq_table
PM / devfreq: exynos-ppmu: Use devm_platform_get_and_ioremap_resource()
OPP: Move required opps configuration to specialized callback
OPP: Handle all genpd cases together in _set_required_opps()
cpufreq: qcom-cpufreq-hw: Revert adding cpufreq qos
dt-bindings: cpufreq: cpufreq-qcom-hw: Add QCM2290
dt-bindings: cpufreq: cpufreq-qcom-hw: Sanitize data per compatible
dt-bindings: cpufreq: cpufreq-qcom-hw: Allow just 1 frequency domain
cpufreq: Add SM7225 to cpufreq-dt-platdev blocklist
cpufreq: qcom-cpufreq-hw: fix double IO unmap and resource release on exit
cpufreq: mediatek: Raise proc and sram max voltage for MT7622/7623
cpufreq: mediatek: raise proc/sram max voltage for MT8516
...
Diffstat (limited to 'drivers/opp/core.c')
-rw-r--r-- | drivers/opp/core.c | 78 |
1 files changed, 44 insertions, 34 deletions
diff --git a/drivers/opp/core.c b/drivers/opp/core.c index e87567dbe99f..954c94865cf5 100644 --- a/drivers/opp/core.c +++ b/drivers/opp/core.c @@ -935,8 +935,8 @@ static int _set_opp_bw(const struct opp_table *opp_table, return 0; } -static int _set_required_opp(struct device *dev, struct device *pd_dev, - struct dev_pm_opp *opp, int i) +static int _set_performance_state(struct device *dev, struct device *pd_dev, + struct dev_pm_opp *opp, int i) { unsigned int pstate = likely(opp) ? opp->required_opps[i]->pstate : 0; int ret; @@ -953,37 +953,19 @@ static int _set_required_opp(struct device *dev, struct device *pd_dev, return ret; } -/* This is only called for PM domain for now */ -static int _set_required_opps(struct device *dev, - struct opp_table *opp_table, - struct dev_pm_opp *opp, bool up) +static int _opp_set_required_opps_generic(struct device *dev, + struct opp_table *opp_table, struct dev_pm_opp *opp, bool scaling_down) { - struct opp_table **required_opp_tables = opp_table->required_opp_tables; - struct device **genpd_virt_devs = opp_table->genpd_virt_devs; - int i, ret = 0; - - if (!required_opp_tables) - return 0; - - /* required-opps not fully initialized yet */ - if (lazy_linking_pending(opp_table)) - return -EBUSY; - - /* - * We only support genpd's OPPs in the "required-opps" for now, as we - * don't know much about other use cases. Error out if the required OPP - * doesn't belong to a genpd. - */ - if (unlikely(!required_opp_tables[0]->is_genpd)) { - dev_err(dev, "required-opps don't belong to a genpd\n"); - return -ENOENT; - } - - /* Single genpd case */ - if (!genpd_virt_devs) - return _set_required_opp(dev, dev, opp, 0); + dev_err(dev, "setting required-opps isn't supported for non-genpd devices\n"); + return -ENOENT; +} - /* Multiple genpd case */ +static int _opp_set_required_opps_genpd(struct device *dev, + struct opp_table *opp_table, struct dev_pm_opp *opp, bool scaling_down) +{ + struct device **genpd_virt_devs = + opp_table->genpd_virt_devs ? opp_table->genpd_virt_devs : &dev; + int i, ret = 0; /* * Acquire genpd_virt_dev_lock to make sure we don't use a genpd_dev @@ -992,15 +974,15 @@ static int _set_required_opps(struct device *dev, mutex_lock(&opp_table->genpd_virt_dev_lock); /* Scaling up? Set required OPPs in normal order, else reverse */ - if (up) { + if (!scaling_down) { for (i = 0; i < opp_table->required_opp_count; i++) { - ret = _set_required_opp(dev, genpd_virt_devs[i], opp, i); + ret = _set_performance_state(dev, genpd_virt_devs[i], opp, i); if (ret) break; } } else { for (i = opp_table->required_opp_count - 1; i >= 0; i--) { - ret = _set_required_opp(dev, genpd_virt_devs[i], opp, i); + ret = _set_performance_state(dev, genpd_virt_devs[i], opp, i); if (ret) break; } @@ -1011,6 +993,34 @@ static int _set_required_opps(struct device *dev, return ret; } +/* This is only called for PM domain for now */ +static int _set_required_opps(struct device *dev, struct opp_table *opp_table, + struct dev_pm_opp *opp, bool up) +{ + /* required-opps not fully initialized yet */ + if (lazy_linking_pending(opp_table)) + return -EBUSY; + + if (opp_table->set_required_opps) + return opp_table->set_required_opps(dev, opp_table, opp, up); + + return 0; +} + +/* Update set_required_opps handler */ +void _update_set_required_opps(struct opp_table *opp_table) +{ + /* Already set */ + if (opp_table->set_required_opps) + return; + + /* All required OPPs will belong to genpd or none */ + if (opp_table->required_opp_tables[0]->is_genpd) + opp_table->set_required_opps = _opp_set_required_opps_genpd; + else + opp_table->set_required_opps = _opp_set_required_opps_generic; +} + static void _find_current_opp(struct device *dev, struct opp_table *opp_table) { struct dev_pm_opp *opp = ERR_PTR(-ENODEV); |