OPP updates for 6.6

- Minor core cleanup and addition of new frequency related APIs (Viresh
   Kumar and Manivannan Sadhasivam).
 
 - Convert ti cpufreq/opp bindings to json schema (Nishanth Menon).
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEx73Crsp7f6M6scA70rkcPK6BEhwFAmTsdWEACgkQ0rkcPK6B
 EhyuNhAAtd3KqoIlE4L1fGQe1F3tukuPR8KCYyeDJzT+mvjlBTi6xcDJoMSdiE68
 tRH6QI6+dzzFnyLbC3v3WULWosFkY1ETkZNVvmjyE+DE7v7mwRL5EdAQfJ2OoBH6
 7906FHy5XN9+ch/LLJ8ja+d+z9jx38obkVB87nrEio3rocaYuPRYjesum57LWU/7
 Bh+9VqiCFIMu0U4cDXHcmrsh9OEupWF4NQZ3N3QDlwKjiSd05jmzYcKx3tOO6oa4
 NRNUoQ4AH1qk6BBc/V1igfFXCFSYTY1RRKslzeIDbocNrphXmY6qq2muBbnpmJ2P
 Ykyyc+q9cSzzgPV/VHH54g5woJh34oIvxmDPaieAjPVIzLNOJXW7zN2FjeKH4pXZ
 kTBtqpUcbqpcZuLryd91WclXIL9WsjdHaB4XkKnsWMFBVcWBrET3d/x4sR1HkD6c
 CU0ftr68qzuoT9vyeOs/636FeK+l4Bmsp2m30v5DsoO9DC5n5EMMEZqZHVD0Csvy
 bLoEHOhHSMtJwknK8QkRde6KdxwteEbHK2IR1VmKz+ppa87AFbLxfqR1zgtyZ8Ho
 0/rtzPODfp2vd+gPfBXfiwhg/57cL1Knxmm0g/11PUQPAYreRxBE+ovPGDJ39oSo
 KX9tqqAokirIsdNXFV0v6GWivGZZlcMErGqBMY88Wt2zNkKm7vY=
 =b27+
 -----END PGP SIGNATURE-----

Merge tag 'opp-updates-6.6' of git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm

Pull OPP updates for 6.6 from Viresh Kumar:

"- Minor core cleanup and addition of new frequency related APIs (Viresh
   Kumar and Manivannan Sadhasivam).

 - Convert ti cpufreq/opp bindings to json schema (Nishanth Menon)."

* tag 'opp-updates-6.6' of git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm:
  dt-bindings: cpufreq: Convert ti-cpufreq to json schema
  dt-bindings: opp: Convert ti-omap5-opp-supply to json schema
  OPP: Fix argument name in doc comment
  dt-bindings: opp: Increase maxItems for opp-hz property
  OPP: Fix passing 0 to PTR_ERR in _opp_attach_genpd()
  OPP: Fix potential null ptr dereference in dev_pm_opp_get_required_pstate()
  OPP: Reuse dev_pm_opp_get_freq_indexed()
  OPP: Update _read_freq() to return the correct frequency
  OPP: Add dev_pm_opp_find_freq_exact_indexed()
  OPP: Introduce dev_pm_opp_get_freq_indexed() API
  OPP: Introduce dev_pm_opp_find_freq_{ceil/floor}_indexed() APIs
  OPP: Rearrange entries in pm_opp.h
This commit is contained in:
Rafael J. Wysocki 2023-08-28 14:15:41 +02:00
commit 422ec6fe27
8 changed files with 349 additions and 234 deletions

View file

