aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/power
diff options
context:
space:
mode:
authorNishanth Menon <nm@ti.com>2012-10-24 16:00:12 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2012-11-14 18:36:10 -0500
commit0779726cc265805d0f7c7dd1d791fa4076b31a9a (patch)
treea43a115b9b701dfa275566002cc2ad3d227792fe /drivers/base/power
parent80126ce7aeb4e187429681ef8a7785b7dcd7a348 (diff)
PM / OPP: predictable fail results for opp_find* functions, v2
Currently the opp_find* functions return -ENODEV when: a) it cant find a device (e.g. request for an OPP search on device which was not registered) b) When it cant find a match for the search strategy used This makes life a little in-efficient for users such as devfreq to make reasonable judgement before switching search strategies. So, standardize the return results as following: -EINVAL for bad pointer parameters -ENODEV when device cannot be found -ERANGE when search fails This has the following benefit for devfreq implementation: The search fails when an unregistered device pointer is provided. This is a trigger to change the search direction and search for a better fit, however, if we cannot differentiate between a valid search range failure Vs an unregistered device, second search goes through the same fail return condition. This can be avoided by appropriate handling of error return code. With this change, we also fix devfreq for the improved search strategy with updated error code. Signed-off-by: Nishanth Menon <nm@ti.com> Reviewed-by: Kevin Hilman <khilman@ti.com> Acked-by: MyungJoo Ham <myungjoo.ham@samsung.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/base/power')
-rw-r--r--drivers/base/power/opp.c27
1 files changed, 19 insertions, 8 deletions
diff --git a/drivers/base/power/opp.c b/drivers/base/power/opp.c
index 66888861f9eb..c8a908b099c0 100644
--- a/drivers/base/power/opp.c
+++ b/drivers/base/power/opp.c
@@ -235,7 +235,10 @@ EXPORT_SYMBOL(opp_get_opp_count);
235 * 235 *
236 * Searches for exact match in the opp list and returns pointer to the matching 236 * Searches for exact match in the opp list and returns pointer to the matching
237 * opp if found, else returns ERR_PTR in case of error and should be handled 237 * opp if found, else returns ERR_PTR in case of error and should be handled
238 * using IS_ERR. 238 * using IS_ERR. Error return values can be:
239 * EINVAL: for bad pointer
240 * ERANGE: no match found for search
241 * ENODEV: if device not found in list of registered devices
239 * 242 *
240 * Note: available is a modifier for the search. if available=true, then the 243 * Note: available is a modifier for the search. if available=true, then the
241 * match is for exact matching frequency and is available in the stored OPP 244 * match is for exact matching frequency and is available in the stored OPP
@@ -254,7 +257,7 @@ struct opp *opp_find_freq_exact(struct device *dev, unsigned long freq,
254 bool available) 257 bool available)
255{ 258{
256 struct device_opp *dev_opp; 259 struct device_opp *dev_opp;
257 struct opp *temp_opp, *opp = ERR_PTR(-ENODEV); 260 struct opp *temp_opp, *opp = ERR_PTR(-ERANGE);
258 261
259 dev_opp = find_device_opp(dev); 262 dev_opp = find_device_opp(dev);
260 if (IS_ERR(dev_opp)) { 263 if (IS_ERR(dev_opp)) {
@@ -284,7 +287,11 @@ EXPORT_SYMBOL(opp_find_freq_exact);
284 * for a device. 287 * for a device.
285 * 288 *
286 * Returns matching *opp and refreshes *freq accordingly, else returns 289 * Returns matching *opp and refreshes *freq accordingly, else returns
287 * ERR_PTR in case of error and should be handled using IS_ERR. 290 * ERR_PTR in case of error and should be handled using IS_ERR. Error return
291 * values can be:
292 * EINVAL: for bad pointer
293 * ERANGE: no match found for search
294 * ENODEV: if device not found in list of registered devices
288 * 295 *
289 * Locking: This function must be called under rcu_read_lock(). opp is a rcu 296 * Locking: This function must be called under rcu_read_lock(). opp is a rcu
290 * protected pointer. The reason for the same is that the opp pointer which is 297 * protected pointer. The reason for the same is that the opp pointer which is
@@ -295,7 +302,7 @@ EXPORT_SYMBOL(opp_find_freq_exact);
295struct opp *opp_find_freq_ceil(struct device *dev, unsigned long *freq) 302struct opp *opp_find_freq_ceil(struct device *dev, unsigned long *freq)
296{ 303{
297 struct device_opp *dev_opp; 304 struct device_opp *dev_opp;
298 struct opp *temp_opp, *opp = ERR_PTR(-ENODEV); 305 struct opp *temp_opp, *opp = ERR_PTR(-ERANGE);
299 306
300 if (!dev || !freq) { 307 if (!dev || !freq) {
301 dev_err(dev, "%s: Invalid argument freq=%p\n", __func__, freq); 308 dev_err(dev, "%s: Invalid argument freq=%p\n", __func__, freq);
@@ -304,7 +311,7 @@ struct opp *opp_find_freq_ceil(struct device *dev, unsigned long *freq)
304 311
305 dev_opp = find_device_opp(dev); 312 dev_opp = find_device_opp(dev);
306 if (IS_ERR(dev_opp)) 313 if (IS_ERR(dev_opp))
307 return opp; 314 return ERR_CAST(dev_opp);
308 315
309 list_for_each_entry_rcu(temp_opp, &dev_opp->opp_list, node) { 316 list_for_each_entry_rcu(temp_opp, &dev_opp->opp_list, node) {
310 if (temp_opp->available && temp_opp->rate >= *freq) { 317 if (temp_opp->available && temp_opp->rate >= *freq) {
@@ -327,7 +334,11 @@ EXPORT_SYMBOL(opp_find_freq_ceil);
327 * for a device. 334 * for a device.
328 * 335 *
329 * Returns matching *opp and refreshes *freq accordingly, else returns 336 * Returns matching *opp and refreshes *freq accordingly, else returns
330 * ERR_PTR in case of error and should be handled using IS_ERR. 337 * ERR_PTR in case of error and should be handled using IS_ERR. Error return
338 * values can be:
339 * EINVAL: for bad pointer
340 * ERANGE: no match found for search
341 * ENODEV: if device not found in list of registered devices
331 * 342 *
332 * Locking: This function must be called under rcu_read_lock(). opp is a rcu 343 * Locking: This function must be called under rcu_read_lock(). opp is a rcu
333 * protected pointer. The reason for the same is that the opp pointer which is 344 * protected pointer. The reason for the same is that the opp pointer which is
@@ -338,7 +349,7 @@ EXPORT_SYMBOL(opp_find_freq_ceil);
338struct opp *opp_find_freq_floor(struct device *dev, unsigned long *freq) 349struct opp *opp_find_freq_floor(struct device *dev, unsigned long *freq)
339{ 350{
340 struct device_opp *dev_opp; 351 struct device_opp *dev_opp;
341 struct opp *temp_opp, *opp = ERR_PTR(-ENODEV); 352 struct opp *temp_opp, *opp = ERR_PTR(-ERANGE);
342 353
343 if (!dev || !freq) { 354 if (!dev || !freq) {
344 dev_err(dev, "%s: Invalid argument freq=%p\n", __func__, freq); 355 dev_err(dev, "%s: Invalid argument freq=%p\n", __func__, freq);
@@ -347,7 +358,7 @@ struct opp *opp_find_freq_floor(struct device *dev, unsigned long *freq)
347 358
348 dev_opp = find_device_opp(dev); 359 dev_opp = find_device_opp(dev);
349 if (IS_ERR(dev_opp)) 360 if (IS_ERR(dev_opp))
350 return opp; 361 return ERR_CAST(dev_opp);
351 362
352 list_for_each_entry_rcu(temp_opp, &dev_opp->opp_list, node) { 363 list_for_each_entry_rcu(temp_opp, &dev_opp->opp_list, node) {
353 if (temp_opp->available) { 364 if (temp_opp->available) {