diff options
| author | Chanwoo Choi <cw00.choi@samsung.com> | 2014-05-09 03:43:07 -0400 |
|---|---|---|
| committer | MyungJoo Ham <myungjoo.ham@samsung.com> | 2014-05-24 09:33:34 -0400 |
| commit | 585fc83ece43be63d5775e536f855db33dd752cf (patch) | |
| tree | 0bea4c3fe8e818f8d2e455d48265709c6e429c9e /drivers/devfreq | |
| parent | 26d518530b19c62dd8165165958d7429db4cd1fe (diff) | |
PM / devfreq: Fix devfreq_remove_device() to improve the sequence of resource free
This patch modify devfreq_remove_device() to improve the sequence of resource
free. If executing existing devfreq_remove_device(), this function always
executes _remove_devfreq() twice. In result, second _remove_devfreq() always
return error value. So, This patch resolves complicated function sequence
as following:
[Flow sequence before modification]
devfreq_remove_device()
_remove_devfreq(devfreq, false)
kfree(devfreq); /* Free devfreq */
if (!skip ...) { /* skip is false */
device_unregister(&devfreq->dev)
put_device(&devfreq->dev);
...
dev->release()
devfreq_dev_release()
_remove_devfreq(devfreq, true) <- Recall to free devfreq
/*
* Always return error without freeing resource because
* already _remove_devfreq() frees the memory of devfreq.
*/
}
[Flow sequence after modification]
devfreq_remove_device
device_unregister(&devfreq->dev)
put_device(&devfreq->dev);
..
dev->release()
devfreq_dev_release()
_remove_devfreq()
kfree(devfreq); /* Free devfreq */
Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
[Merge conflict resolved by MyungJoo]
Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
Diffstat (limited to 'drivers/devfreq')
| -rw-r--r-- | drivers/devfreq/devfreq.c | 14 |
1 files changed, 4 insertions, 10 deletions
diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index 2042ec3656ba..af4af7708574 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c | |||
| @@ -394,7 +394,7 @@ static int devfreq_notifier_call(struct notifier_block *nb, unsigned long type, | |||
| 394 | * @devfreq: the devfreq struct | 394 | * @devfreq: the devfreq struct |
| 395 | * @skip: skip calling device_unregister(). | 395 | * @skip: skip calling device_unregister(). |
| 396 | */ | 396 | */ |
| 397 | static void _remove_devfreq(struct devfreq *devfreq, bool skip) | 397 | static void _remove_devfreq(struct devfreq *devfreq) |
| 398 | { | 398 | { |
| 399 | mutex_lock(&devfreq_list_lock); | 399 | mutex_lock(&devfreq_list_lock); |
| 400 | if (IS_ERR(find_device_devfreq(devfreq->dev.parent))) { | 400 | if (IS_ERR(find_device_devfreq(devfreq->dev.parent))) { |
| @@ -412,11 +412,6 @@ static void _remove_devfreq(struct devfreq *devfreq, bool skip) | |||
| 412 | if (devfreq->profile->exit) | 412 | if (devfreq->profile->exit) |
| 413 | devfreq->profile->exit(devfreq->dev.parent); | 413 | devfreq->profile->exit(devfreq->dev.parent); |
| 414 | 414 | ||
| 415 | if (!skip && get_device(&devfreq->dev)) { | ||
| 416 | device_unregister(&devfreq->dev); | ||
| 417 | put_device(&devfreq->dev); | ||
| 418 | } | ||
| 419 | |||
| 420 | mutex_destroy(&devfreq->lock); | 415 | mutex_destroy(&devfreq->lock); |
| 421 | kfree(devfreq); | 416 | kfree(devfreq); |
| 422 | } | 417 | } |
| @@ -426,14 +421,12 @@ static void _remove_devfreq(struct devfreq *devfreq, bool skip) | |||
| 426 | * @dev: the devfreq device | 421 | * @dev: the devfreq device |
| 427 | * | 422 | * |
| 428 | * This calls _remove_devfreq() if _remove_devfreq() is not called. | 423 | * This calls _remove_devfreq() if _remove_devfreq() is not called. |
| 429 | * Note that devfreq_dev_release() could be called by _remove_devfreq() as | ||
| 430 | * well as by others unregistering the device. | ||
| 431 | */ | 424 | */ |
| 432 | static void devfreq_dev_release(struct device *dev) | 425 | static void devfreq_dev_release(struct device *dev) |
| 433 | { | 426 | { |
| 434 | struct devfreq *devfreq = to_devfreq(dev); | 427 | struct devfreq *devfreq = to_devfreq(dev); |
| 435 | 428 | ||
| 436 | _remove_devfreq(devfreq, true); | 429 | _remove_devfreq(devfreq); |
| 437 | } | 430 | } |
| 438 | 431 | ||
| 439 | /** | 432 | /** |
| @@ -544,7 +537,8 @@ int devfreq_remove_device(struct devfreq *devfreq) | |||
| 544 | if (!devfreq) | 537 | if (!devfreq) |
| 545 | return -EINVAL; | 538 | return -EINVAL; |
| 546 | 539 | ||
| 547 | _remove_devfreq(devfreq, false); | 540 | device_unregister(&devfreq->dev); |
| 541 | put_device(&devfreq->dev); | ||
| 548 | 542 | ||
| 549 | return 0; | 543 | return 0; |
| 550 | } | 544 | } |