@ -1,132 +0,0 @@
TI CPUFreq and OPP bindings
================================
Certain TI SoCs, like those in the am335x, am437x, am57xx, and dra7xx
families support different OPPs depending on the silicon variant in use.
The ti-cpufreq driver can use revision and an efuse value from the SoC to
provide the OPP framework with supported hardware information. This is
used to determine which OPPs from the operating-points-v2 table get enabled
when it is parsed by the OPP framework.
Required properties:
--------------------
In 'cpus' nodes:
- operating-points-v2: Phandle to the operating-points-v2 table to use.
In 'operating-points-v2' table:
- compatible: Should be
- 'operating-points-v2-ti-cpu' for am335x, am43xx, and dra7xx/am57xx,
omap34xx, omap36xx and am3517 SoCs
- syscon: A phandle pointing to a syscon node representing the control module
register space of the SoC.
Optional properties:
--------------------
- "vdd-supply", "vbb-supply": to define two regulators for dra7xx
- "cpu0-supply", "vbb-supply": to define two regulators for omap36xx
For each opp entry in 'operating-points-v2' table:
- opp-supported-hw: Two bitfields indicating:
1. Which revision of the SoC the OPP is supported by
2. Which eFuse bits indicate this OPP is available
A bitwise AND is performed against these values and if any bit
matches, the OPP gets enabled.
Example:
--------
/* From arch/arm/boot/dts/am33xx.dtsi */
cpus {
#address-cells = <1>;
#size-cells = <0>;
cpu@0 {
compatible = "arm,cortex-a8";
device_type = "cpu";
reg = <0>;
operating-points-v2 = <&cpu0_opp_table>;
clocks = <&dpll_mpu_ck>;
clock-names = "cpu";
clock-latency = <300000>; /* From omap-cpufreq driver */
};
};
/*
* cpu0 has different OPPs depending on SoC revision and some on revisions
* 0x2 and 0x4 have eFuse bits that indicate if they are available or not
*/
cpu0_opp_table: opp-table {
compatible = "operating-points-v2-ti-cpu";
syscon = <&scm_conf>;
/*
* The three following nodes are marked with opp-suspend
* because they can not be enabled simultaneously on a
* single SoC.
*/
opp50-300000000 {
opp-hz = /bits/ 64 <300000000>;
opp-microvolt = <950000 931000 969000>;
opp-supported-hw = <0x06 0x0010>;
opp-suspend;
};
opp100-275000000 {
opp-hz = /bits/ 64 <275000000>;
opp-microvolt = <1100000 1078000 1122000>;
opp-supported-hw = <0x01 0x00FF>;
opp-suspend;
};
opp100-300000000 {
opp-hz = /bits/ 64 <300000000>;
opp-microvolt = <1100000 1078000 1122000>;
opp-supported-hw = <0x06 0x0020>;
opp-suspend;
};
opp100-500000000 {
opp-hz = /bits/ 64 <500000000>;
opp-microvolt = <1100000 1078000 1122000>;
opp-supported-hw = <0x01 0xFFFF>;
};
opp100-600000000 {
opp-hz = /bits/ 64 <600000000>;
opp-microvolt = <1100000 1078000 1122000>;
opp-supported-hw = <0x06 0x0040>;
};
opp120-600000000 {
opp-hz = /bits/ 64 <600000000>;
opp-microvolt = <1200000 1176000 1224000>;
opp-supported-hw = <0x01 0xFFFF>;
};
opp120-720000000 {
opp-hz = /bits/ 64 <720000000>;
opp-microvolt = <1200000 1176000 1224000>;
opp-supported-hw = <0x06 0x0080>;
};
oppturbo-720000000 {
opp-hz = /bits/ 64 <720000000>;
opp-microvolt = <1260000 1234800 1285200>;
opp-supported-hw = <0x01 0xFFFF>;
};
oppturbo-800000000 {
opp-hz = /bits/ 64 <800000000>;
opp-microvolt = <1260000 1234800 1285200>;
opp-supported-hw = <0x06 0x0100>;
};
oppnitro-1000000000 {
opp-hz = /bits/ 64 <1000000000>;
opp-microvolt = <1325000 1298500 1351500>;
opp-supported-hw = <0x04 0x0200>;
};
};

View file

