diff options
author | Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> | 2023-07-20 11:10:52 +0530 |
---|---|---|
committer | Viresh Kumar <viresh.kumar@linaro.org> | 2023-07-21 15:08:27 +0530 |
commit | 142e17c1c2b48e3fb4f024e62ab6dee18f268694 (patch) | |
tree | 7a106123a9417aceab9869d77840b426fdbcbd27 | |
parent | 754833b3194c30dad5af0145e25192a8e29521ab (diff) |
OPP: Introduce dev_pm_opp_find_freq_{ceil/floor}_indexed() APIs
In the case of devices with multiple clocks, drivers need to specify the
clock index for the OPP framework to find the OPP corresponding to the
floor/ceil of the supplied frequency. So let's introduce the two new APIs
accepting the clock index as an argument.
These APIs use the exising _find_key_ceil() helper by supplying the clock
index to it.
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
[ Viresh: Rearranged definitions in pm_opp.h ]
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
-rw-r--r-- | drivers/opp/core.c | 56 | ||||
-rw-r--r-- | include/linux/pm_opp.h | 18 |
2 files changed, 74 insertions, 0 deletions
diff --git a/drivers/opp/core.c b/drivers/opp/core.c index 3f46e499d615..cb4f47b341f9 100644 --- a/drivers/opp/core.c +++ b/drivers/opp/core.c @@ -659,6 +659,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 * @freq: Start frequency @@ -684,6 +712,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 * @level: level to search for diff --git a/include/linux/pm_opp.h b/include/linux/pm_opp.h index 3821f50b9b89..2617f2c51f29 100644 --- a/include/linux/pm_opp.h +++ b/include/linux/pm_opp.h @@ -125,9 +125,15 @@ struct dev_pm_opp *dev_pm_opp_find_freq_exact(struct device *dev, struct dev_pm_opp *dev_pm_opp_find_freq_floor(struct device *dev, unsigned long *freq); +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); @@ -261,12 +267,24 @@ static inline struct dev_pm_opp *dev_pm_opp_find_freq_floor(struct device *dev, 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) { |