aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/devfreq/devfreq.c
diff options
context:
space:
mode:
authorEnric Balletbo i Serra <enric.balletbo@collabora.com>2018-07-04 04:45:50 -0400
committerMyungJoo Ham <myungjoo.ham@samsung.com>2018-10-01 21:16:41 -0400
commit23c7b54ca1cd1797ef39169ab85e6d46f1c2d061 (patch)
treec04d424c2507228ea6cffb310f9b50b6b738296e /drivers/devfreq/devfreq.c
parent17b57b1883c1285f3d0dc2266e8f79286a7bef38 (diff)
PM / devfreq: Fix devfreq_add_device() when drivers are built as modules.
When the devfreq driver and the governor driver are built as modules, the call to devfreq_add_device() or governor_store() fails because the governor driver is not loaded at the time the devfreq driver loads. The devfreq driver has a build dependency on the governor but also should have a runtime dependency. We need to make sure that the governor driver is loaded before the devfreq driver. This patch fixes this bug by adding a try_then_request_governor() function. First tries to find the governor, and then, if it is not found, it requests the module and tries again. Fixes: 1b5c1be2c88e (PM / devfreq: map devfreq drivers to governor using name) Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com> Reviewed-by: Chanwoo Choi <cw00.choi@samsung.com> Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
Diffstat (limited to 'drivers/devfreq/devfreq.c')
-rw-r--r--drivers/devfreq/devfreq.c53
1 files changed, 49 insertions, 4 deletions
diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index 4c49bb1330b5..62ead442a872 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -11,6 +11,7 @@
11 */ 11 */
12 12
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/kmod.h>
14#include <linux/sched.h> 15#include <linux/sched.h>
15#include <linux/errno.h> 16#include <linux/errno.h>
16#include <linux/err.h> 17#include <linux/err.h>
@@ -221,6 +222,49 @@ static struct devfreq_governor *find_devfreq_governor(const char *name)
221 return ERR_PTR(-ENODEV); 222 return ERR_PTR(-ENODEV);
222} 223}
223 224
225/**
226 * try_then_request_governor() - Try to find the governor and request the
227 * module if is not found.
228 * @name: name of the governor
229 *
230 * Search the list of devfreq governors and request the module and try again
231 * if is not found. This can happen when both drivers (the governor driver
232 * and the driver that call devfreq_add_device) are built as modules.
233 * devfreq_list_lock should be held by the caller. Returns the matched
234 * governor's pointer.
235 */
236static struct devfreq_governor *try_then_request_governor(const char *name)
237{
238 struct devfreq_governor *governor;
239 int err = 0;
240
241 if (IS_ERR_OR_NULL(name)) {
242 pr_err("DEVFREQ: %s: Invalid parameters\n", __func__);
243 return ERR_PTR(-EINVAL);
244 }
245 WARN(!mutex_is_locked(&devfreq_list_lock),
246 "devfreq_list_lock must be locked.");
247
248 governor = find_devfreq_governor(name);
249 if (IS_ERR(governor)) {
250 mutex_unlock(&devfreq_list_lock);
251
252 if (!strncmp(name, DEVFREQ_GOV_SIMPLE_ONDEMAND,
253 DEVFREQ_NAME_LEN))
254 err = request_module("governor_%s", "simpleondemand");
255 else
256 err = request_module("governor_%s", name);
257 /* Restore previous state before return */
258 mutex_lock(&devfreq_list_lock);
259 if (err)
260 return NULL;
261
262 governor = find_devfreq_governor(name);
263 }
264
265 return governor;
266}
267
224static int devfreq_notify_transition(struct devfreq *devfreq, 268static int devfreq_notify_transition(struct devfreq *devfreq,
225 struct devfreq_freqs *freqs, unsigned int state) 269 struct devfreq_freqs *freqs, unsigned int state)
226{ 270{
@@ -646,9 +690,8 @@ struct devfreq *devfreq_add_device(struct device *dev,
646 mutex_unlock(&devfreq->lock); 690 mutex_unlock(&devfreq->lock);
647 691
648 mutex_lock(&devfreq_list_lock); 692 mutex_lock(&devfreq_list_lock);
649 list_add(&devfreq->node, &devfreq_list);
650 693
651 governor = find_devfreq_governor(devfreq->governor_name); 694 governor = try_then_request_governor(devfreq->governor_name);
652 if (IS_ERR(governor)) { 695 if (IS_ERR(governor)) {
653 dev_err(dev, "%s: Unable to find governor for the device\n", 696 dev_err(dev, "%s: Unable to find governor for the device\n",
654 __func__); 697 __func__);
@@ -664,12 +707,14 @@ struct devfreq *devfreq_add_device(struct device *dev,
664 __func__); 707 __func__);
665 goto err_init; 708 goto err_init;
666 } 709 }
710
711 list_add(&devfreq->node, &devfreq_list);
712
667 mutex_unlock(&devfreq_list_lock); 713 mutex_unlock(&devfreq_list_lock);
668 714
669 return devfreq; 715 return devfreq;
670 716
671err_init: 717err_init:
672 list_del(&devfreq->node);
673 mutex_unlock(&devfreq_list_lock); 718 mutex_unlock(&devfreq_list_lock);
674 719
675 device_unregister(&devfreq->dev); 720 device_unregister(&devfreq->dev);
@@ -991,7 +1036,7 @@ static ssize_t governor_store(struct device *dev, struct device_attribute *attr,
991 return -EINVAL; 1036 return -EINVAL;
992 1037
993 mutex_lock(&devfreq_list_lock); 1038 mutex_lock(&devfreq_list_lock);
994 governor = find_devfreq_governor(str_governor); 1039 governor = try_then_request_governor(str_governor);
995 if (IS_ERR(governor)) { 1040 if (IS_ERR(governor)) {
996 ret = PTR_ERR(governor); 1041 ret = PTR_ERR(governor);
997 goto out; 1042 goto out;