@ -0,0 +1,92 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/opp/operating-points-v2-ti-cpu.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: TI CPU OPP (Operating Performance Points)
description:
TI SoCs, like those in the AM335x, AM437x, AM57xx, AM62x, and DRA7xx
families, the CPU frequencies subset and the voltage value of each
OPP vary based on the silicon variant used. The data sheet sections
corresponding to "Operating Performance Points" describe the frequency
and voltage values based on device type and speed bin information
blown in corresponding eFuse bits as referred to by the Technical
Reference Manual.
This document extends the operating-points-v2 binding by providing
the hardware description for the scheme mentioned above.
maintainers:
- Nishanth Menon <nm@ti.com>
allOf:
- $ref: opp-v2-base.yaml#
properties:
compatible:
const: operating-points-v2-ti-cpu
syscon:
$ref: /schemas/types.yaml#/definitions/phandle
description: |
points to syscon node representing the control module
register space of the SoC.
opp-shared: true
patternProperties:
'^opp(-?[0-9]+)*$':
type: object
additionalProperties: false
properties:
clock-latency-ns: true
opp-hz: true
opp-microvolt: true
opp-supported-hw: true
opp-suspend: true
turbo-mode: true
required:
- opp-hz
- opp-supported-hw
required:
- compatible
- syscon
additionalProperties: false
examples:
- |
opp-table {
compatible = "operating-points-v2-ti-cpu";
syscon = <&scm_conf>;
opp-300000000 {
opp-hz = /bits/ 64 <300000000>;
opp-microvolt = <1100000 1078000 1122000>;
opp-supported-hw = <0x06 0x0020>;
opp-suspend;
};
opp-500000000 {
opp-hz = /bits/ 64 <500000000>;
opp-microvolt = <1100000 1078000 1122000>;
opp-supported-hw = <0x01 0xFFFF>;
};
opp-600000000 {
opp-hz = /bits/ 64 <600000000>;
opp-microvolt = <1100000 1078000 1122000>;
opp-supported-hw = <0x06 0x0040>;
};
opp-1000000000 {
opp-hz = /bits/ 64 <1000000000>;
opp-microvolt = <1325000 1298500 1351500>;
opp-supported-hw = <0x04 0x0200>;
};
};

View file

@ -56,7 +56,7 @@ patternProperties:
need to be configured and that is left for the implementation
specific binding.
minItems: 1
maxItems: 16
maxItems: 32
items:
maxItems: 1

View file

@ -0,0 +1,101 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/opp/ti,omap-opp-supply.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Texas Instruments OMAP compatible OPP supply
description:
OMAP5, DRA7, and AM57 families of SoCs have Class 0 AVS eFuse
registers, which contain OPP-specific voltage information tailored
for the specific device. This binding provides the information
needed to describe such a hardware values and relate them to program
the primary regulator during an OPP transition.
Also, some supplies may have an associated vbb-supply, an Adaptive
Body Bias regulator, which must transition in a specific sequence
w.r.t the vdd-supply and clk when making an OPP transition. By
supplying two regulators to the device that will undergo OPP
transitions, we can use the multi-regulator support implemented by
the OPP core to describe both regulators the platform needs. The
OPP core binding Documentation/devicetree/bindings/opp/opp-v2.yaml
provides further information (refer to Example 4 Handling multiple
regulators).
maintainers:
- Nishanth Menon <nm@ti.com>
properties:
$nodename:
pattern: '^opp-supply(@[0-9a-f]+)?$'
compatible:
oneOf:
- description: Basic OPP supply controlling VDD and VBB
const: ti,omap-opp-supply
- description: OMAP5+ optimized voltages in efuse(Class 0) VDD along with
VBB.
const: ti,omap5-opp-supply
- description: OMAP5+ optimized voltages in efuse(class0) VDD but no VBB
const: ti,omap5-core-opp-supply
reg:
maxItems: 1
ti,absolute-max-voltage-uv:
$ref: /schemas/types.yaml#/definitions/uint32
description: Absolute maximum voltage for the OPP supply in micro-volts.
minimum: 750000
maximum: 1500000
ti,efuse-settings:
description: An array of u32 tuple items providing information about
optimized efuse configuration.
minItems: 1
$ref: /schemas/types.yaml#/definitions/uint32-matrix
items:
items:
- description: Reference voltage in micro-volts (OPP Voltage)
minimum: 750000
maximum: 1500000
multipleOf: 10000
- description: efuse offset where the optimized voltage is located
multipleOf: 4
maximum: 256
required:
- compatible
- ti,absolute-max-voltage-uv
allOf:
- if:
not:
properties:
compatible:
contains:
const: ti,omap-opp-supply
then:
required:
- reg
- ti,efuse-settings
additionalProperties: false
examples:
- |
opp-supply {
compatible = "ti,omap-opp-supply";
ti,absolute-max-voltage-uv = <1375000>;
};
- |
opp-supply@4a003b20 {
compatible = "ti,omap5-opp-supply";
reg = <0x4a003b20 0x8>;
ti,efuse-settings =
/* uV offset */
<1060000 0x0>,
<1160000 0x4>,
<1210000 0x8>;
ti,absolute-max-voltage-uv = <1500000>;
};

