Commit Graph

32 Commits

Author SHA1 Message Date
Dave Gerlach 0764c604c8 PM / OPP: Expose _of_get_opp_desc_node as dev_pm_opp API
Rename _of_get_opp_desc_node to dev_pm_opp_of_get_opp_desc_node and add it
to include/linux/pm_opp.h to allow other drivers, such as platform OPP
and cpufreq drivers, to make use of it.

Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Dave Gerlach <d-gerlach@ti.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2017-02-09 22:52:17 +01:00
Viresh Kumar 7034764a1e PM / OPP: Add 'struct kref' to struct dev_pm_opp
Add kref to struct dev_pm_opp for easier accounting of the OPPs.

Note that the OPPs are freed under the opp_table->lock mutex only.

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>
2017-01-30 09:22:21 +01:00
Viresh Kumar fa30184d19 PM / OPP: Return opp_table from dev_pm_opp_set_*() routines
Now that we have proper kernel reference infrastructure in place for OPP
tables, use it to guarantee that the OPP table isn't freed while being
used by the callers of dev_pm_opp_set_*() APIs.

Make them all return the pointer to the OPP table after taking its
reference and put the reference back with dev_pm_opp_put_*() APIs.

Now that the OPP table wouldn't get freed while these routines are
executing after dev_pm_opp_get_opp_table() is called, there is no need
to take opp_table_lock. Drop them as well.

Remove the rcu specific comments from these routines as they aren't
relevant anymore.

Note that prototypes of dev_pm_opp_{set|put}_regulators() were already
updated by another patch.

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>
2017-01-30 09:22:21 +01:00
Viresh Kumar f067a982ce PM / OPP: Add 'struct kref' to OPP table
Add kref to struct opp_table for easier accounting of the OPP table.

Note that the new routine dev_pm_opp_get_opp_table() takes the reference
from under the opp_table_lock, which guarantees that the OPP table
doesn't get freed unless dev_pm_opp_put_opp_table() is called for the
OPP table.

Two separate release mechanisms are added: locked and unlocked. In
unlocked version the routines aren't required to take/drop
opp_table_lock as the callers have already done that. This is required
to avoid breaking git bisect, otherwise we may get lockdeps between
commits. Once all the users of OPP table are updated the unlocked
version shall be removed.

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>
2017-01-30 09:22:20 +01:00
Viresh Kumar dc2c9ad52a PM / OPP: Don't expose srcu_head to register notifiers
Let the OPP core provide helpers to register notifiers for any device,
instead of exposing srcu_head outside of the core.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Acked-by: MyungJoo Ham <myungjoo.ham@samsung.com>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2017-01-27 11:49:09 +01:00
Viresh Kumar 3aa26a3b2e PM / OPP: Rename dev_pm_opp_get_suspend_opp() and return OPP rate
There is only one user of dev_pm_opp_get_suspend_opp() and that uses it
to get the OPP rate for the suspend_opp.

Rename dev_pm_opp_get_suspend_opp() as dev_pm_opp_get_suspend_opp_freq()
and return the rate directly from it.

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>
2017-01-27 11:49:09 +01:00
Viresh Kumar 4dab160eb1 PM / OPP: Allow platform specific custom set_opp() callbacks
The generic set_opp() handler isn't sufficient for platforms with
complex DVFS.  For example, some TI platforms have multiple regulators
for a CPU device. The order in which various supplies need to be
programmed is only known to the platform code and its best to leave it
to it.

This patch implements APIs to register platform specific set_opp()
callback.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Tested-by: Dave Gerlach <d-gerlach@ti.com>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2016-12-06 02:27:59 +01:00
Viresh Kumar 947355850f PM / OPP: Separate out _generic_set_opp()
Later patches would add support for custom set_opp() callbacks. This
patch separates out the code for _generic_set_opp() handler in order to
prepare for that.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Tested-by: Dave Gerlach <d-gerlach@ti.com>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2016-12-06 02:27:59 +01:00
Viresh Kumar dfbe4678d7 PM / OPP: Add infrastructure to manage multiple regulators
This patch adds infrastructure to manage multiple regulators and updates
the only user (cpufreq-dt) of dev_pm_opp_set{put}_regulator().

