diff options
author | Viresh Kumar <viresh.kumar@linaro.org> | 2014-12-09 23:15:35 -0500 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2014-12-10 16:18:34 -0500 |
commit | 6ce4184d0308888dd6ac2b6ab5f8ec0b2006092e (patch) | |
tree | 986a1cb3efce104afd0cc80d9a1c151a3e6a7845 | |
parent | 07cce74a7b259cb90029530e9549bf1d9a1b1c34 (diff) |
PM / OPP: do error handling at the bottom of dev_pm_opp_add_dynamic()
This makes it less error prone and moves common resource deallocation at a
single place.
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r-- | drivers/base/power/opp.c | 17 |
1 files changed, 10 insertions, 7 deletions
diff --git a/drivers/base/power/opp.c b/drivers/base/power/opp.c index 1150b9d2e012..d24dd614a0bd 100644 --- a/drivers/base/power/opp.c +++ b/drivers/base/power/opp.c | |||
@@ -413,6 +413,7 @@ static int dev_pm_opp_add_dynamic(struct device *dev, unsigned long freq, | |||
413 | struct device_opp *dev_opp = NULL; | 413 | struct device_opp *dev_opp = NULL; |
414 | struct dev_pm_opp *opp, *new_opp; | 414 | struct dev_pm_opp *opp, *new_opp; |
415 | struct list_head *head; | 415 | struct list_head *head; |
416 | int ret; | ||
416 | 417 | ||
417 | /* allocate new OPP node */ | 418 | /* allocate new OPP node */ |
418 | new_opp = kzalloc(sizeof(*new_opp), GFP_KERNEL); | 419 | new_opp = kzalloc(sizeof(*new_opp), GFP_KERNEL); |
@@ -435,9 +436,8 @@ static int dev_pm_opp_add_dynamic(struct device *dev, unsigned long freq, | |||
435 | if (IS_ERR(dev_opp)) { | 436 | if (IS_ERR(dev_opp)) { |
436 | dev_opp = add_device_opp(dev); | 437 | dev_opp = add_device_opp(dev); |
437 | if (!dev_opp) { | 438 | if (!dev_opp) { |
438 | mutex_unlock(&dev_opp_list_lock); | 439 | ret = -ENOMEM; |
439 | kfree(new_opp); | 440 | goto free_opp; |
440 | return -ENOMEM; | ||
441 | } | 441 | } |
442 | 442 | ||
443 | head = &dev_opp->opp_list; | 443 | head = &dev_opp->opp_list; |
@@ -458,15 +458,13 @@ static int dev_pm_opp_add_dynamic(struct device *dev, unsigned long freq, | |||
458 | 458 | ||
459 | /* Duplicate OPPs ? */ | 459 | /* Duplicate OPPs ? */ |
460 | if (new_opp->rate == opp->rate) { | 460 | if (new_opp->rate == opp->rate) { |
461 | int ret = opp->available && new_opp->u_volt == opp->u_volt ? | 461 | ret = opp->available && new_opp->u_volt == opp->u_volt ? |
462 | 0 : -EEXIST; | 462 | 0 : -EEXIST; |
463 | 463 | ||
464 | dev_warn(dev, "%s: duplicate OPPs detected. Existing: freq: %lu, volt: %lu, enabled: %d. New: freq: %lu, volt: %lu, enabled: %d\n", | 464 | dev_warn(dev, "%s: duplicate OPPs detected. Existing: freq: %lu, volt: %lu, enabled: %d. New: freq: %lu, volt: %lu, enabled: %d\n", |
465 | __func__, opp->rate, opp->u_volt, opp->available, | 465 | __func__, opp->rate, opp->u_volt, opp->available, |
466 | new_opp->rate, new_opp->u_volt, new_opp->available); | 466 | new_opp->rate, new_opp->u_volt, new_opp->available); |
467 | mutex_unlock(&dev_opp_list_lock); | 467 | goto free_opp; |
468 | kfree(new_opp); | ||
469 | return ret; | ||
470 | } | 468 | } |
471 | 469 | ||
472 | list_add: | 470 | list_add: |
@@ -480,6 +478,11 @@ list_add: | |||
480 | */ | 478 | */ |
481 | srcu_notifier_call_chain(&dev_opp->srcu_head, OPP_EVENT_ADD, new_opp); | 479 | srcu_notifier_call_chain(&dev_opp->srcu_head, OPP_EVENT_ADD, new_opp); |
482 | return 0; | 480 | return 0; |
481 | |||
482 | free_opp: | ||
483 | mutex_unlock(&dev_opp_list_lock); | ||
484 | kfree(new_opp); | ||
485 | return ret; | ||
483 | } | 486 | } |
484 | 487 | ||
485 | /** | 488 | /** |