View file

@ -1,63 +0,0 @@
Texas Instruments OMAP compatible OPP supply description
OMAP5, DRA7, and AM57 family of SoCs have Class0 AVS eFuse registers which
contain data that can be used to adjust voltages programmed for some of their
supplies for more efficient operation. This binding provides the information
needed to read these values and use them to program the main regulator during
an OPP transitions.
Also, some supplies may have an associated vbb-supply which is an Adaptive Body
Bias regulator which much be transitioned in a specific sequence with regards
to the vdd-supply and clk when making an OPP transition. By supplying two
regulators to the device that will undergo OPP transitions we can make use
of the multi regulator binding that is part of the OPP core described here [1]
to describe both regulators needed by the platform.
[1] Documentation/devicetree/bindings/opp/opp-v2.yaml
Required Properties for Device Node:
- vdd-supply: phandle to regulator controlling VDD supply
- vbb-supply: phandle to regulator controlling Body Bias supply
(Usually Adaptive Body Bias regulator)
Required Properties for opp-supply node:
- compatible: Should be one of:
"ti,omap-opp-supply" - basic OPP supply controlling VDD and VBB
"ti,omap5-opp-supply" - OMAP5+ optimized voltages in efuse(class0)VDD
along with VBB
"ti,omap5-core-opp-supply" - OMAP5+ optimized voltages in efuse(class0) VDD
but no VBB.
- reg: Address and length of the efuse register set for the device (mandatory
only for "ti,omap5-opp-supply")
- ti,efuse-settings: An array of u32 tuple items providing information about
optimized efuse configuration. Each item consists of the following:
volt: voltage in uV - reference voltage (OPP voltage)
efuse_offseet: efuse offset from reg where the optimized voltage is stored.
- ti,absolute-max-voltage-uv: absolute maximum voltage for the OPP supply.
Example:
/* Device Node (CPU) */
cpus {
cpu0: cpu@0 {
device_type = "cpu";
...
vdd-supply = <&vcc>;
vbb-supply = <&abb_mpu>;
};
};
/* OMAP OPP Supply with Class0 registers */
opp_supply_mpu: opp_supply@4a003b20 {
compatible = "ti,omap5-opp-supply";
reg = <0x4a003b20 0x8>;
ti,efuse-settings = <
/* uV offset */
1060000 0x0
1160000 0x4
1210000 0x8
>;
ti,absolute-max-voltage-uv = <1500000>;
};

View file

