aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/devfreq
diff options
context:
space:
mode:
authorVincent Donnefort <vincent.donnefort@arm.com>2018-09-02 20:02:07 -0400
committerMyungJoo Ham <myungjoo.ham@samsung.com>2018-10-01 21:16:41 -0400
commit2f061fd0c2d852e32e03a903fccd810663c5c31e (patch)
tree9cd1724ec2a4cf6aeb03d1e56c65d6fa371588d3 /drivers/devfreq
parentf037eb8c1f476bc903d99695c1eb9f99ccb46b27 (diff)
PM / devfreq: stopping the governor before device_unregister()
device_release() is freeing the resources before calling the device specific release callback which is, in the case of devfreq, stopping the governor. It is a problem as some governors are using the device resources. e.g. simpleondemand which is using the devfreq deferrable monitoring work. If it is not stopped before the resources are freed, it might lead to a use after free. Signed-off-by: Vincent Donnefort <vincent.donnefort@arm.com> Reviewed-by: John Einar Reitan <john.reitan@arm.com> [cw00.choi: Fix merge conflict] Reviewed-by: Chanwoo Choi <cw00.choi@samsung.com> Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
Diffstat (limited to 'drivers/devfreq')
-rw-r--r--drivers/devfreq/devfreq.c9
1 files changed, 4 insertions, 5 deletions
diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index b5e7af60723c..1868423355d9 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -575,10 +575,6 @@ static void devfreq_dev_release(struct device *dev)
575 list_del(&devfreq->node); 575 list_del(&devfreq->node);
576 mutex_unlock(&devfreq_list_lock); 576 mutex_unlock(&devfreq_list_lock);
577 577
578 if (devfreq->governor)
579 devfreq->governor->event_handler(devfreq,
580 DEVFREQ_GOV_STOP, NULL);
581
582 if (devfreq->profile->exit) 578 if (devfreq->profile->exit)
583 devfreq->profile->exit(devfreq->dev.parent); 579 devfreq->profile->exit(devfreq->dev.parent);
584 580
@@ -714,7 +710,7 @@ struct devfreq *devfreq_add_device(struct device *dev,
714err_init: 710err_init:
715 mutex_unlock(&devfreq_list_lock); 711 mutex_unlock(&devfreq_list_lock);
716 712
717 device_unregister(&devfreq->dev); 713 devfreq_remove_device(devfreq);
718 devfreq = NULL; 714 devfreq = NULL;
719err_dev: 715err_dev:
720 if (devfreq) 716 if (devfreq)
@@ -735,6 +731,9 @@ int devfreq_remove_device(struct devfreq *devfreq)
735 if (!devfreq) 731 if (!devfreq)
736 return -EINVAL; 732 return -EINVAL;
737 733
734 if (devfreq->governor)
735 devfreq->governor->event_handler(devfreq,
736 DEVFREQ_GOV_STOP, NULL);
738 device_unregister(&devfreq->dev); 737 device_unregister(&devfreq->dev);
739 738
740 return 0; 739 return 0;