This is preparatory work for adding full support for devices with
multiple regulators.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Tested-by: Dave Gerlach <d-gerlach@ti.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2016-12-06 02:27:59 +01:00
Viresh Kumar 0f0fe7e013 PM / OPP: Manage supply's voltage/current in a separate structure
This is a preparatory step for multiple regulator per device support.
Move the voltage/current variables to a new structure.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Tested-by: Dave Gerlach <d-gerlach@ti.com>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2016-12-06 02:27:59 +01:00
Stephen Boyd 91291d9ad9 PM / OPP: Pass opp_table to dev_pm_opp_put_regulator()
Joonyoung Shim reported an interesting problem on his ARM octa-core
Odoroid-XU3 platform. During system suspend, dev_pm_opp_put_regulator()
was failing for a struct device for which dev_pm_opp_set_regulator() is
called earlier.

This happened because an earlier call to
dev_pm_opp_of_cpumask_remove_table() function (from cpufreq-dt.c file)
removed all the entries from opp_table->dev_list apart from the last CPU
device in the cpumask of CPUs sharing the OPP.

But both dev_pm_opp_set_regulator() and dev_pm_opp_put_regulator()
routines get CPU device for the first CPU in the cpumask. And so the OPP
core failed to find the OPP table for the struct device.

This patch attempts to fix this problem by returning a pointer to the
opp_table from dev_pm_opp_set_regulator() and using that as the
parameter to dev_pm_opp_put_regulator(). This ensures that the
dev_pm_opp_put_regulator() doesn't fail to find the opp table.

Note that similar design problem also exists with other
dev_pm_opp_put_*() APIs, but those aren't used currently by anyone and
so we don't need to update them for now.

Cc: 4.4+ <stable@vger.kernel.org> # 4.4+
Reported-by: Joonyoung Shim <jy0922.shim@samsung.com>
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
[ Viresh: Wrote commit log and tested on exynos 5250 ]
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2016-11-30 22:41:28 +01:00
Sudeep Holla 411466c508 PM / OPP: add non-OF versions of dev_pm_opp_{cpumask_, }remove_table
Functions dev_pm_opp_of_{cpumask_,}remove_table removes/frees all the
static OPP entries associated with the device and/or all cpus(in case
of cpumask) that are created from DT.

However the OPP entries are populated reading from the firmware or some
different method using dev_pm_opp_add are marked dynamic and can't be
removed using above functions.

This patch adds non DT/OF versions of dev_pm_opp_{cpumask_,}remove_table
to support the above mentioned usecase.

This is in preparation to make use of the same in scpi-cpufreq.c

Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
Acked-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>
2016-05-05 01:38:44 +02:00
Arnd Bergmann ddbb74bc70 PM / OPP: pass cpumask by reference
The new use of dev_pm_opp_set_sharing_cpus resulted in a harmless compiler
warning with CONFIG_CPUMASK_OFFSTACK=y:

drivers/cpufreq/mvebu-cpufreq.c: In function 'armada_xp_pmsu_cpufreq_init':
include/linux/cpumask.h:550:25: error: passing argument 2 of 'dev_pm_opp_set_sharing_cpus' discards 'const' qualifier from pointer target type [-Werror=discarded-qualifiers]

The problem here is that cpumask_var_t gets passed by reference, but
by declaring a 'const cpumask_var_t' argument, only the pointer is
constant, not the actual mask. This is harmless because the function
does not actually modify the mask.

This patch changes the function prototypes for all of the related functions
to pass a 'struct cpumask *' instead of 'cpumask_var_t', matching what
most other such functions do in the kernel. This lets us mark all the
other similar functions as taking a 'const' mask where possible,
and it avoids the warning without any change in object code.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Fixes: 947bd567f7 (mvebu: Use dev_pm_opp_set_sharing_cpus() to mark OPP tables as shared)
Acked-by: Pavel Machek <pavel@ucw.cz>
Acked-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>
2016-05-05 01:34:20 +02:00
Viresh Kumar 6f707daa38 PM / OPP: Add dev_pm_opp_get_sharing_cpus()
OPP core allows a platform to mark OPP table as shared, when the
platform isn't using operating-points-v2 bindings.