@ -177,25 +177,24 @@ unsigned long dev_pm_opp_get_power(struct dev_pm_opp *opp)
EXPORT_SYMBOL_GPL(dev_pm_opp_get_power);
/**
* dev_pm_opp_get_freq() - Gets the frequency corresponding to an available opp
* @opp: opp for which frequency has to be returned for
* dev_pm_opp_get_freq_indexed() - Gets the frequency corresponding to an
* available opp with specified index
* @opp: opp for which frequency has to be returned for
* @index: index of the frequency within the required opp
*
* Return: frequency in hertz corresponding to the opp, else
* return 0
* Return: frequency in hertz corresponding to the opp with specified index,
* else return 0
*/
unsigned long dev_pm_opp_get_freq(struct dev_pm_opp *opp)
unsigned long dev_pm_opp_get_freq_indexed(struct dev_pm_opp *opp, u32 index)
{
if (IS_ERR_OR_NULL(opp)) {
if (IS_ERR_OR_NULL(opp) || index >= opp->opp_table->clk_count) {
pr_err("%s: Invalid parameters\n", __func__);
return 0;
}
if (!assert_single_clk(opp->opp_table))
return 0;
return opp->rates[0];
return opp->rates[index];
}
EXPORT_SYMBOL_GPL(dev_pm_opp_get_freq);
EXPORT_SYMBOL_GPL(dev_pm_opp_get_freq_indexed);
/**
* dev_pm_opp_get_level() - Gets the level corresponding to an available opp
@ -227,20 +226,18 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_get_level);
unsigned int dev_pm_opp_get_required_pstate(struct dev_pm_opp *opp,
unsigned int index)
{
struct opp_table *opp_table = opp->opp_table;
if (IS_ERR_OR_NULL(opp) || !opp->available ||
index >= opp_table->required_opp_count) {
index >= opp->opp_table->required_opp_count) {
pr_err("%s: Invalid parameters\n", __func__);
return 0;
}
/* required-opps not fully initialized yet */
if (lazy_linking_pending(opp_table))
if (lazy_linking_pending(opp->opp_table))
return 0;
/* The required OPP table must belong to a genpd */
if (unlikely(!opp_table->required_opp_tables[index]->is_genpd)) {
if (unlikely(!opp->opp_table->required_opp_tables[index]->is_genpd)) {
pr_err("%s: Performance state is only valid for genpds.\n", __func__);
return 0;
}
@ -450,7 +447,7 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_get_opp_count);
/* Helpers to read keys */
static unsigned long _read_freq(struct dev_pm_opp *opp, int index)
{
return opp->rates[0];
return opp->rates[index];
}
static unsigned long _read_level(struct dev_pm_opp *opp, int index)
@ -626,6 +623,34 @@ struct dev_pm_opp *dev_pm_opp_find_freq_exact(struct device *dev,
}
EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_exact);
/**
* dev_pm_opp_find_freq_exact_indexed() - Search for an exact freq for the
* clock corresponding to the index
* @dev: Device for which we do this operation
* @freq: frequency to search for
* @index: Clock index
* @available: true/false - match for available opp
*
* Search for the matching exact OPP for the clock corresponding to the
* specified index from a starting freq for a device.
*
* Return: matching *opp , else returns ERR_PTR in case of error and should be
* handled using IS_ERR. Error return values can be:
* EINVAL: for bad pointer
* ERANGE: no match found for search
* ENODEV: if device not found in list of registered devices
*
* The callers are required to call dev_pm_opp_put() for the returned OPP after
* use.
*/
struct dev_pm_opp *
dev_pm_opp_find_freq_exact_indexed(struct device *dev, unsigned long freq,
u32 index, bool available)
{
return _find_key_exact(dev, freq, index, available, _read_freq, NULL);
}
EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_exact_indexed);
static noinline struct dev_pm_opp *_find_freq_ceil(struct opp_table *opp_table,
unsigned long *freq)
{
@ -658,6 +683,34 @@ struct dev_pm_opp *dev_pm_opp_find_freq_ceil(struct device *dev,
}
EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_ceil);
/**
* dev_pm_opp_find_freq_ceil_indexed() - Search for a rounded ceil freq for the
* clock corresponding to the index
* @dev: Device for which we do this operation
* @freq: Start frequency
* @index: Clock index
*
* Search for the matching ceil *available* OPP for the clock corresponding to
* the specified index from a starting freq for a device.
*
* Return: matching *opp and refreshes *freq accordingly, else returns
* ERR_PTR in case of error and should be handled using IS_ERR. Error return
* values can be:
* EINVAL: for bad pointer
* ERANGE: no match found for search
* ENODEV: if device not found in list of registered devices
*
* The callers are required to call dev_pm_opp_put() for the returned OPP after
* use.
*/
struct dev_pm_opp *
dev_pm_opp_find_freq_ceil_indexed(struct device *dev, unsigned long *freq,
u32 index)
{
return _find_key_ceil(dev, freq, index, true, _read_freq, NULL);
}
EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_ceil_indexed);
/**
* dev_pm_opp_find_freq_floor() - Search for a rounded floor freq
* @dev: device for which we do this operation
@ -683,6 +736,34 @@ struct dev_pm_opp *dev_pm_opp_find_freq_floor(struct device *dev,
}
EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_floor);
/**
* dev_pm_opp_find_freq_floor_indexed() - Search for a rounded floor freq for the
* clock corresponding to the index
* @dev: Device for which we do this operation
* @freq: Start frequency
* @index: Clock index
*
* Search for the matching floor *available* OPP for the clock corresponding to
* the specified index from a starting freq for a device.
*
* Return: matching *opp and refreshes *freq accordingly, else returns
* ERR_PTR in case of error and should be handled using IS_ERR. Error return
* values can be:
* EINVAL: for bad pointer
* ERANGE: no match found for search
* ENODEV: if device not found in list of registered devices
*
* The callers are required to call dev_pm_opp_put() for the returned OPP after
* use.
*/
struct dev_pm_opp *
dev_pm_opp_find_freq_floor_indexed(struct device *dev, unsigned long *freq,
u32 index)
{
return _find_key_floor(dev, freq, index, true, _read_freq, NULL);
}
EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_floor_indexed);
/**
* dev_pm_opp_find_level_exact() - search for an exact level
* @dev: device for which we do this operation
@ -2379,7 +2460,7 @@ static int _opp_attach_genpd(struct opp_table *opp_table, struct device *dev,
virt_dev = dev_pm_domain_attach_by_name(dev, *name);
if (IS_ERR_OR_NULL(virt_dev)) {
ret = PTR_ERR(virt_dev) ? : -ENODEV;
ret = virt_dev ? PTR_ERR(virt_dev) : -ENODEV;
dev_err(dev, "Couldn't attach to pm_domain: %d\n", ret);
goto err;
}

View file

@ -24,7 +24,7 @@
/**
* dev_pm_opp_init_cpufreq_table() - create a cpufreq table for a device
* @dev: device for which we do this operation
* @table: Cpufreq table returned back to caller
* @opp_table: Cpufreq table returned back to caller
*
* Generate a cpufreq table for a provided device- this assumes that the
* opp table is already initialized and ready for usage.
@ -89,7 +89,7 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_init_cpufreq_table);
/**
* dev_pm_opp_free_cpufreq_table() - free the cpufreq table
* @dev: device for which we do this operation
* @table: table to free
* @opp_table: table to free
*
* Free up the table allocated by dev_pm_opp_init_cpufreq_table
*/

