History log of /linux-master/drivers/opp/of.c
Revision Date Author Comments
# 92514143 16-Nov-2023 Viresh Kumar <viresh.kumar@linaro.org>

OPP: Don't set OPP recursively for a parent genpd

Like other frameworks (clk, regulator, etc.) genpd core too takes care
of propagation to performance state to parent genpds. The OPP core
shouldn't attempt the same, or it may result in undefined behavior.

Add checks at various places to take care of the same.

Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
Tested-by: Stephan Gerhold <stephan.gerhold@kernkonzept.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# e37440e7 27-Oct-2023 Viresh Kumar <viresh.kumar@linaro.org>

OPP: Call dev_pm_opp_set_opp() for required OPPs

Configuring the required OPP was never properly implemented, we just
took an exception for genpds and configured them directly, while leaving
out all other required OPP types.

Now that a standard call to dev_pm_opp_set_opp() takes care of
configuring the opp->level too, the special handling for genpds can be
avoided by simply calling dev_pm_opp_set_opp() for the required OPPs,
which shall eventually configure the corresponding level for genpds.

This also makes it possible for us to configure other type of required
OPPs (no concrete users yet though), via the same path. This is how
other frameworks take care of parent nodes, like clock, regulators, etc,
where we recursively call the same helper.

In order to call dev_pm_opp_set_opp() for the virtual genpd devices,
they must share the OPP table of the genpd. Call _add_opp_dev() for them
to get that done.

This commit also extends the struct dev_pm_opp_config to pass required
devices, for non-genpd cases, which can be used to call
dev_pm_opp_set_opp() for the non-genpd required devices.

Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
Tested-by: Stephan Gerhold <stephan.gerhold@kernkonzept.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# 6d366d0e 12-Oct-2023 Viresh Kumar <viresh.kumar@linaro.org>

OPP: Use _set_opp_level() for single genpd case

There are two genpd (as required-opp) cases that we need to handle,
devices with a single genpd and ones with multiple genpds.

The multiple genpds case is clear, where the OPP core calls
dev_pm_domain_attach_by_name() for them and uses the virtual devices
returned by this helper to call dev_pm_domain_set_performance_state()
later to change the performance state.

The single genpd case however requires special handling as we need to
use the same `dev` structure (instead of a virtual one provided by genpd
core) for setting the performance state via
dev_pm_domain_set_performance_state().

As we move towards more generic code to take care of the required OPPs,
where we will recursively call dev_pm_opp_set_opp() for all the required
OPPs, the above special case becomes a problem.

It doesn't make sense for a device's DT entry to have both "opp-level"
and single "required-opps" entry pointing to a genpd's OPP, as that
would make the OPP core call dev_pm_domain_set_performance_state() for
two different values for the same device structure. And so we can reuse
the 'opp->level" field in such a case and call _set_opp_level() for the
device.

Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
Tested-by: Stephan Gerhold <stephan.gerhold@kernkonzept.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# 073d3d2c 26-Oct-2023 Viresh Kumar <viresh.kumar@linaro.org>

OPP: Level zero is valid

The level zero can be used by some OPPs to drop performance state vote
for the device. It is perfectly fine to allow the same.

_set_opp_level() considers it as an invalid value currently and returns
early.

In order to support this properly, initialize the level field with
U32_MAX, which denotes unused level field.

Reported-by: Stephan Gerhold <stephan.gerhold@kernkonzept.com>
Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
Tested-by: Stephan Gerhold <stephan.gerhold@kernkonzept.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# 96104046 12-Oct-2023 Viresh Kumar <viresh.kumar@linaro.org>

OPP: Add _link_required_opps() to avoid code duplication

Factor out _link_required_opps() to remove duplicate code. No functional
change.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>


# 8e6db129 12-Oct-2023 Viresh Kumar <viresh.kumar@linaro.org>

OPP: Fix formatting of if/else block

Add {} to both if else blocks or none.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>


# 184ff4f7 05-Oct-2023 Nathan Chancellor <nathan@kernel.org>

OPP: Fix -Wunsequenced in _of_add_opp_table_v1()

Clang warns (or errors with CONFIG_WERROR=y):

drivers/opp/of.c:1081:28: error: multiple unsequenced modifications to 'val' [-Werror,-Wunsequenced]
1081 | .freq = be32_to_cpup(val++) * 1000,
| ^
1082 | .u_volt = be32_to_cpup(val++),
| ~~
1 error generated.

There is no sequence point in a designated initializer. Move back to
separate variables for the creation of the values, so that there are
sequence points between each evaluation and increment of val.

Fixes: 75bbc92c09d8 ("OPP: Add dev_pm_opp_add_dynamic() to allow more flexibility")
Signed-off-by: Nathan Chancellor <nathan@kernel.org>
Reviewed-by: Nick Desaulniers <ndesaulniers@google.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# 248a38d5 25-Sep-2023 Ulf Hansson <ulf.hansson@linaro.org>

OPP: Add dev_pm_opp_add_dynamic() to allow more flexibility

The dev_pm_opp_add() API is limited to add dynamic OPPs with a frequency
and a voltage level. To enable more flexibility, let's add a new API,
dev_pm_opp_add_dynamic() that's takes a struct dev_pm_opp_data* instead of
a list of in-parameters.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# 5fb2864c 26-Jun-2023 Andrew Halaney <ahalaney@redhat.com>

OPP: Properly propagate error along when failing to get icc_path

fa155f4f8348 ("OPP: Use dev_err_probe() when failing to get icc_path")
failed to actually use the error it was trying to log:

smatch warnings:
drivers/opp/of.c:516 dev_pm_opp_of_find_icc_paths() warn: passing zero to 'dev_err_probe'

Make sure to use the right error and pass it along.

Fixes: fa155f4f8348 ("OPP: Use dev_err_probe() when failing to get icc_path")
Reported-by: kernel test robot <lkp@intel.com>
Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
Closes: https://lore.kernel.org/r/202306262008.guNLgjt6-lkp@intel.com/
Signed-off-by: Andrew Halaney <ahalaney@redhat.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# fa155f4f 23-Jun-2023 Andrew Halaney <ahalaney@redhat.com>

OPP: Use dev_err_probe() when failing to get icc_path

This, in tandem with dynamic debug, can print useful information about
-EPROBE_DEFFER like below, and keeps similar behavior for other errors:

[ 16.561072] cpu cpu0: error -EPROBE_DEFER: dev_pm_opp_of_find_icc_paths: Unable to get path0
[ 16.575777] platform 18591000.cpufreq: deferred probe pending

Signed-off-by: Andrew Halaney <ahalaney@redhat.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# 7c41cdcd 14-Jun-2023 Viresh Kumar <viresh.kumar@linaro.org>

OPP: Simplify the over-designed pstate <-> level dance