And, so there should be a non DT way of finding out if the OPP table is
shared or not.

This patch adds dev_pm_opp_get_sharing_cpus(), which first tries to get
OPP sharing information from the opp-table (in case it is already marked
as shared), otherwise it uses the existing DT way of finding sharing
information.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2016-04-28 15:18:18 +02:00
Viresh Kumar dde370b23c PM / OPP: Mark cpumask as const in dev_pm_opp_set_sharing_cpus()
dev_pm_opp_set_sharing_cpus() isn't supposed to update the cpumask
passed as its parameter, and so it should always have been marked
'const'.

Do it now.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2016-04-28 15:18:18 +02:00
Viresh Kumar d708b384c0 PM / OPP: -ENOSYS is applicable only to syscalls
Some of the routines have used -ENOSYS for the cases where the
functionality isn't implemented in the kernel. But ENOSYS is supposed to
be used only for syscalls.

Replace that with -ENOTSUPP, which specifically means that the operation
isn't supported.

While at it, replace exiting -EINVAL errors for similar cases to
-ENOTSUPP.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2016-04-28 15:18:18 +02:00
Viresh Kumar 642aa8cee7 PM / OPP: dev_pm_opp_set_sharing_cpus() doesn't depend on CONFIG_OF
dev_pm_opp_set_sharing_cpus() doesn't do any DT specific stuff and its
declarations are added within the CONFIG_OF ifdef by mistake. Take them
out of that.

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>
2016-04-25 16:10:15 +02:00
Viresh Kumar 6a0712f6f1 PM / OPP: Add dev_pm_opp_set_rate()
This adds a routine, dev_pm_opp_set_rate(), responsible for configuring
power-supply and clock source for an OPP.

The OPP is found by matching against the target_freq passed to the
routine. This shall replace similar code present in most of the OPP
users and help simplify them a lot.

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>
2016-02-10 01:11:54 +01:00
Viresh Kumar 2174344765 PM / OPP: Introduce dev_pm_opp_get_max_transition_latency()
In few use cases (like: cpufreq), it is desired to get the maximum
latency for changing OPPs. Add support for that.

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>
2016-02-10 01:11:53 +01:00
Viresh Kumar 655c9df961 PM / OPP: Introduce dev_pm_opp_get_max_volt_latency()
In few use cases (like: cpufreq), it is desired to get the maximum
voltage latency for changing OPPs. Add support for that.

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>
2016-02-10 01:11:53 +01:00
Viresh Kumar 9f8ea969d5 PM / OPP: get/put regulators from OPP core
This allows the OPP core to request/free the regulator resource,
attached to a device OPP. The regulator device is fetched using the name
provided by the driver, while calling: dev_pm_opp_set_regulator().

This will work for both OPP-v1 and v2 bindings.

This is a preliminary step for moving the OPP switching logic into the
OPP core.

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>
2016-02-10 01:11:53 +01:00
Viresh Kumar 01fb4d3c39 PM / OPP: Parse 'opp-<prop>-<name>' bindings
OPP bindings (for few properties) allow a platform to choose a
value/range among a set of available options. The options are present as
opp-<prop>-<name>, where the platform needs to supply the <name> string.

The OPP properties which allow such an option are: opp-microvolt and
opp-microamp.

Add support to the OPP-core to parse these bindings, by introducing
dev_pm_opp_{set|put}_prop_name() APIs.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Tested-by: Lee Jones <lee.jones@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-12-10 23:08:51 +01:00
Viresh Kumar 7de36b0aa5 PM / OPP: Parse 'opp-supported-hw' binding
OPP bindings allow a platform to enable OPPs based on the version of the
hardware they are used for.