View file

@ -103,7 +103,7 @@ int dev_pm_opp_get_supplies(struct dev_pm_opp *opp, struct dev_pm_opp_supply *su
unsigned long dev_pm_opp_get_power(struct dev_pm_opp *opp);
unsigned long dev_pm_opp_get_freq(struct dev_pm_opp *opp);
unsigned long dev_pm_opp_get_freq_indexed(struct dev_pm_opp *opp, u32 index);
unsigned int dev_pm_opp_get_level(struct dev_pm_opp *opp);
@ -121,17 +121,29 @@ unsigned long dev_pm_opp_get_suspend_opp_freq(struct device *dev);
struct dev_pm_opp *dev_pm_opp_find_freq_exact(struct device *dev,
unsigned long freq,
bool available);
struct dev_pm_opp *
dev_pm_opp_find_freq_exact_indexed(struct device *dev, unsigned long freq,
u32 index, bool available);
struct dev_pm_opp *dev_pm_opp_find_freq_floor(struct device *dev,
unsigned long *freq);
struct dev_pm_opp *dev_pm_opp_find_level_exact(struct device *dev,
unsigned int level);
struct dev_pm_opp *dev_pm_opp_find_level_ceil(struct device *dev,
unsigned int *level);
struct dev_pm_opp *dev_pm_opp_find_freq_floor_indexed(struct device *dev,
unsigned long *freq, u32 index);
struct dev_pm_opp *dev_pm_opp_find_freq_ceil(struct device *dev,
unsigned long *freq);
struct dev_pm_opp *dev_pm_opp_find_freq_ceil_indexed(struct device *dev,
unsigned long *freq, u32 index);
struct dev_pm_opp *dev_pm_opp_find_level_exact(struct device *dev,
unsigned int level);
struct dev_pm_opp *dev_pm_opp_find_level_ceil(struct device *dev,
unsigned int *level);
struct dev_pm_opp *dev_pm_opp_find_bw_ceil(struct device *dev,
unsigned int *bw, int index);
@ -200,7 +212,7 @@ static inline unsigned long dev_pm_opp_get_power(struct dev_pm_opp *opp)
return 0;
}
static inline unsigned long dev_pm_opp_get_freq(struct dev_pm_opp *opp)
static inline unsigned long dev_pm_opp_get_freq_indexed(struct dev_pm_opp *opp, u32 index)
{
return 0;
}
@ -247,36 +259,55 @@ static inline unsigned long dev_pm_opp_get_suspend_opp_freq(struct device *dev)
return 0;
}
static inline struct dev_pm_opp *dev_pm_opp_find_level_exact(struct device *dev,
unsigned int level)
{
return ERR_PTR(-EOPNOTSUPP);
}
static inline struct dev_pm_opp *dev_pm_opp_find_level_ceil(struct device *dev,
unsigned int *level)
{
return ERR_PTR(-EOPNOTSUPP);
}
static inline struct dev_pm_opp *dev_pm_opp_find_freq_exact(struct device *dev,
unsigned long freq, bool available)
{
return ERR_PTR(-EOPNOTSUPP);
}
static inline struct dev_pm_opp *
dev_pm_opp_find_freq_exact_indexed(struct device *dev, unsigned long freq,
u32 index, bool available)
{
return ERR_PTR(-EOPNOTSUPP);
}
static inline struct dev_pm_opp *dev_pm_opp_find_freq_floor(struct device *dev,
unsigned long *freq)
{
return ERR_PTR(-EOPNOTSUPP);
}
static inline struct dev_pm_opp *
dev_pm_opp_find_freq_floor_indexed(struct device *dev, unsigned long *freq, u32 index)
{
return ERR_PTR(-EOPNOTSUPP);
}
static inline struct dev_pm_opp *dev_pm_opp_find_freq_ceil(struct device *dev,
unsigned long *freq)
{
return ERR_PTR(-EOPNOTSUPP);
}
static inline struct dev_pm_opp *
dev_pm_opp_find_freq_ceil_indexed(struct device *dev, unsigned long *freq, u32 index)
{
return ERR_PTR(-EOPNOTSUPP);
}
static inline struct dev_pm_opp *dev_pm_opp_find_level_exact(struct device *dev,
unsigned int level)
{
return ERR_PTR(-EOPNOTSUPP);
}
static inline struct dev_pm_opp *dev_pm_opp_find_level_ceil(struct device *dev,
unsigned int *level)
{
return ERR_PTR(-EOPNOTSUPP);
}
static inline struct dev_pm_opp *dev_pm_opp_find_bw_ceil(struct device *dev,
unsigned int *bw, int index)
{
@ -631,4 +662,9 @@ static inline void dev_pm_opp_put_prop_name(int token)
dev_pm_opp_clear_config(token);
}
static inline unsigned long dev_pm_opp_get_freq(struct dev_pm_opp *opp)
{
return dev_pm_opp_get_freq_indexed(opp, 0);
}
#endif /* __LINUX_OPP_H__ */