While adding support for "performance states" in the OPP and genpd core,
it was decided to set the `pstate` field via genpd's
pm_genpd_opp_to_performance_state() helper, to allow platforms to set
`pstate` even if they don't have a corresponding `level` field in the DT
OPP tables (More details are present in commit 6e41766a6a50 ("PM /
Domain: Implement of_genpd_opp_to_performance_state()")).

Revisiting that five years later clearly suggests that it was
over-designed as all current users are eventually using the `level`
value only.

The previous commit already added necessary checks to make sure pstate
is only used for genpd tables. Lets now simplify this a little, and use
`level` directly and remove `pstate` field altogether.

Suggested-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>


# 84cb7ff3 14-Jun-2023 Viresh Kumar <viresh.kumar@linaro.org>

OPP: pstate is only valid for genpd OPP tables

It is not very clear right now that the `pstate` field is only valid for
genpd OPP tables and not consumer tables. And there is no checking for
the same at various places.

Add checks in place to verify that and make it clear to the reader.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
Reviewed-by: Bjorn Andersson <quic_bjorande@quicinc.com>
Tested-by: Bjorn Andersson <quic_bjorande@quicinc.com>


# 04bd2eaf 13-Jun-2023 Viresh Kumar <viresh.kumar@linaro.org>

OPP: don't drop performance constraint on OPP table removal

This code was added (long back) by commit 009acd196fc8 ("PM / OPP:
Support updating performance state of device's power domain") and at
that time the `opp->pstate` field was used to store the performance
state required by a device's OPP.

Over time that changed and the `->pstate` field is now used only for
genpd devices and consumer devices access that via the required-opps
instead.

Because of all these changes, _opp_table_kref_release() now drops the
constraint only when the genpd's OPP table gets freed and not the
device's. Which is definitely not what we wanted. And dropping the
constraint doesn't have much meaning as the genpd itself is going away.

Moreover, if we want to drop constraints here, then just dropping the
performance constraint alone isn't sufficient as there are other
resource constraints like clk, regulator, etc. too, which must be
handled.

Probably the right thing to do here is to leave this decision to the
consumers, which can call `dev_pm_opp_set_rate(dev, 0)` or similar APIs
to drop all constraints properly. Which many of the consumers already
do.

Remove the special code, which is broken anyway.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>


# 64aaeb70 08-Jun-2023 Viresh Kumar <viresh.kumar@linaro.org>

OPP: Protect `lazy_opp_tables` list with `opp_table_lock`

The `opp_table_lock` lock is already used to protect the list elsewhere,
use it while adding or removing entries from it.

Reported-by: Stephan Gerhold <stephan.gerhold@kernkonzept.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Tested-by: Stephan Gerhold <stephan.gerhold@kernkonzept.com>


# 167eb2bd 07-Jun-2023 Viresh Kumar <viresh.kumar@linaro.org>

OPP: Staticize `lazy_opp_tables` in of.c

`lazy_opp_tables` is only used in of.c, move it there and mark it
`static`.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# cd6f0f51 29-Mar-2023 Rob Herring <robh@kernel.org>

OPP: Adjust includes to remove of_device.h

Now that of_cpu_device_node_get() is defined in of.h, of_device.h is just
implicitly including other includes, and is no longer needed. Adjust the
include files with what was implicitly included by of_device.h (cpu.h and
of.h) and drop including of_device.h.

Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Link: https://lore.kernel.org/r/20230329-dt-cpu-header-cleanups-v1-18-581e2605fe47@kernel.org
Signed-off-by: Rob Herring <robh@kernel.org>


# 528f2d8d 22-Feb-2023 Viresh Kumar <viresh.kumar@linaro.org>

OPP: Move required opps configuration to specialized callback

The required-opps configuration is closely tied to genpd and performance
states at the moment and it is not very obvious that required-opps can
live without genpds. Though we don't support configuring required-opps
for non-genpd cases currently.

This commit aims at separating these parts, where configuring genpds
would be a special case of configuring the required-opps.

Add a specialized callback, set_required_opps(), to the opp table and
set it to different callbacks accordingly.

This shouldn't result in any functional changes for now.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>


# e9eadc28 10-Mar-2023 Rob Herring <robh@kernel.org>

opp: Use of_property_present() for testing DT property presence

It is preferred to use typed property access functions (i.e.
of_property_read_<type> functions) rather than low-level
of_get_property/of_find_property functions for reading properties. As
part of this, convert of_get_property/of_find_property calls to the
recently added of_property_present() helper when we just want to test
for presence of a property and nothing more.

Signed-off-by: Rob Herring <robh@kernel.org>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# 2eedf62e 03-Nov-2022 James Calligeros <jcalligeros99@gmail.com>

OPP: decouple dt properties in opp_parse_supplies()

The opp-microwatt property was added with the intention of providing
platforms a way to specify a precise value for the power consumption
of a device at a given OPP to enable better energy-aware scheduling
decisions by informing the kernel of the total static and dynamic
power of a device at a given OPP, removing the reliance on the EM
subsystem's often flawed estimations. This property is parsed by
opp_parse_supplies(), which creates a hard dependency on the
opp-microvolt property.

Some platforms, such as Apple Silicon, do not describe their device's
voltage regulators in the DT as they cannot be controlled by the kernel
and/or rely on opaque firmware algorithms to control their voltage and
current characteristics at runtime. We can, however, experimentally
determine the power consumption of a given device at a given OPP, taking
advantage of opp-microwatt to provide EAS on such devices as was
initially intended.

Allow platforms to specify and consume any subset of opp-microvolt,
opp-microamp, or opp-microwatt without a hard dependency on
opp-microvolt to enable this functionality on such platforms.

Tested-by: James Calligeros <jcalligeros99@gmail.com>
Signed-off-by: James Calligeros <jcalligeros99@gmail.com>
Co-developed-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# e5acb199 02-Nov-2022 Viresh Kumar <viresh.kumar@linaro.org>

OPP: Simplify opp_parse_supplies() by restructuring it

opp_parse_supplies() has grown into too big of a routine (~190 lines)
and it is not straight-forward to understand it anymore.

Break it into smaller routines and reduce code redundancy a bit by using
the same code to parse properties.

This shouldn't result in any logical changes.

Tested-by: James Calligeros <jcalligeros99@gmail.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# 71b09429 02-Nov-2022 Viresh Kumar <viresh.kumar@linaro.org>

OPP: Parse named opp-microwatt property too

We missed parsing the named opp-microwatt-<name> property, fix that.

Tested-by: James Calligeros <jcalligeros99@gmail.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# 3466ea2c 18-Jul-2022 Liang He <windhl@126.com>

OPP: Don't drop opp->np reference while it is still in use

The struct dev_pm_opp contains a reference of the DT node, opp->np,
throughout its lifetime. We should increase the refcount for the same
from _opp_add_static_v2(), and drop it while removing the OPP finally.

Signed-off-by: Liang He <windhl@126.com>
[ Viresh: Updated subject / commit log, create _of_clear_opp() and drop
reference from it]
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# ce736cf7 18-Jul-2022 Liang He <windhl@126.com>

OPP: Don't drop opp_table->np reference while it is still in use

The OPP table contains a reference of the DT node, opp_table->np,
throughout its lifetime. We shouldn't drop the refcount for the same
from _of_init_opp_table(), but do that while removing the OPP table
finally.

Signed-off-by: Liang He <windhl@126.com>
[ Viresh: Updated subject / commit log and drop reference from
_of_clear_opp_table() ]
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# 1e5fb384 04-Jul-2022 Viresh Kumar <viresh.kumar@linaro.org>

OPP: Remove dev{m}_pm_opp_of_add_table_noclk()

Remove the now unused variants and the now unnecessary "getclk"
parameter from few routines.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# 2083da24 09-Jun-2022 Viresh Kumar <viresh.kumar@linaro.org>

OPP: Allow multiple clocks for a device

This patch adds support to allow multiple clocks for a device.

The design is pretty much similar to how this is done for regulators,
and platforms can supply their own version of the config_clks() callback
if they have multiple clocks for their device. The core manages the
calls via opp_table->config_clks() eventually.

We have kept both "clk" and "clks" fields in the OPP table structure and
the reason is provided as a comment in _opp_set_clknames(). The same
isn't done for "rates" though and we use rates[0] at most of the places
now.

Co-developed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Tested-by: Jon Hunter <jonathanh@nvidia.com>
Tested-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
Tested-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# 8bdac14b 09-Jun-2022 Viresh Kumar <viresh.kumar@linaro.org>

OPP: Reuse _opp_compare_key() in _opp_add_static_v2()

Reuse _opp_compare_key() in _opp_add_static_v2() instead of just
comparing frequency while finding suspend frequency. Also add a comment
over _opp_compare_key() explaining its return values.

Tested-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# 4768914b 08-Jun-2022 Viresh Kumar <viresh.kumar@linaro.org>

OPP: Remove rate_not_available parameter to _opp_add()

commit 32715be4fe95 ("opp: Fix adding OPP entries in a wrong order if
rate is unavailable") removed the only user of this field, get rid of
rest of it now.

Tested-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# d6134583 09-Jun-2022 Viresh Kumar <viresh.kumar@linaro.org>

OPP: Use consistent names for OPP table instances

The OPP table is called "opp_table" at most of the places and "table" at
few. Make all of them follow the same naming convention, "opp_table".

Tested-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# ae6ccaa6 07-Jul-2022 Lukasz Luba <lukasz.luba@arm.com>

PM: EM: convert power field to micro-Watts precision and align drivers

The milli-Watts precision causes rounding errors while calculating
efficiency cost for each OPP. This is especially visible in the 'simple'
Energy Model (EM), where the power for each OPP is provided from OPP
framework. This can cause some OPPs to be marked inefficient, while
using micro-Watts precision that might not happen.

Update all EM users which access 'power' field and assume the value is
in milli-Watts.

Solve also an issue with potential overflow in calculation of energy
estimation on 32bit machine. It's needed now since the power value
(thus the 'cost' as well) are higher.

Example calculation which shows the rounding error and impact:

power = 'dyn-power-coeff' * volt_mV * volt_mV * freq_MHz

power_a_uW = (100 * 600mW * 600mW * 500MHz) / 10^6 = 18000
power_a_mW = (100 * 600mW * 600mW * 500MHz) / 10^9 = 18

power_b_uW = (100 * 605mW * 605mW * 600MHz) / 10^6 = 21961
power_b_mW = (100 * 605mW * 605mW * 600MHz) / 10^9 = 21

max_freq = 2000MHz

cost_a_mW = 18 * 2000MHz/500MHz = 72
cost_a_uW = 18000 * 2000MHz/500MHz = 72000

cost_b_mW = 21 * 2000MHz/600MHz = 70 // <- artificially better
cost_b_uW = 21961 * 2000MHz/600MHz = 73203

The 'cost_b_mW' (which is based on old milli-Watts) is misleadingly
better that the 'cost_b_uW' (this patch uses micro-Watts) and such
would have impact on the 'inefficient OPPs' information in the Cpufreq
framework. This patch set removes the rounding issue.

Signed-off-by: Lukasz Luba <lukasz.luba@arm.com>
Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>


# 907ed123 06-Apr-2022 Dan Carpenter <dan.carpenter@oracle.com>

OPP: call of_node_put() on error path in _bandwidth_supported()

This code does not call of_node_put(opp_np) if of_get_next_available_child()
returns NULL. But it should.

Fixes: 45679f9b508f ("opp: Don't parse icc paths unnecessarily")
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# 75a3a99a 21-Mar-2022 Lukasz Luba <lukasz.luba@arm.com>

PM: EM: Change the order of arguments in the .active_power() callback

The .active_power() callback passes the device pointer when it's called.
Aligned with a convetion present in other subsystems and pass the 'dev'
as a first argument. It looks more cleaner.

Adjust all affected drivers which implement that API callback.

Suggested-by: Ionela Voinescu <ionela.voinescu@arm.com>
Signed-off-by: Lukasz Luba <lukasz.luba@arm.com>
Reviewed-by: Ionela Voinescu <ionela.voinescu@arm.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>


# 32bf8bc9 02-Mar-2022 Lukasz Luba <lukasz.luba@arm.com>

OPP: Add support of "opp-microwatt" for EM registration

The Energy Model (EM) can be created based on DT entry:
'dynamic-power-coefficient'. It's a 'simple' EM which is limited to the
dynamic power. It has to fit into the math formula which requires also
information about voltage. Some of the platforms don't expose voltage
information, thus it's not possible to use EM registration using DT.

This patch aims to fix it. It introduces new implementation of the EM
registration callback. The new mechanism relies on the new OPP feature
allowing to get power (which is coming from "opp-microwatt" DT property)
expressed in micro-Watts.

The patch also opens new opportunity to better support platforms, which
have a decent static power. It allows to register the EM based on real
power measurements which models total power (static + dynamic), so better
reflects real HW.

Signed-off-by: Lukasz Luba <lukasz.luba@arm.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# 4f9a7a1d 02-Mar-2022 Lukasz Luba <lukasz.luba@arm.com>

OPP: Add "opp-microwatt" supporting code

Add new property to the OPP: power value. The OPP entry in the DT can have
"opp-microwatt". Add the needed code to handle this new property in the
existing infrastructure.

Signed-off-by: Lukasz Luba <lukasz.luba@arm.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# 27ff8187 08-Oct-2021 YueHaibing <yuehaibing@huawei.com>

opp: Fix return in _opp_add_static_v2()

Fix sparse warning:
drivers/opp/of.c:924 _opp_add_static_v2() warn: passing zero to 'ERR_PTR'

For duplicate OPPs 'ret' be set to zero.

Fixes: deac8703da5f ("PM / OPP: _of_add_opp_table_v2(): increment count only if OPP is added")
Signed-off-by: YueHaibing <yuehaibing@huawei.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# e69709f6 20-Sep-2021 Dmitry Osipenko <digetx@gmail.com>

opp: Add more resource-managed variants of dev_pm_opp_of_add_table()

Add resource-managed variants of dev_pm_opp_of_add_table_indexed() and
dev_pm_opp_of_add_table_noclk(), allowing drivers to remove boilerplate
code.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
[ Viresh: Added underscore to devm_of_add_table_indexed() ]
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# 8b7912f4 30-Sep-2021 Pavankumar Kondeti <pkondeti@codeaurora.org>

opp: Fix required-opps phandle array count check

The 'required-opps' property is optional. So of_count_phandle_with_args()
can return -ENOENT when queried for required-opps. Handle this case.

Signed-off-by: Pavankumar Kondeti <pkondeti@codeaurora.org>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# 020d86fc 12-Aug-2021 Rajendra Nayak <rnayak@codeaurora.org>

opp: Don't print an error if required-opps is missing

The 'required-opps' property is considered optional, hence remove
the pr_err() in of_parse_required_opp() when we find the property is
missing.
While at it, also fix the return value of
of_get_required_opp_performance_state() when of_parse_required_opp()
fails, return a -ENODEV instead of the -EINVAL.

Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>


# 335ffab3 26-Jul-2021 Michał Mirosław <mirq-linux@rere.qmqm.pl>

opp: remove WARN when no valid OPPs remain

This WARN can be triggered per-core and the stack trace is not useful.
Replace it with plain dev_err(). Fix a comment while at it.

Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# 4fa82a87 15-Jun-2021 Hsin-Yi Wang <hsinyi@chromium.org>

opp: Allow required-opps to be used for non genpd use cases

Don't limit required_opp_table to genpd only. One possible use case is
cpufreq based devfreq governor, which can use required-opps property to
derive devfreq from cpufreq.

Though the OPP core still doesn't support non-genpd required-opps in
_set_required_opps().

Suggested-by: Chanwoo Choi <cw00.choi@samsung.com>
Signed-off-by: Hsin-Yi Wang <hsinyi@chromium.org>
[ Viresh: Update _set_required_opps() to check for genpd ]
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# ac9fd3c8 17-May-2021 Yang Yingliang <yangyingliang@huawei.com>

opp: use list_del_init instead of list_del/INIT_LIST_HEAD

Using list_del_init() instead of list_del() + INIT_LIST_HEAD()
to simpify the code.

Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# 3d5cfbb6 14-Mar-2021 Yangtao Li <tiny.windzz@gmail.com>

opp: Add devres wrapper for dev_pm_opp_of_add_table

Add devres wrapper for dev_pm_opp_of_add_table() to simplify drivers
code.

Signed-off-by: Yangtao Li <tiny.windzz@gmail.com>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# 7eba0c76 25-Nov-2019 Viresh Kumar <viresh.kumar@linaro.org>

opp: Allow lazy-linking of required-opps

The OPP core currently requires the required opp tables to be available
before the dependent OPP table is added, as it needs to create links
from the dependent OPP table to the required ones. This may not be
convenient for all the platforms though, as this requires strict
ordering for probing the drivers.

This patch allows lazy-linking of the required-opps. The OPP tables for
which the required-opp-tables aren't available at the time of their
initialization, are added to a special list of OPP tables:
lazy_opp_tables. Later on, whenever a new OPP table is registered with
the OPP core, we check if it is required by an OPP table in the pending
list; if yes, then we complete the linking then and there.

An OPP table is marked unusable until the time all its required-opp
tables are available. And if lazy-linking fails for an OPP table, the
OPP core disables all of its OPPs to make sure no one can use them.

Tested-by: Hsin-Yi Wang <hsinyi@chromium.org>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# b6ecd5d4 17-Jan-2021 Dmitry Osipenko <digetx@gmail.com>

opp: Print OPP level in debug message of _opp_add_static_v2()

Print OPP level in debug message of _opp_add_static_v2(). This helps to
chase GENPD bugs.

Tested-by: Peter Geis <pgwipeout@gmail.com>
Tested-by: Nicolas Chauvet <kwizart@gmail.com>
Tested-by: Matt Merhar <mattmerhar@protonmail.com>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# 559fef0d 27-Jan-2021 Viresh Kumar <viresh.kumar@linaro.org>

opp: Add dev_pm_opp_of_add_table_noclk()

A few drivers have device's clk but they don't want the OPP core to
handle that. Add a new helper for them, dev_pm_opp_of_add_table_noclk().

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Tested-by: Dmitry Osipenko <digetx@gmail.com>


# 32439ac7 27-Jan-2021 Viresh Kumar <viresh.kumar@linaro.org>

opp: Defer acquiring the clk until OPPs are added

We acquire the clk at the time the OPP table is allocated, though it
works fine, it is not the best place to do so. One of the main reason
being we may need to acquire it again from dev_pm_opp_set_clkname() if
the platform wants another clock to be acquired instead.

There is also requirement from some of the platforms where they do not
want the OPP core to manage the clock at all.

This patch hence defers acquiring the clk until the time we are certain
about which clk we need to acquire and if we really need to acquire one.
With this commit, the clk will get acquired either from
dev_pm_opp_set_clkname() or while we initialize the OPPs within the
table.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Tested-by: Dmitry Osipenko <digetx@gmail.com>


# 406e4765 26-Jan-2021 Viresh Kumar <viresh.kumar@linaro.org>

opp: Create _of_add_table_indexed() to reduce code duplication

The implementation of dev_pm_opp_of_add_table() and
dev_pm_opp_of_add_table_indexed() are almost identical. Create
_of_add_table_indexed() to reduce code redundancy.

Also remove the duplication of the doc style comments by referring to
dev_pm_opp_of_add_table() from dev_pm_opp_of_add_table_indexed().

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Tested-by: Dmitry Osipenko <digetx@gmail.com>


# d7b9d9b3 17-Jan-2021 Dmitry Osipenko <digetx@gmail.com>

opp: Correct debug message in _opp_add_static_v2()

The debug message always prints rate=0 instead of a proper value, fix it.

Fixes: 6c591eec67cb ("OPP: Add helpers for reading the binding properties")
Tested-by: Peter Geis <pgwipeout@gmail.com>
Tested-by: Nicolas Chauvet <kwizart@gmail.com>
Tested-by: Matt Merhar <mattmerhar@protonmail.com>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
[ Viresh: Added Fixes tag ]
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# 6ee70e8c 08-Dec-2020 Nicola Mazzucato <nicola.mazzucato@arm.com>

opp: of: Allow empty opp-table with opp-shared

The opp binding now allows to have an empty opp table and shared-opp to
still describe that devices share v/f lines.

When initialising an empty opp table, allow such case by:
- treating such conditions with warnings in place of errors
- don't fail on empty table

Signed-off-by: Nicola Mazzucato <nicola.mazzucato@arm.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# e77dcb0b 05-Nov-2020 Viresh Kumar <viresh.kumar@linaro.org>

opp: Don't create an OPP table from dev_pm_opp_get_opp_table()

It has been found that some users (like cpufreq-dt and others on LKML)
have abused the helper dev_pm_opp_get_opp_table() to create the OPP
table instead of just finding it, which is the wrong thing to do. This
routine was meant for OPP core's internal working and exposed the whole
functionality by mistake.

Change the scope of dev_pm_opp_get_opp_table() to only finding the
table. The internal helpers _opp_get_opp_table*() are thus renamed to
_add_opp_table*(), dev_pm_opp_get_opp_table_indexed() is removed (as we
don't need the index field for finding the OPP table) and so the only
user, genpd, is updated.

Note that the prototype of _add_opp_table() was already left in opp.h by
mistake when it was removed earlier and so we weren't required to add it
now.

Acked-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# c250d50f 04-Nov-2020 Lukasz Luba <lukasz.luba@arm.com>

PM: EM: Add a flag indicating units of power values in Energy Model

There are different platforms and devices which might use different scale
for the power values. Kernel sub-systems might need to check if all
Energy Model (EM) devices are using the same scale. Address that issue and
store the information inside EM for each device. Thanks to that they can
be easily compared and proper action triggered.

Suggested-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Reviewed-by: Quentin Perret <qperret@google.com>
Signed-off-by: Lukasz Luba <lukasz.luba@arm.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>


# 27c09484 27-Oct-2020 Viresh Kumar <viresh.kumar@linaro.org>

opp: Allocate the OPP table outside of opp_table_lock

There is no critical section which needs protection with locks while
allocating an OPP table, except while adding it to the opp_tables list.
And taking the opp_table_lock for the entire duration causes circular
dependency issues like the one mentioned below. This patch takes
another approach to reduce the size of the critical section to avoid
such issues, the details of that are present within the patch.

======================================================
WARNING: possible circular locking dependency detected
5.4.72 #14 Not tainted
------------------------------------------------------
chrome/1865 is trying to acquire lock:
ffffffdd34921750 (opp_table_lock){+.+.}, at: _find_opp_table+0x34/0x74

but task is already holding lock:
ffffff81f0fc71a8 (reservation_ww_class_mutex){+.+.}, at: submit_lock_objects+0x70/0x1ec

fscrypt: AES-256-CTS-CBC using implementation "cts-cbc-aes-ce"
which lock already depends on the new lock.

the existing dependency chain (in reverse order) is:
-> #4 (reservation_ww_class_mutex){+.+.}:
__mutex_lock_common+0xec/0xc0c
ww_mutex_lock_interruptible+0x5c/0xc4
msm_gem_fault+0x2c/0x124
__do_fault+0x40/0x16c
handle_mm_fault+0x7cc/0xd98
do_page_fault+0x230/0x3b4
do_translation_fault+0x5c/0x78
do_mem_abort+0x4c/0xb4
el0_da+0x1c/0x20
-> #3 (&mm->mmap_sem){++++}:
__might_fault+0x70/0x98
compat_filldir+0xf8/0x48c
dcache_readdir+0x70/0x1dc
iterate_dir+0xd4/0x180
__arm64_compat_sys_getdents+0xa0/0x19c
el0_svc_common+0xa8/0x178
el0_svc_compat_handler+0x2c/0x40
el0_svc_compat+0x8/0x10
-> #2 (&sb->s_type->i_mutex_key#3){++++}:
down_write+0x54/0x16c
start_creating+0x68/0x128
debugfs_create_dir+0x28/0x114
opp_debug_register+0x8c/0xc0
_add_opp_dev_unlocked+0x5c/0x70
_add_opp_dev+0x38/0x58
_opp_get_opp_table+0xdc/0x1ac
dev_pm_opp_get_opp_table_indexed+0x24/0x30
dev_pm_opp_of_add_table_indexed+0x48/0x84
of_genpd_add_provider_onecell+0xc0/0x1b8
rpmhpd_probe+0x240/0x268
platform_drv_probe+0x90/0xb0
really_probe+0x134/0x2ec
driver_probe_device+0x64/0xfc
__device_attach_driver+0x8c/0xa4
bus_for_each_drv+0x90/0xd8
__device_attach+0xc0/0x148
device_initial_probe+0x20/0x2c
bus_probe_device+0x34/0x94
device_add+0x1fc/0x3b0
of_device_add+0x3c/0x4c
of_platform_device_create_pdata+0xb8/0xfc
of_platform_bus_create+0x1e4/0x368
of_platform_populate+0x70/0xbc
devm_of_platform_populate+0x58/0xa0
rpmh_rsc_probe+0x36c/0x3cc
platform_drv_probe+0x90/0xb0
really_probe+0x134/0x2ec
driver_probe_device+0x64/0xfc
__device_attach_driver+0x8c/0xa4
bus_for_each_drv+0x90/0xd8
__device_attach+0xc0/0x148
device_initial_probe+0x20/0x2c
bus_probe_device+0x34/0x94
device_add+0x1fc/0x3b0
of_device_add+0x3c/0x4c
of_platform_device_create_pdata+0xb8/0xfc
of_platform_bus_create+0x1e4/0x368
of_platform_bus_create+0x230/0x368
of_platform_populate+0x70/0xbc
of_platform_default_populate_init+0xa8/0xc0
do_one_initcall+0x1c8/0x3fc
do_initcall_level+0xb4/0x10c
do_basic_setup+0x30/0x48
kernel_init_freeable+0x124/0x1a4
kernel_init+0x14/0x104
ret_from_fork+0x10/0x18
-> #1 (&opp_table->lock){+.+.}:
__mutex_lock_common+0xec/0xc0c
mutex_lock_nested+0x40/0x50
_add_opp_dev+0x2c/0x58
_opp_get_opp_table+0xdc/0x1ac
dev_pm_opp_get_opp_table_indexed+0x24/0x30
dev_pm_opp_of_add_table_indexed+0x48/0x84
of_genpd_add_provider_onecell+0xc0/0x1b8
rpmhpd_probe+0x240/0x268
platform_drv_probe+0x90/0xb0
really_probe+0x134/0x2ec
driver_probe_device+0x64/0xfc
__device_attach_driver+0x8c/0xa4
bus_for_each_drv+0x90/0xd8
__device_attach+0xc0/0x148
device_initial_probe+0x20/0x2c
bus_probe_device+0x34/0x94
device_add+0x1fc/0x3b0
of_device_add+0x3c/0x4c
of_platform_device_create_pdata+0xb8/0xfc
of_platform_bus_create+0x1e4/0x368
of_platform_populate+0x70/0xbc
devm_of_platform_populate+0x58/0xa0
rpmh_rsc_probe+0x36c/0x3cc
platform_drv_probe+0x90/0xb0
really_probe+0x134/0x2ec
driver_probe_device+0x64/0xfc
__device_attach_driver+0x8c/0xa4
bus_for_each_drv+0x90/0xd8
__device_attach+0xc0/0x148
device_initial_probe+0x20/0x2c
bus_probe_device+0x34/0x94
device_add+0x1fc/0x3b0
of_device_add+0x3c/0x4c
of_platform_device_create_pdata+0xb8/0xfc
of_platform_bus_create+0x1e4/0x368
of_platform_populate+0x70/0xbc
devm_of_platform_populate+0x58/0xa0
rpmh_rsc_probe+0x36c/0x3cc
platform_drv_probe+0x90/0xb0
really_probe+0x134/0x2ec
driver_probe_device+0x64/0xfc
__device_attach_driver+0x8c/0xa4
bus_for_each_drv+0x90/0xd8
__device_attach+0xc0/0x148
device_initial_probe+0x20/0x2c
bus_probe_device+0x34/0x94
device_add+0x1fc/0x3b0
of_device_add+0x3c/0x4c
of_platform_device_create_pdata+0xb8/0xfc
of_platform_bus_create+0x1e4/0x368
of_platform_bus_create+0x230/0x368
of_platform_populate+0x70/0xbc
of_platform_default_populate_init+0xa8/0xc0
do_one_initcall+0x1c8/0x3fc
do_initcall_level+0xb4/0x10c
do_basic_setup+0x30/0x48
kernel_init_freeable+0x124/0x1a4
kernel_init+0x14/0x104
ret_from_fork+0x10/0x18
-> #0 (opp_table_lock){+.+.}:
__lock_acquire+0xee4/0x2450
lock_acquire+0x1cc/0x210
__mutex_lock_common+0xec/0xc0c
mutex_lock_nested+0x40/0x50
_find_opp_table+0x34/0x74
dev_pm_opp_find_freq_exact+0x2c/0xdc
a6xx_gmu_resume+0xc8/0xecc
a6xx_pm_resume+0x148/0x200
adreno_resume+0x28/0x34
pm_generic_runtime_resume+0x34/0x48
__rpm_callback+0x70/0x10c
rpm_callback+0x34/0x8c
rpm_resume+0x414/0x550
__pm_runtime_resume+0x7c/0xa0
msm_gpu_submit+0x60/0x1c0
msm_ioctl_gem_submit+0xadc/0xb60
drm_ioctl_kernel+0x9c/0x118
drm_ioctl+0x27c/0x408
drm_compat_ioctl+0xcc/0xdc
__se_compat_sys_ioctl+0x100/0x206c
__arm64_compat_sys_ioctl+0x20/0x2c
el0_svc_common+0xa8/0x178
el0_svc_compat_handler+0x2c/0x40
el0_svc_compat+0x8/0x10
other info that might help us debug this:
Chain exists of: opp_table_lock --> &mm->mmap_sem --> reservation_ww_class_mutex
Possible unsafe locking scenario:
CPU0 CPU1
---- ----
lock(reservation_ww_class_mutex);
lock(&mm->mmap_sem);
lock(reservation_ww_class_mutex);
lock(opp_table_lock);

*** DEADLOCK ***

3 locks held by chrome/1865:
#0: ffffff81edecc0d8 (&dev->struct_mutex){+.+.}, at: msm_ioctl_gem_submit+0x264/0xb60
#1: ffffff81d0000870 (reservation_ww_class_acquire){+.+.}, at: msm_ioctl_gem_submit+0x8e8/0xb60
#2: ffffff81f0fc71a8 (reservation_ww_class_mutex){+.+.}, at: submit_lock_objects+0x70/0x1ec
stack backtrace:
CPU: 0 PID: 1865 Comm: chrome Not tainted 5.4.72 #14
Hardware name: Google Lazor (rev1+) with LTE (DT)
Call trace:
dump_backtrace+0x0/0x158
show_stack+0x20/0x2c
dump_stack+0xc8/0x160
print_circular_bug+0x2c4/0x2c8
check_noncircular+0x1a8/0x1b0
__lock_acquire+0xee4/0x2450
lock_acquire+0x1cc/0x210
__mutex_lock_common+0xec/0xc0c
mutex_lock_nested+0x40/0x50
_find_opp_table+0x34/0x74
dev_pm_opp_find_freq_exact+0x2c/0xdc
a6xx_gmu_resume+0xc8/0xecc
a6xx_pm_resume+0x148/0x200
adreno_resume+0x28/0x34
pm_generic_runtime_resume+0x34/0x48
__rpm_callback+0x70/0x10c
rpm_callback+0x34/0x8c
rpm_resume+0x414/0x550
__pm_runtime_resume+0x7c/0xa0
msm_gpu_submit+0x60/0x1c0
msm_ioctl_gem_submit+0xadc/0xb60
drm_ioctl_kernel+0x9c/0x118
drm_ioctl+0x27c/0x408
drm_compat_ioctl+0xcc/0xdc
__se_compat_sys_ioctl+0x100/0x206c
__arm64_compat_sys_ioctl+0x20/0x2c
el0_svc_common+0xa8/0x178
el0_svc_compat_handler+0x2c/0x40
el0_svc_compat+0x8/0x10

Reported-by: Rob Clark <robdclark@gmail.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# 1f6620f8 13-Oct-2020 Viresh Kumar <viresh.kumar@linaro.org>

opp: Don't always remove static OPPs in _of_add_opp_table_v1()

The patch missed returning 0 early in case of success and hence the
static OPPs got removed by mistake. Fix it.

Fixes: 90d46d71cce2 ("opp: Handle multiple calls for same OPP table in _of_add_opp_table_v1()")
Reported-by: Aisheng Dong <aisheng.dong@nxp.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Tested-by: Dong Aisheng <aisheng.dong@nxp.com>


# a5663c9b 11-Sep-2020 Viresh Kumar <viresh.kumar@linaro.org>

opp: Allow opp-level to be set to 0

The DT bindings don't put such a constraint, nor should the kernel. It
is perfectly fine for opp-level to be set to 0, if we need to put the
performance state votes for a domain for a particular OPP.

Reported-by: Stephan Gerhold <stephan@gerhold.net>
Tested-by: Stephan Gerhold <stephan@gerhold.net>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# 0ff25c99 26-Aug-2020 Viresh Kumar <viresh.kumar@linaro.org>

opp: Allow opp-supported-hw to contain multiple versions

The bindings allow multiple versions to be passed to "opp-supported-hw"
property, either of which can result in enabling of the OPP.

Update code to allow that.

Tested-by: Stephan Gerhold <stephan@gerhold.net>
Tested-by: Dmitry Osipenko <digetx@gmail.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# 90d46d71 01-Sep-2020 Viresh Kumar <viresh.kumar@linaro.org>

opp: Handle multiple calls for same OPP table in _of_add_opp_table_v1()

Until now for V1 OPP bindings we used to call
dev_pm_opp_of_cpumask_add_table() first and then
dev_pm_opp_set_sharing_cpus() in the cpufreq-dt driver.

A later patch will though update the cpufreq-dt driver to optimize the
code a bit and we will call dev_pm_opp_set_sharing_cpus() first followed
by dev_pm_opp_of_cpumask_add_table(), which doesn't work well today as
it tries to re parse the OPP entries. This should work nevertheless for
V1 bindings as the same works for V2 bindings.

Adapt the same approach from V2 bindings and fix this.

Reported-by: Marek Szyprowski <m.szyprowski@samsung.com>
Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# dd461cd9 27-Jul-2020 Stephan Gerhold <stephan@gerhold.net>

opp: Allow dev_pm_opp_get_opp_table() to return -EPROBE_DEFER

The OPP core manages various resources, e.g. clocks or interconnect paths.
These resources are looked up when the OPP table is allocated once
dev_pm_opp_get_opp_table() is called the first time (either directly
or indirectly through one of the many helper functions).

At this point, the resources may not be available yet, i.e. looking them
up will result in -EPROBE_DEFER. Unfortunately, dev_pm_opp_get_opp_table()
is currently unable to propagate this error code since it only returns
the allocated OPP table or NULL.

This means that all consumers of the OPP core are required to make sure
that all necessary resources are available. Usually this happens by
requesting them, checking the result and releasing them immediately after.

For example, we have added "dev_pm_opp_of_find_icc_paths(dev, NULL)" to
several drivers now just to make sure the interconnect providers are
ready before the OPP table is allocated. If this call is missing,
the OPP core will only warn about this and then attempt to continue
without interconnect. This will eventually fail horribly, e.g.:

cpu cpu0: _allocate_opp_table: Error finding interconnect paths: -517
... later ...
of: _read_bw: Mismatch between opp-peak-kBps and paths (1 0)
cpu cpu0: _opp_add_static_v2: opp key field not found
cpu cpu0: _of_add_opp_table_v2: Failed to add OPP, -22

This example happens when trying to use interconnects for a CPU OPP
table together with qcom-cpufreq-nvmem.c. qcom-cpufreq-nvmem calls
dev_pm_opp_set_supported_hw(), which ends up allocating the OPP table
early. To fix the problem with the current approach we would need to add
yet another call to dev_pm_opp_of_find_icc_paths(dev, NULL).
But actually qcom-cpufreq-nvmem.c has nothing to do with interconnects...

This commit attempts to make this more robust by allowing
dev_pm_opp_get_opp_table() to return an error pointer. Fixing all
the usages is trivial because the function is usually used indirectly
through another helper (e.g. dev_pm_opp_set_supported_hw() above).
These other helpers already return an error pointer.

The example above then works correctly because set_supported_hw() will
return -EPROBE_DEFER, and qcom-cpufreq-nvmem.c already propagates that
error. It should also be possible to remove the remaining usages of
"dev_pm_opp_of_find_icc_paths(dev, NULL)" from other drivers as well.

Note that this commit currently only handles -EPROBE_DEFER for the
clock/interconnects within _allocate_opp_table(). Other errors are just
ignored as before. Eventually those should be propagated as well.

Signed-off-by: Stephan Gerhold <stephan@gerhold.net>
Acked-by: Krzysztof Kozlowski <krzk@kernel.org>
Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
[ Viresh: skip checking return value of dev_pm_opp_get_opp_table() for
EPROBE_DEFER in domain.c, fix NULL return value and reorder
code a bit in core.c, and update exynos-asv.c ]
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# 8aaf6264 20-Aug-2020 Viresh Kumar <viresh.kumar@linaro.org>

opp: Remove _dev_pm_opp_find_and_remove_table() wrapper

Remove the unnecessary wrapper and merge
_dev_pm_opp_find_and_remove_table() with dev_pm_opp_remove_table().

Tested-by: Rajendra Nayak <rnayak@codeaurora.org>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# 6544abc5 15-Jul-2020 Walter Lozano <walter.lozano@collabora.com>

opp: Increase parsed_static_opps in _of_add_opp_table_v1()

Currently, when using _of_add_opp_table_v2 parsed_static_opps is
increased and this value is used in _opp_remove_all_static() to
check if there are static opp entries that need to be freed.
Unfortunately this does not happen when using _of_add_opp_table_v1(),
which leads to warnings.

This patch increases parsed_static_opps in _of_add_opp_table_v1() in a
similar way as in _of_add_opp_table_v2().

Fixes: 03758d60265c ("opp: Replace list_kref with a local counter")
Cc: v5.6+ <stable@vger.kernel.org> # v5.6+
Signed-off-by: Walter Lozano <walter.lozano@collabora.com>
[ Viresh: Do the operation with lock held and set the value to 1 instead
of incrementing it ]
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# 0e0ffa85 27-May-2020 Lukasz Luba <lukasz.luba@arm.com>

OPP: refactor dev_pm_opp_of_register_em() and update related drivers

The Energy Model framework supports not only CPU devices. Drop the CPU
specific interface with cpumask and add struct device. Add also a return
value, user might use it. This new interface provides easy way to create
a simple Energy Model, which then might be used by e.g. thermal subsystem.

Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Signed-off-by: Lukasz Luba <lukasz.luba@arm.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>


# d0351cc3 27-May-2020 Lukasz Luba <lukasz.luba@arm.com>

PM / EM: update callback structure and add device pointer

The Energy Model framework is going to support devices other that CPUs. In
order to make this happen change the callback function and add pointer to
a device as an argument.

Update the related users to use new function and new callback from the
Energy Model.

Acked-by: Quentin Perret <qperret@google.com>
Signed-off-by: Lukasz Luba <lukasz.luba@arm.com>
Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>


# 45679f9b 27-May-2020 Sibi Sankar <sibis@codeaurora.org>

opp: Don't parse icc paths unnecessarily

The DT node of the device may contain interconnect paths while the OPP
table doesn't have the bandwidth values. There is no need to parse the
paths in such cases.

Signed-off-by: Sibi Sankar <sibis@codeaurora.org>
Tested-by: Sibi Sankar <sibis@codeaurora.org>
Reviewed-by: Sibi Sankar <sibis@codeaurora.org>
[ Viresh: Support the case of !opp_table and massaged changelog ]
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# 120e117b 12-May-2020 Georgi Djakov <georgi.djakov@linaro.org>

opp: Add sanity checks in _read_opp_key()

When we read the OPP keys, it would be nice to do some sanity checks
of the values we get from DT and see if they match with the information
that is populated in the OPP table. Let's pass a pointer of the table,
so that we can do some validation.

Signed-off-by: Georgi Djakov <georgi.djakov@linaro.org>
Reviewed-by: Matthias Kaehlcke <mka@chromium.org>
Reviewed-by: Sibi Sankar <sibis@codeaurora.org>
[ Viresh: Fix rebase conflicts ]
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# 6d3f922c 12-May-2020 Georgi Djakov <georgi.djakov@linaro.org>

opp: Add support for parsing interconnect bandwidth

The OPP bindings now support bandwidth values, so add support to parse it
from device tree and store it into the new dev_pm_opp_icc_bw struct, which
is part of the dev_pm_opp.

Signed-off-by: Georgi Djakov <georgi.djakov@linaro.org>
Reviewed-by: Matthias Kaehlcke <mka@chromium.org>
[ Viresh: Create _read_bw() and use it, renamed _of_find_icc_paths() to
dev_pm_opp_of_find_icc_paths(), exported it and made opp_table
argument optional. Also drop the depends on from Kconfig. ]
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# 6c591eec 12-May-2020 Saravana Kannan <saravanak@google.com>

OPP: Add helpers for reading the binding properties

The opp-hz DT property is not mandatory and we may use another property
as a key in the OPP table. Add helper functions to simplify the reading
and comparing the keys.

Signed-off-by: Saravana Kannan <saravanak@google.com>
Signed-off-by: Georgi Djakov <georgi.djakov@linaro.org>
Reviewed-by: Matthias Kaehlcke <mka@chromium.org>
Reviewed-by: Sibi Sankar <sibis@codeaurora.org>
[ Viresh: Removed an unnecessary comment ]
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# 03758d60 11-Nov-2019 Viresh Kumar <viresh.kumar@linaro.org>

opp: Replace list_kref with a local counter

A kref or refcount isn't the right tool to be used here for counting
number of devices that are sharing the static OPPs created for the OPP
table. For example, we are reinitializing the kref again, after it
reaches a value of 0 and frees the resources, if the static OPPs get
added for the same OPP table structure (as the OPP table structure was
never freed). That is messy and very unclear.

This patch makes parsed_static_opps an unsigned integer and uses it to
count the number of users of the static OPPs. The increment and
decrement to parsed_static_opps is done under opp_table->lock now to
make sure no races are possible if the OPP table is getting added and
removed in parallel (which doesn't happen in practice, but can in
theory).

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# ba003319 18-Nov-2019 Viresh Kumar <viresh.kumar@linaro.org>

opp: Free static OPPs on errors while adding them

The static OPPs aren't getting freed properly, if errors occur while
adding them. Fix that by calling _put_opp_list_kref() and putting their
reference on failures.

Fixes: 11e1a1648298 ("opp: Don't decrement uninitialized list_kref")
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# b19c2355 18-Oct-2019 Viresh Kumar <viresh.kumar@linaro.org>

opp: Reinitialize the list_kref before adding the static OPPs again

The list_kref reaches a count of 0 when all the static OPPs are removed,
for example when dev_pm_opp_of_cpumask_remove_table() is called, though
the actual OPP table may not get freed as it may still be referenced by
other parts of the kernel, like from a call to
dev_pm_opp_set_supported_hw(). And if we call
dev_pm_opp_of_cpumask_add_table() again at this point, we must
reinitialize the list_kref otherwise the kernel will hit a WARN() in
kref infrastructure for incrementing a kref with value 0.

Fixes: 11e1a1648298 ("opp: Don't decrement uninitialized list_kref")
Reported-by: Dmitry Osipenko <digetx@gmail.com>
Tested-by: Dmitry Osipenko <digetx@gmail.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# f2edbb66 10-Oct-2019 Viresh Kumar <viresh.kumar@linaro.org>

opp: of: drop incorrect lockdep_assert_held()

_find_opp_of_np() doesn't traverse the list of OPP tables but instead
just the entries within an OPP table and so only requires to lock the
OPP table itself.

The lockdep_assert_held() was added there by mistake and isn't really
required.

Fixes: 5d6d106fa455 ("OPP: Populate required opp tables from "required-opps" property")
Cc: v5.0+ <stable@vger.kernel.org> # v5.0+
Reported-by: Niklas Cassel <niklas.cassel@linaro.org>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# 45275517 09-Jul-2019 Anson Huang <Anson.Huang@nxp.com>

opp: of: Support multiple suspend OPPs defined in DT

With property "opp-supported-hw" introduced, the OPP table
in DT could be a large OPP table and ONLY a subset of OPPs
are available, based on the version of the hardware running
on. That introduces restriction of using "opp-suspend"
property to define the suspend OPP, as we are NOT sure if the
OPP containing "opp-suspend" property is available for the
hardware running on, and the of opp core does NOT allow multiple
suspend OPPs defined in DT OPP table.

To eliminate this restrition, make of opp core allow multiple
suspend OPPs defined in DT, and pick the OPP with highest rate
and with "opp-suspend" property present to be suspend OPP, it
can speed up the suspend/resume process.

Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# 11e1a164 03-Jul-2019 Viresh Kumar <viresh.kumar@linaro.org>

opp: Don't decrement uninitialized list_kref

The list_kref was added for static OPPs and to track their users. The
kref is initialized while the static OPPs are added, but removed
unconditionally even if the static OPPs were never added. This causes
refcount mismatch warnings currently.

Fix that by always initializing the kref when the OPP table is first
initialized. The refcount is later incremented only for the second user
onwards.

Fixes: d0e8ae6c26da ("OPP: Create separate kref for static OPPs list")
Reported-by: Rajendra Nayak <rnayak@codeaurora.org>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# d2912cb1 04-Jun-2019 Thomas Gleixner <tglx@linutronix.de>

treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 500

Based on 2 normalized pattern(s):

this program is free software you can redistribute it and or modify
it under the terms of the gnu general public license version 2 as
published by the free software foundation

this program is free software you can redistribute it and or modify
it under the terms of the gnu general public license version 2 as
published by the free software foundation #

extracted by the scancode license scanner the SPDX license identifier

GPL-2.0-only

has been chosen to replace the boilerplate/reference in 4122 file(s).

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Enrico Weigelt <info@metux.net>
Reviewed-by: Kate Stewart <kstewart@linuxfoundation.org>
Reviewed-by: Allison Randal <allison@lohutok.net>
Cc: linux-spdx@vger.kernel.org
Link: https://lkml.kernel.org/r/20190604081206.933168790@linutronix.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>


# c0ab9e08 08-May-2019 Viresh Kumar <viresh.kumar@linaro.org>

opp: Allocate genpd_virt_devs from dev_pm_opp_attach_genpd()

Currently the space for the array of virtual devices is allocated along
with the OPP table, but that isn't going to work well from now onwards.
For single power domain case, a driver can either use the original
device structure for setting the performance state (if genpd attached
with dev_pm_domain_attach()) or use the virtual device structure (if
genpd attached with dev_pm_domain_attach_by_name(), which returns the
virtual device) and so we can't know in advance if we are going to need
genpd_virt_devs array or not.

Lets delay the allocation a bit and do it along with
dev_pm_opp_attach_genpd() rather. The deallocation is done from
dev_pm_opp_detach_genpd().

Tested-by: Niklas Cassel <niklas.cassel@linaro.org>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# 55286a29 05-Mar-2019 Rajendra Nayak <rnayak@codeaurora.org>

OPP: Fix handling of multiple power domains

We seem to rely on the number of phandles specified in the
'required-opps' property to identify cases where a device is
associated with multiple power domains and hence would have
multiple virtual devices that have to be dealt with.

In cases where we do have devices with multiple power domains
but with only one of them being scalable, this logic seems to
fail.

Instead read the number of power domains from DT to identify
such cases.

Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
Reviewed-by: Stephen Boyd <sboyd@kernel.org>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>


# a4f342b9 04-Feb-2019 Quentin Perret <qperret@qperret.net>

PM / OPP: Introduce a power estimation helper

The Energy Model (EM) framework provides an API to let drivers register
the active power of CPUs. The drivers are expected to provide a callback
method which estimates the power consumed by a CPU at each available
performance levels. How exactly this should be implemented, however,
depends on the platform.

On some systems, PM_OPP knows the voltage and frequency at which CPUs
can run. When coupled with the CPU 'capacitance' (as provided by the
'dynamic-power-coefficient' devicetree binding), it is possible to
estimate the dynamic power consumption of a CPU as P = C * V^2 * f, with
C its capacitance and V and f respectively the voltage and frequency of
the OPP. The Intelligent Power Allocator (IPA) thermal governor already
implements that estimation method, in the thermal framework.

However, this power estimation method can be applied to any platform
where all the parameters are known (C, V and f), and not only those
suffering thermal issues. As such, the code implementing this feature
can be re-used to also populate the EM framework now used by EAS.

As a first step, introduce in PM_OPP a helper function which CPUFreq
drivers can use to register into the EM framework. This duplicates the
power estimation done in IPA until it can be migrated to using the EM
framework. This will be done later, once the EM framework has support
for at least all platforms currently supported by IPA.

Signed-off-by: Quentin Perret <quentin.perret@arm.com>
Tested-by: Matthias Kaehlcke <mka@chromium.org>
Reviewed-by: Matthias Kaehlcke <mka@chromium.org>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# 5b93ac54 09-Jan-2019 Rajendra Nayak <rnayak@codeaurora.org>

OPP: Add support for parsing the 'opp-level' property

Now that the OPP bindings are updated to include an optional
'opp-level' property, add support to parse it from device tree
and store it as part of dev_pm_opp structure.
Also add and export an helper 'dev_pm_opp_get_level()' that can be
used to get the level value read from device tree when present.

Reviewed-by: Stephen Boyd <swboyd@chromium.org>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Signed-off-by: Andy Gross <andy.gross@linaro.org>


# 2feb5a89 14-Dec-2018 Viresh Kumar <viresh.kumar@linaro.org>

OPP: Don't return 0 on error from of_get_required_opp_performance_state()

of_get_required_opp_performance_state() returns 0 on errors currently
and a positive performance state otherwise. Since 0 is a valid
performance state (representing off), it would be better if this routine
returns negative values on error.

That will also make it behave similar to
dev_pm_opp_xlate_performance_state(), which also returns performance
states and returns negative values on error. Change the return type of
the function to "int" in order to return negative values.

This doesn't have any users for now and so no other part of the kernel
will be impacted with this change.

Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# 699e21e4 21-Nov-2018 Viresh Kumar <viresh.kumar@linaro.org>

OPP: Improve _find_table_of_opp_np()

Make _find_table_of_opp_np() more efficient by using of_get_parent() to
find the parent OPP table node.

Tested-by: Rajendra Nayak <rnayak@codeaurora.org>
Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# 46f48aca 11-Dec-2018 Viresh Kumar <viresh.kumar@linaro.org>

OPP: Fix missing debugfs supply directory for OPPs

There is one case where we may end up with no "supply" directory for the
OPPs in debugfs. That happens when the OPP core isn't managing the
regulators for the device and the device's OPP do have microvolt
property. It happens because the opp_table->regulator_count remains set
to 0 and the debugfs routines don't add any supply directory in such a
case.

This commit fixes that by setting opp_table->regulator_count to 1 in
that particular case. But to make everything work nicely and not break
other parts of the core, regulator_count is defined as "int" now instead
of "unsigned int" and it can have different special values now. It is
set to -1 initially to mark it "uninitialized" and later only we set it
to 0 or positive values after checking how many supplies are there.

This also helps in finding the bugs where only few of the OPPs have the
"opp-microvolt" property set and not all.

Fixes: 1fae788ed640 ("PM / OPP: Don't create debugfs "supply-0" directory unnecessarily")
Reported-by: Quentin Perret <quentin.perret@arm.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# 3e27c79c 22-Nov-2018 Viresh Kumar <viresh.kumar@linaro.org>

OPP: Fix parsing of multiple phandles in "operating-points-v2" property

We currently return error if more than one phandle is present in the
"operating-points-v2" property, which is incorrect. We only want to
check the count of phandles here and set index to 0 if only one phandle
is present.

Fix it.

Fixes: 5ed4cecd75e9 ("OPP: Pass OPP table to _of_add_opp_table_v{1|2}()")
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# 534245cc 27-Jun-2018 Viresh Kumar <viresh.kumar@linaro.org>

OPP: Remove of_dev_pm_opp_find_required_opp()

This isn't used anymore, remove it.

Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# 4c6a343e 27-Jun-2018 Viresh Kumar <viresh.kumar@linaro.org>

OPP: Rename and relocate of_genpd_opp_to_performance_state()

The OPP core already has the performance state values for each of the
genpd's OPPs and there is no need to call the genpd callback again to
get the performance state for the case where the end device doesn't have
an OPP table and has the "required-opps" property directly in its node.

This commit renames of_genpd_opp_to_performance_state() as
of_get_required_opp_performance_state() and moves it to the OPP core, as
it is all about OPP stuff now.

Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# ca1b5d77 13-Jun-2018 Viresh Kumar <viresh.kumar@linaro.org>

OPP: Configure all required OPPs

Now that all the infrastructure is in place to support multiple required
OPPs, lets switch over to using it.

A new internal routine _set_required_opps() takes care of updating
performance state for all the required OPPs. With this the performance
state updates are supported even when the end device needs to configure
regulators as well, that wasn't the case earlier.

The pstates were earlier stored in the end device's OPP structures, that
also changes now as those values are stored in the genpd's OPP
structures. And so we switch over to using
pm_genpd_opp_to_performance_state() instead of
of_genpd_opp_to_performance_state() to get performance state for the
genpd OPPs.

The routine _generic_set_opp_domain() is not required anymore and is
removed.

On errors we don't try to recover by reverting to old settings as things
are really complex now and the calls here should never really fail
unless there is a bug. There is no point increasing the complexity, for
code which will never be executed.

Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# 4f018bc0 26-Jun-2018 Viresh Kumar <viresh.kumar@linaro.org>

OPP: Add dev_pm_opp_{set|put}_genpd_virt_dev() helper

Multiple generic power domains for a consumer device are supported with
the help of virtual devices, which are created for each consumer device
- genpd pair. These are the device structures which are attached to the
power domain and are required by the OPP core to set the performance
state of the genpd.

The helpers added by this commit are required to be called once for each
of these virtual devices. These are required only if multiple domains
are available for a device, otherwise the actual device structure will
be used instead by the OPP core.

The new helpers also support the complex cases where the consumer device
wouldn't always require all the domains. For example, a camera may
require only one power domain during normal operations but two during
high resolution operations. The consumer driver can call
dev_pm_opp_put_genpd_virt_dev(high_resolution_genpd_virt_dev) if it is
currently operating in the normal mode and doesn't have any performance
requirements from the genpd which manages high resolution power
requirements. The consumer driver can later call
dev_pm_opp_set_genpd_virt_dev(high_resolution_genpd_virt_dev) once it
switches back to the high resolution mode.

The new helpers differ from other OPP set/put helpers as the new ones
can be called with OPPs initialized for the table as we may need to call
them on the fly because of the complex case explained above. For this
reason it is possible that the genpd virt_dev structure may be used in
parallel while the new helpers are running and a new mutex is added to
protect against that. We didn't use the existing opp_table->lock mutex
as that is widely used in the OPP core and we will need this lock in the
dev_pm_opp_set_rate() helper while changing OPP and we need to make sure
there is not much contention while doing that as that's the hotpath.

Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# da544b61 07-Jun-2018 Viresh Kumar <viresh.kumar@linaro.org>

OPP: Populate OPPs from "required-opps" property

An earlier commit populated the OPP tables from the "required-opps"
property, this commit populates the individual OPPs. This is repeated
for each OPP in the OPP table and these populated OPPs will be used by
later commits.

Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# 5d6d106f 07-Jun-2018 Viresh Kumar <viresh.kumar@linaro.org>

OPP: Populate required opp tables from "required-opps" property

The current implementation works only for the case where a single
phandle is present in the "required-opps" property, while DT allows
multiple phandles to be present there.

This patch adds new infrastructure to parse all the phandles present in
"required-opps" property and save pointers of the required OPP's OPP
tables. These will be used by later commits.

Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# 61d8e7c7 13-Jun-2018 Viresh Kumar <viresh.kumar@linaro.org>

OPP: Identify and mark genpd OPP tables

We need to handle genpd OPP tables differently, this is already the case
at one location and will be extended going forward. Add another field to
the OPP table to check if the table belongs to a genpd or not.

Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# deac8703 03-Oct-2018 Dave Gerlach <d-gerlach@ti.com>

PM / OPP: _of_add_opp_table_v2(): increment count only if OPP is added

Currently the _of_add_opp_table_v2 call loops through the OPP nodes in
the operating-points-v2 table in the device tree and calls
_opp_add_static_v2 for each to add them to the table. It counts each
iteration through this loop as an added OPP, however there are cases
where _opp_add_static_v2() returns 0 but no new OPP is added to the
list.

This can happen while adding duplicate OPP or if the OPP isn't supported
by hardware.

Because of this the count variable will contain the number of OPP nodes
in the table in device tree but not necessarily the ones that are
actually added.

As this count value is what is checked to determine if there are any
valid OPPs, if a platform has an operating-points-v2 table with all OPP
nodes containing opp-supported-hw values that are not currently
supported, then _of_add_opp_table_v2 will fail to abort as it should due
to an empty table.

Additionally, since commit 3ba98324e81a ("PM / OPP: Get
performance state using genpd helper"), the same count variable is
compared against the number of OPPs containing performance states and
requires that either all or none have pstates set, however in the case
of any opp table that has any entries that do not get added by
_opp_add_static_v2 due to incompatible opp-supported-hw fields, these
numbers will not match and _of_add_opp_table_v2 will incorrectly fail.

We need to clearly identify all the three cases (success, failure,
unsupported/duplicate OPPs) and then increment count only on success
case. Change return type of _opp_add_static_v2() to return the pointer
to the newly added OPP instead of an integer. This routine now returns a
valid pointer if the OPP is really added, NULL for unsupported or
duplicate OPPs, and error value cased as a pointer on errors.

Ideally the fixes tag in this commit should point back to the commit
that introduced OPP v2 initially, as that's where we started incorrectly
accounting for duplicate OPPs:

commit 274659029c9d ("PM / OPP: Add support to parse "operating-points-v2" bindings")

But it wasn't a real problem until recently as the count was only used
to check if any OPPs are added or not. And so this commit points to a
rather recent commit where we added more code that depends on the value
of "count".

Fixes: 3ba98324e81a ("PM / OPP: Get performance state using genpd helper")
Reported-by: Dave Gerlach <d-gerlach@ti.com>
Reported-by: Niklas Cassel <niklas.cassel@linaro.org>
Tested-by: Niklas Cassel <niklas.cassel@linaro.org>
Signed-off-by: Dave Gerlach <d-gerlach@ti.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# 50b6b87c 03-Oct-2018 Viresh Kumar <viresh.kumar@linaro.org>

OPP: Improve error handling in dev_pm_opp_of_cpumask_add_table()

The error handling wasn't appropriate in
dev_pm_opp_of_cpumask_add_table(). For example it returns 0 on success
and also for the case where cpumask is empty or cpu_device wasn't found
for any of the CPUs.

It should really return error on such cases, so that the callers can be
aware of the outcome.

Fix it.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# 5ed4cecd 11-Sep-2018 Viresh Kumar <viresh.kumar@linaro.org>

OPP: Pass OPP table to _of_add_opp_table_v{1|2}()

Both _of_add_opp_table_v1() and _of_add_opp_table_v2() contain similar
code to get the OPP table and their parent routine also parses the DT to
find the OPP table's node pointer. This can be simplified by getting the
OPP table in advance and then passing it as argument to these routines.

Tested-by: Niklas Cassel <niklas.cassel@linaro.org>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# 283d55e6 06-Sep-2018 Viresh Kumar <viresh.kumar@linaro.org>

OPP: Prevent creating multiple OPP tables for devices sharing OPP nodes

When two or more devices are sharing their clock and voltage rails, they
share the same OPP table. But there are some corner cases where the OPP
core incorrectly creates separate OPP tables for them.

For example, CPU 0 and 1 share clock/voltage rails. The platform
specific code calls dev_pm_opp_set_regulators() for CPU0 and the OPP
core creates an OPP table for it (the individual OPPs aren't initialized
as of now). The same is repeated for CPU1 then. Because
_opp_get_opp_table() doesn't compare DT node pointers currently, it
fails to find the link between CPU0 and CPU1 and so creates a new OPP
table.

Fix this by calling _managed_opp() from _opp_get_opp_table().
_managed_opp() gain an additional argument (index) to get the right node
pointer. This resulted in simplifying code in _of_add_opp_table_v2() as
well.

Tested-by: Niklas Cassel <niklas.cassel@linaro.org>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# cdd6ed90 11-Sep-2018 Viresh Kumar <viresh.kumar@linaro.org>

OPP: Use a single mechanism to free the OPP table

Currently there are two separate ways to free the OPP table based on how
it is created in the first place.

We call _dev_pm_opp_remove_table() to free the static and/or dynamic
OPP, OPP list devices, etc. This is done for the case where the OPP
table is added while initializing the OPPs, like via the path
dev_pm_opp_of_add_table().

We also call dev_pm_opp_put_opp_table() in some cases which eventually
frees the OPP table structure once the reference count reaches 0. This
is used by the first case as well as other cases like
dev_pm_opp_set_regulators() where the OPPs aren't necessarily
initialized at this point.

This whole thing is a bit unclear and messy and obstruct any further
cleanup/fixup of OPP core.

This patch tries to streamline this by keeping a single path for OPP
table destruction, i.e. dev_pm_opp_put_opp_table().

All the cleanup happens in _opp_table_kref_release() now after the
reference count reaches 0. _dev_pm_opp_remove_table() is removed as it
isn't required anymore.

We don't drop the reference to the OPP table after creating it from
_of_add_opp_table_v{1|2}() anymore and the same is dropped only when we
try to remove them.

Tested-by: Niklas Cassel <niklas.cassel@linaro.org>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# 2a4eb735 13-Sep-2018 Viresh Kumar <viresh.kumar@linaro.org>

OPP: Don't remove dynamic OPPs from _dev_pm_opp_remove_table()

Only one platform was depending on this feature and it is already
updated now. Stop removing dynamic OPPs from _dev_pm_opp_remove_table().
This simplifies lot of paths and removes unnecessary parameters.

Tested-by: Niklas Cassel <niklas.cassel@linaro.org>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# d0e8ae6c 10-Sep-2018 Viresh Kumar <viresh.kumar@linaro.org>

OPP: Create separate kref for static OPPs list

The static OPPs don't always get freed with the OPP table, it can happen
before that as well. For example, if the OPP table is first created
using helpers like dev_pm_opp_set_supported_hw() and the OPPs are
created at a later point. Now when the OPPs are removed, the OPP table
stays until the time dev_pm_opp_put_supported_hw() is called.

Later patches will streamline the freeing of OPP table and that requires
the static OPPs to get freed with help of a separate kernel reference.
This patch prepares for that by creating a separate kref for static OPPs
list.

Tested-by: Niklas Cassel <niklas.cassel@linaro.org>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# f06ed90e 13-Jun-2018 Viresh Kumar <viresh.kumar@linaro.org>

OPP: Parse OPP table's DT properties from _of_init_opp_table()

Parse the DT properties present in the OPP table from
_of_init_opp_table(), which is a dedicated routine for DT parsing.

Minor relocation of helpers is required for this.

It is possible now for _managed_opp() to return a partially initialized
OPP table if the OPP table is created via the helpers like
dev_pm_opp_set_supported_hw() and we need another flag to indicate if
the static OPP are already parsed or not to make sure we don't
incorrectly skip initializing the static OPPs.

Tested-by: Niklas Cassel <niklas.cassel@linaro.org>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# eb7c8743 05-Sep-2018 Viresh Kumar <viresh.kumar@linaro.org>

OPP: Pass index to _of_init_opp_table()

This is a preparatory patch required for the next commit which will
start using OPP table's node pointer in _of_init_opp_table(), which
requires the index in order to read the OPP table's phandle.

This commit adds the index argument in the call chains in order to get
it delivered to _of_init_opp_table().

Tested-by: Niklas Cassel <niklas.cassel@linaro.org>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# 404b1369 13-Sep-2018 Viresh Kumar <viresh.kumar@linaro.org>

OPP: Don't try to remove all OPP tables on failure

dev_pm_opp_of_cpumask_add_table() creates the OPP table for all CPUs
present in the cpumask and on errors it should revert all changes it has
done.

It actually is doing a bit more than that. On errors, it tries to free
all the OPP tables, even the one it hasn't created yet. This may also
end up freeing the OPP tables which were created from separate path,
like dev_pm_opp_set_supported_hw().

Reported-and-tested-by: Niklas Cassel <niklas.cassel@linaro.org>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# 2fbb8670 10-Sep-2018 Viresh Kumar <viresh.kumar@linaro.org>

OPP: Free OPP table properly on performance state irregularities

The OPP table was freed, but not the individual OPPs which is done from
_dev_pm_opp_remove_table(). Fix it by calling _dev_pm_opp_remove_table()
as well.

Cc: 4.18 <stable@vger.kernel.org> # v4.18
Fixes: 3ba98324e81a ("PM / OPP: Get performance state using genpd helper")
Tested-by: Niklas Cassel <niklas.cassel@linaro.org>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# 8a352fd8 30-May-2018 Viresh Kumar <viresh.kumar@linaro.org>

OPP: Allow same OPP table to be used for multiple genpd

The OPP binding says:

Property: operating-points-v2

...

This can contain more than one phandle for power domain
providers that provide multiple power domains. That is, one
phandle for each power domain. If only one phandle is available,
then the same OPP table will be used for all power domains
provided by the power domain provider.

But the OPP core isn't allowing the same OPP table to be used for
multiple domains. Update dev_pm_opp_of_add_table_indexed() to allow
that.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Tested-by: Rajendra Nayak <rnayak@codeaurora.org>


# 6a89e012 15-May-2018 Dan Carpenter <dan.carpenter@oracle.com>

PM / OPP: silence an uninitialized variable warning

Smatch complains that it's possible we print "rate" in the debug output
when it hasn't been initialized. It should be zero on that path.

Fixes: a1e8c13600bf ("PM / OPP: "opp-hz" is optional for power domains")
[ Viresh: Added the Fixes tag ]
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>


# 3ba98324 18-Nov-2016 Viresh Kumar <viresh.kumar@linaro.org>

PM / OPP: Get performance state using genpd helper

The genpd core provides an API now to retrieve the performance state
from DT, use that instead of the ->get_pstate() callback.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>


# e2f4b5f8 11-Jan-2018 Viresh Kumar <viresh.kumar@linaro.org>

PM / OPP: Implement dev_pm_opp_get_of_node()

This adds a new helper to let the power domain drivers to access
opp->np, so that they can read platform specific properties from the
node.

Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>


# a88bd2a5 29-Nov-2017 Viresh Kumar <viresh.kumar@linaro.org>

PM / OPP: Implement of_dev_pm_opp_find_required_opp()

A device's DT node or its OPP nodes can contain a phandle to other
device's OPP node, in the "required-opps" property.

This patch implements a routine to find that required OPP from the node
that contains the "required-opps" property.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>


# fa9b274f 25-Apr-2017 Viresh Kumar <viresh.kumar@linaro.org>

PM / OPP: Implement dev_pm_opp_of_add_table_indexed()

The "operating-points-v2" property can contain a list of phandles now,
specifically for the power domain providers that provide multiple
domains.

Add support to parse that.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>


# a1e8c136 06-Apr-2018 Viresh Kumar <viresh.kumar@linaro.org>

PM / OPP: "opp-hz" is optional for power domains

"opp-hz" property is optional for power domains now and we shouldn't
error out if it is missing for power domains.

This patch creates two new routines, _get_opp_count() and
_opp_is_duplicate(), by separating existing code from their parent
functions. Also skip duplicate OPP check for power domain OPPs as they
may not have any the "opp-hz" field, but a platform specific performance
state binding to uniquely identify OPP nodes.

By default the debugfs OPP nodes are named using the "rate" value, but
that isn't possible for the power domain OPP nodes and hence they use
the index of the OPP node in the OPP node list instead.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>


# 9867999f 12-Oct-2017 Sudeep Holla <Sudeep.Holla@arm.com>

PM / OPP: add missing of_node_put() for of_get_cpu_node()

Commit 762792913f8c (PM / OPP: Fix get sharing CPUs when hotplug
is used) moved away from using cpu_dev->of_node because of some
limitations.

However, commit 7467c9d95989 (of: return of_get_cpu_node from
of_cpu_device_node_get if CPUs are not registered) added support to
fall back to of_get_cpu_node() if called if CPUs are not registered
yet.

Add the missing of_node_put() for the CPU device nodes. Also go back
to using of_cpu_device_node_get() in dev_pm_opp_of_get_sharing_cpus()
to avoid scanning the device tree again.

Acked-by: Viresh Kumar <vireshk@kernel.org>
Fixes: 762792913f8c (PM / OPP: Fix get sharing CPUs when hotplug is used)
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>


# 7978db34 04-Oct-2017 Tobias Jordan <Tobias.Jordan@elektrobit.com>

PM / OPP: Add missing of_node_put(np)

The for_each_available_child_of_node() loop in _of_add_opp_table_v2()
doesn't drop the reference to "np" on errors. Fix that.

Fixes: 274659029c9d (PM / OPP: Add support to parse "operating-points-v2" bindings)
Cc: 4.3+ <stable@vger.kernel.org> # 4.3+
Signed-off-by: Tobias Jordan <Tobias.Jordan@elektrobit.com>
[ VK: Improved commit log. ]
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>


# 7813dd6f 26-Sep-2017 Viresh Kumar <viresh.kumar@linaro.org>

PM / OPP: Move the OPP directory out of power/

The drivers/base/power/ directory is special and contains code related
to power management core like system suspend/resume, hibernation, etc.
It was fine to keep the OPP code inside it when we had just one file for
it, but it is growing now and already has a directory for itself.

Lets move it directly under drivers/ directory, just like cpufreq and
cpuidle.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Acked-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>