Received: by 2002:a17:90a:88:0:0:0:0 with SMTP id a8csp23980pja; Fri, 22 Nov 2019 02:59:00 -0800 (PST) X-Google-Smtp-Source: APXvYqyCi9ws1V9OiFM9MnJHgcQkA1aoFAYfA9P+WB+UtseyDo7emBW3dex9adZroG79t3MKbE0Q X-Received: by 2002:a50:9fc1:: with SMTP id c59mr287096edf.305.1574420340587; Fri, 22 Nov 2019 02:59:00 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1574420340; cv=none; d=google.com; s=arc-20160816; b=IbG/c9v0EUubIlCwmegooM1QhFxgP2tFsAEW8/qoOmS2jP0SjrGIGrkIGLEYh2EBe+ CF29udCBKZvxt3/lpeSuQ9i9RHadAB7zykcxrITwYKHMucX/PLN8PhjVXdpQDpCO822d kj0TEqIfsOyd4dStbW/2GxHRebwIAwN53U4m/b0hCCFMbZu1UKz8veC8cwS/KgcmPAJu UE+4l+b/BjB1H1887Xu44WE3Uk5SDe2+I6FWOzGvb2J+gZvP4Vv55Qpi3plPpmah+4X3 Jy3g6Q7yWpY0cMojIJ4sOLz3ueurp1rSujMUwnPA/vwAwQbn3T6lhwBtmFkYhu17f68J HKuw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=nAdKYpRccBdWFVS2Lbn72qQN5lqZ5N70NSSlRp85zb4=; b=qT3PF5+ogQg2PZ6GPnqG3gLtCYM50YEEb/CwDNBPlblsqPjvj8YeP/LvZ2XoiNK6/X kSfEkoe6yxPlplDfTH/zKGQmxQLYPaC1o29wGkP4T7cM/vLJDankwdFx0WpqzaQH/Gwf wBzCpjeCARepB3RQnY7dAeCfd2phDTt5AcegEmwxJ7zC7tAtYBBOspulwNnvOBHJ0sJE cMe0olNuTJTc4ONcnW31X8DhPD1PFFGwhy51jLSIA7ZN16b8QLQPzu+Qjpz0kStlrZIY 4jtHqdGRbP+r0ZPLfrKzur/yxHGkWfTrKaV6jdQF59WtOvay0vXB+ykswNnLAiPPMIuA Ebfg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=r1ssk3W7; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id i26si3766185edy.197.2019.11.22.02.58.37; Fri, 22 Nov 2019 02:59:00 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=r1ssk3W7; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730681AbfKVK5e (ORCPT + 99 others); Fri, 22 Nov 2019 05:57:34 -0500 Received: from mail.kernel.org ([198.145.29.99]:46230 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730068AbfKVK5X (ORCPT ); Fri, 22 Nov 2019 05:57:23 -0500 Received: from localhost (83-86-89-107.cable.dynamic.v4.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id E30DE2071C; Fri, 22 Nov 2019 10:57:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1574420242; bh=MHLTiLMo6OoNuIgCw9aGwbaQZgICcAPVVuPD8MIH+yM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=r1ssk3W7EKQZOmyJ9rHCEd3qVuX0ozDgWu5oV1cvLwZrxRmCb3RUz401gr+kEOsKQ meC4mXxM3sjbymPVWJSEp22uUzRSraucD5YqGEwU5jqlof9/BOcYq9SKwlu7y0ErEf +7yPHvM1+GtYqLpSu+TrJJP/R51VvHtYGJdtV/rM= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Enric Balletbo i Serra , Chanwoo Choi , MyungJoo Ham , Sasha Levin Subject: [PATCH 4.19 041/220] PM / devfreq: Fix devfreq_add_device() when drivers are built as modules. Date: Fri, 22 Nov 2019 11:26:46 +0100 Message-Id: <20191122100915.244786602@linuxfoundation.org> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20191122100912.732983531@linuxfoundation.org> References: <20191122100912.732983531@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Enric Balletbo i Serra [ Upstream commit 23c7b54ca1cd1797ef39169ab85e6d46f1c2d061 ] 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 Reviewed-by: Chanwoo Choi Signed-off-by: MyungJoo Ham Signed-off-by: Sasha Levin --- drivers/devfreq/devfreq.c | 53 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 4 deletions(-) diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index 4c49bb1330b52..62ead442a8721 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -11,6 +11,7 @@ */ #include +#include #include #include #include @@ -221,6 +222,49 @@ static struct devfreq_governor *find_devfreq_governor(const char *name) return ERR_PTR(-ENODEV); } +/** + * try_then_request_governor() - Try to find the governor and request the + * module if is not found. + * @name: name of the governor + * + * Search the list of devfreq governors and request the module and try again + * if is not found. This can happen when both drivers (the governor driver + * and the driver that call devfreq_add_device) are built as modules. + * devfreq_list_lock should be held by the caller. Returns the matched + * governor's pointer. + */ +static struct devfreq_governor *try_then_request_governor(const char *name) +{ + struct devfreq_governor *governor; + int err = 0; + + if (IS_ERR_OR_NULL(name)) { + pr_err("DEVFREQ: %s: Invalid parameters\n", __func__); + return ERR_PTR(-EINVAL); + } + WARN(!mutex_is_locked(&devfreq_list_lock), + "devfreq_list_lock must be locked."); + + governor = find_devfreq_governor(name); + if (IS_ERR(governor)) { + mutex_unlock(&devfreq_list_lock); + + if (!strncmp(name, DEVFREQ_GOV_SIMPLE_ONDEMAND, + DEVFREQ_NAME_LEN)) + err = request_module("governor_%s", "simpleondemand"); + else + err = request_module("governor_%s", name); + /* Restore previous state before return */ + mutex_lock(&devfreq_list_lock); + if (err) + return NULL; + + governor = find_devfreq_governor(name); + } + + return governor; +} + static int devfreq_notify_transition(struct devfreq *devfreq, struct devfreq_freqs *freqs, unsigned int state) { @@ -646,9 +690,8 @@ struct devfreq *devfreq_add_device(struct device *dev, mutex_unlock(&devfreq->lock); mutex_lock(&devfreq_list_lock); - list_add(&devfreq->node, &devfreq_list); - governor = find_devfreq_governor(devfreq->governor_name); + governor = try_then_request_governor(devfreq->governor_name); if (IS_ERR(governor)) { dev_err(dev, "%s: Unable to find governor for the device\n", __func__); @@ -664,12 +707,14 @@ struct devfreq *devfreq_add_device(struct device *dev, __func__); goto err_init; } + + list_add(&devfreq->node, &devfreq_list); + mutex_unlock(&devfreq_list_lock); return devfreq; err_init: - list_del(&devfreq->node); mutex_unlock(&devfreq_list_lock); device_unregister(&devfreq->dev); @@ -991,7 +1036,7 @@ static ssize_t governor_store(struct device *dev, struct device_attribute *attr, return -EINVAL; mutex_lock(&devfreq_list_lock); - governor = find_devfreq_governor(str_governor); + governor = try_then_request_governor(str_governor); if (IS_ERR(governor)) { ret = PTR_ERR(governor); goto out; -- 2.20.1