Add support to the OPP-core to parse these bindings, by introducing
dev_pm_opp_{set|put}_supported_hw() APIs.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Tested-by: Lee Jones <lee.jones@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-12-10 23:08:51 +01:00
Viresh Kumar 8f8d37b253 PM / OPP: Prefix exported opp routines with dev_pm_opp_
That's the naming convention followed in most of opp core, but few
routines didn't follow this, fix them.

Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Acked-by: Shawn Guo <shawnguo@kernel.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-09-15 02:03:16 +02:00
Viresh Kumar f0489a5ef4 PM / OPP: Rename opp init/free table routines
free-table routines are opposite of init-table ones, and must be named
to make that clear. Opposite of 'init' is 'exit', but those doesn't suit
really well.

Replace 'init' with 'add' and 'free' with 'remove'.

Reported-by: Pavel Machek <pavel@ucw.cz>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Acked-by: Shawn Guo <shawnguo@kernel.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-09-15 02:03:15 +02:00
Bartlomiej Zolnierkiewicz 4eafbd15b6 PM / OPP: add dev_pm_opp_get_suspend_opp() helper
Add dev_pm_opp_get_suspend_opp() helper to obtain suspend opp.

Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-09-09 02:20:39 +02:00
Bartlomiej Zolnierkiewicz 19445b25e3 PM / OPP: add dev_pm_opp_is_turbo() helper
Add dev_pm_opp_is_turbo() helper to verify if an opp is to be used only
for turbo mode or not.

Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-08-07 03:17:06 +02:00
Viresh Kumar 8d4d4e98ac PM / OPP: Add helpers for initializing CPU OPPs
With "operating-points-v2" its possible to tell which devices share
OPPs. We already have infrastructure to decode that information.

This patch adds following APIs:
 - of_get_cpus_sharing_opps: Returns cpumask of CPUs sharing OPPs (only
   valid with v2 bindings).
 - of_cpumask_init_opp_table: Initializes OPPs for all CPUs present in
   cpumask.
 - of_cpumask_free_opp_table: Frees OPPs for all CPUs present in cpumask.

 - set_cpus_sharing_opps: Sets which CPUs share OPPs (only valid with old
   OPP bindings, as this information isn't present in DT).

Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Reviewed-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-08-07 03:16:01 +02:00
Viresh Kumar 3ca9bb33c6 PM / OPP: Add clock-latency-ns support
With "operating-points-v2" bindings, clock-latency is defined per OPP.
Users of this value expect a single value which defines the latency to
switch to any clock rate. Find maximum clock-latency-ns from the OPP
table to service requests from such users.

Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Reviewed-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-08-07 03:04:23 +02:00
Viresh Kumar 129eec55df PM / OPP Introduce APIs to remove OPPs
OPPs are created statically (from DT) or dynamically. Currently we don't free
OPPs that are created statically, when the module unloads. And so if the module
is inserted back again, we get warning for duplicate OPPs as the same were
already present.

Also, there might be a need to remove dynamic OPPs in future and so API for that
is also added.

This patch adds helper APIs to remove/free existing static and dynamic OPPs.

Because the OPPs are used both under RCU and SRCU, we have to wait for grace
period of both. And so are using kfree_rcu() from within call_srcu().

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2014-11-29 23:53:20 +01:00
Nishanth Menon a0dd7b7965 PM / OPP: Move cpufreq specific OPP functions out of generic OPP library
CPUFreq specific helper functions for OPP (Operating Performance Points)
now use generic OPP functions that allow CPUFreq to be be moved back
into CPUFreq framework. This allows for independent modifications
or future enhancements as needed isolated to just CPUFreq framework
alone.

Here, we just move relevant code and documentation to make this part of
CPUFreq infrastructure.

Cc: Kevin Hilman <khilman@deeprootsystems.com>
Signed-off-by: Nishanth Menon <nm@ti.com>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2014-05-07 00:39:03 +02:00
Nishanth Menon e4db1c7439 PM / OPP: rename header to linux/pm_opp.h
Since Operating Performance Points (OPP) functions are specific
to device specific power management, be specific and rename opp.h
to pm_opp.h

Reported-by: Randy Dunlap <rdunlap@infradead.org>
Signed-off-by: Nishanth Menon <nm@ti.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2013-10-25 22:33:23 +02:00