From patchwork Mon Jul 4 12:07:40 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 12905209 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7B779C43334 for ; Mon, 4 Jul 2022 12:08:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233921AbiGDMIS (ORCPT ); Mon, 4 Jul 2022 08:08:18 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43842 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233912AbiGDMIS (ORCPT ); Mon, 4 Jul 2022 08:08:18 -0400 Received: from mail-pl1-x636.google.com (mail-pl1-x636.google.com [IPv6:2607:f8b0:4864:20::636]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CF0D526D5 for ; Mon, 4 Jul 2022 05:08:16 -0700 (PDT) Received: by mail-pl1-x636.google.com with SMTP id m14so8405121plg.5 for ; Mon, 04 Jul 2022 05:08:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=JrOGtxkFmB6UH0d1rGpCly52Gseq2BReDDh7CSQ+HAQ=; b=qEcnTAIjcN2FhHiBHkMFY4f7YGO5q4FlBkrys/AbzPQC6gyy/PoQmTIQHzPNYy6smq upYJ9fz1S2hIU0zCWOvCx+NBN3GwOwVTxeDdILqAN+ZBJWgOL3aaVpHUyIEQf3W9y4GB oVL403zkb82N14XsG1SDHWSjz0ZiPEs46zuIfVSHfJrWNaUL7fXukYEFO95bvmNySRpt 2WjI0oVb7xcGbbjmi36Z9R6Znz1wCfpQRyNdOkQif0fIJC1HhAztjQCT/hrCRztijbZF NnFiHfq9aQuFW+0mlewI5A6zzCCj0hQQ1NQOdt9t0Vq/akqTODbLRtc4dXQmEtKgQF2I 4l5A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=JrOGtxkFmB6UH0d1rGpCly52Gseq2BReDDh7CSQ+HAQ=; b=sF0Ql3A3erLW+Q6i21do/fTkCHxQbqTwQYJmurj23aZraRYnjcBUUNjT2WWm/wK8eb GF9lJZRWJuxqWYCRIa5+A8fCGyL1YsdzNBrs5XRMjxCtzGjZ5uVWRQE/k/lm2ohEDiaz 2rQZ1dO354T2z8eI6t0EoIoG43fHkHoraLJ48mv4cPdPZ4cpSQxcZC8GPbwv3yTJPt6t WauVSTV4UFj+ccAWTGclITaAPIA+oVuT+S4Z1wh/Qyi2musNa+UhVjHwMzDgRIApL3qQ LhgCN1fSjwHuDNTHFlGz45kwABsCM4OnWi5nxhkmUB/Ut+Jv8NEe3MQSeXWhopOm0b6j jZEA== X-Gm-Message-State: AJIora+CTye27mI2H3H3uJRC9nN1jKpQoStnk0RVPPGDGp/Z/3aEUAtB v7Xp9tE7olibdZJHuhOZ4i9h4A== X-Google-Smtp-Source: AGRyM1vYOAL9m3AYRPKBdHWJfJ6+0roTu5XHMn0UOmQO2dYfab5ob4tUcBZNNswchA1997RbCNrTzw== X-Received: by 2002:a17:90b:1e06:b0:1ec:b513:4523 with SMTP id pg6-20020a17090b1e0600b001ecb5134523mr36905015pjb.58.1656936496430; Mon, 04 Jul 2022 05:08:16 -0700 (PDT) Received: from localhost ([122.171.18.80]) by smtp.gmail.com with ESMTPSA id u10-20020a056a00098a00b0051bc721b838sm21068389pfg.188.2022.07.04.05.08.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 04 Jul 2022 05:08:16 -0700 (PDT) From: Viresh Kumar To: "Rafael J. Wysocki" , Viresh Kumar , Chanwoo Choi , MyungJoo Ham , Kyungmin Park , Krzysztof Kozlowski , Alim Akhtar , Qiang Yu , Rob Herring , Tomeu Vizoso , Steven Price , Alyssa Rosenzweig , Nishanth Menon , Stephen Boyd , Thierry Reding , Jonathan Hunter Cc: linux-pm@vger.kernel.org, Vincent Guittot , Greg Kroah-Hartman , linux-kernel@vger.kernel.org, linux-samsung-soc@vger.kernel.org, linux-arm-kernel@lists.infradead.org, dri-devel@lists.freedesktop.org, lima@lists.freedesktop.org, linux-tegra@vger.kernel.org Subject: [PATCH V3 02/20] OPP: Make dev_pm_opp_set_regulators() accept NULL terminated list Date: Mon, 4 Jul 2022 17:37:40 +0530 Message-Id: <9730e011004b7526e79c6f409f5147fb235b414a.1656935522.git.viresh.kumar@linaro.org> X-Mailer: git-send-email 2.31.1.272.g89b43f80a514 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-samsung-soc@vger.kernel.org Make dev_pm_opp_set_regulators() accept a NULL terminated list of names instead of making the callers keep the two parameters in sync, which creates an opportunity for bugs to get in. Suggested-by: Greg Kroah-Hartman Signed-off-by: Viresh Kumar Reviewed-by: Chanwoo Choi --- drivers/cpufreq/cpufreq-dt.c | 9 ++++----- drivers/cpufreq/ti-cpufreq.c | 7 +++---- drivers/devfreq/exynos-bus.c | 4 ++-- drivers/gpu/drm/lima/lima_devfreq.c | 3 ++- drivers/gpu/drm/panfrost/panfrost_devfreq.c | 4 ++-- drivers/opp/core.c | 18 ++++++++++++------ drivers/soc/tegra/pmc.c | 4 ++-- include/linux/pm_opp.h | 9 ++++----- 8 files changed, 31 insertions(+), 27 deletions(-) diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c index 8fcaba541539..be0c19b3ffa5 100644 --- a/drivers/cpufreq/cpufreq-dt.c +++ b/drivers/cpufreq/cpufreq-dt.c @@ -193,7 +193,7 @@ static int dt_cpufreq_early_init(struct device *dev, int cpu) struct private_data *priv; struct device *cpu_dev; bool fallback = false; - const char *reg_name; + const char *reg_name[] = { NULL, NULL }; int ret; /* Check if this CPU is already covered by some other policy */ @@ -218,10 +218,9 @@ static int dt_cpufreq_early_init(struct device *dev, int cpu) * OPP layer will be taking care of regulators now, but it needs to know * the name of the regulator first. */ - reg_name = find_supply_name(cpu_dev); - if (reg_name) { - priv->opp_table = dev_pm_opp_set_regulators(cpu_dev, ®_name, - 1); + reg_name[0] = find_supply_name(cpu_dev); + if (reg_name[0]) { + priv->opp_table = dev_pm_opp_set_regulators(cpu_dev, reg_name); if (IS_ERR(priv->opp_table)) { ret = PTR_ERR(priv->opp_table); if (ret != -EPROBE_DEFER) diff --git a/drivers/cpufreq/ti-cpufreq.c b/drivers/cpufreq/ti-cpufreq.c index 8f9fdd864391..560d67a6bef1 100644 --- a/drivers/cpufreq/ti-cpufreq.c +++ b/drivers/cpufreq/ti-cpufreq.c @@ -173,7 +173,7 @@ static struct ti_cpufreq_soc_data omap34xx_soc_data = { * seems to always read as 0). */ -static const char * const omap3_reg_names[] = {"cpu0", "vbb"}; +static const char * const omap3_reg_names[] = {"cpu0", "vbb", NULL}; static struct ti_cpufreq_soc_data omap36xx_soc_data = { .reg_names = omap3_reg_names, @@ -326,7 +326,7 @@ static int ti_cpufreq_probe(struct platform_device *pdev) const struct of_device_id *match; struct opp_table *ti_opp_table; struct ti_cpufreq_data *opp_data; - const char * const default_reg_names[] = {"vdd", "vbb"}; + const char * const default_reg_names[] = {"vdd", "vbb", NULL}; int ret; match = dev_get_platdata(&pdev->dev); @@ -387,8 +387,7 @@ static int ti_cpufreq_probe(struct platform_device *pdev) if (opp_data->soc_data->reg_names) reg_names = opp_data->soc_data->reg_names; ti_opp_table = dev_pm_opp_set_regulators(opp_data->cpu_dev, - reg_names, - ARRAY_SIZE(default_reg_names)); + reg_names); if (IS_ERR(ti_opp_table)) { dev_pm_opp_put_supported_hw(opp_data->opp_table); ret = PTR_ERR(ti_opp_table); diff --git a/drivers/devfreq/exynos-bus.c b/drivers/devfreq/exynos-bus.c index e689101abc93..541baff93ee8 100644 --- a/drivers/devfreq/exynos-bus.c +++ b/drivers/devfreq/exynos-bus.c @@ -180,10 +180,10 @@ static int exynos_bus_parent_parse_of(struct device_node *np, { struct device *dev = bus->dev; struct opp_table *opp_table; - const char *vdd = "vdd"; + const char *supplies[] = { "vdd", NULL }; int i, ret, count, size; - opp_table = dev_pm_opp_set_regulators(dev, &vdd, 1); + opp_table = dev_pm_opp_set_regulators(dev, supplies); if (IS_ERR(opp_table)) { ret = PTR_ERR(opp_table); dev_err(dev, "failed to set regulators %d\n", ret); diff --git a/drivers/gpu/drm/lima/lima_devfreq.c b/drivers/gpu/drm/lima/lima_devfreq.c index 8989e215dfc9..dc83c5421125 100644 --- a/drivers/gpu/drm/lima/lima_devfreq.c +++ b/drivers/gpu/drm/lima/lima_devfreq.c @@ -111,6 +111,7 @@ int lima_devfreq_init(struct lima_device *ldev) struct dev_pm_opp *opp; unsigned long cur_freq; int ret; + const char *regulator_names[] = { "mali", NULL }; if (!device_property_present(dev, "operating-points-v2")) /* Optional, continue without devfreq */ @@ -122,7 +123,7 @@ int lima_devfreq_init(struct lima_device *ldev) if (ret) return ret; - ret = devm_pm_opp_set_regulators(dev, (const char *[]){ "mali" }, 1); + ret = devm_pm_opp_set_regulators(dev, regulator_names); if (ret) { /* Continue if the optional regulator is missing */ if (ret != -ENODEV) diff --git a/drivers/gpu/drm/panfrost/panfrost_devfreq.c b/drivers/gpu/drm/panfrost/panfrost_devfreq.c index 194af7f607a6..12784f349550 100644 --- a/drivers/gpu/drm/panfrost/panfrost_devfreq.c +++ b/drivers/gpu/drm/panfrost/panfrost_devfreq.c @@ -91,6 +91,7 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev) struct devfreq *devfreq; struct thermal_cooling_device *cooling; struct panfrost_devfreq *pfdevfreq = &pfdev->pfdevfreq; + const char *supplies[] = { pfdev->comp->supply_names[0], NULL }; if (pfdev->comp->num_supplies > 1) { /* @@ -101,8 +102,7 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev) return 0; } - ret = devm_pm_opp_set_regulators(dev, pfdev->comp->supply_names, - pfdev->comp->num_supplies); + ret = devm_pm_opp_set_regulators(dev, supplies); if (ret) { /* Continue if the optional regulator is missing */ if (ret != -ENODEV) { diff --git a/drivers/opp/core.c b/drivers/opp/core.c index e166bfe5fc90..4e4593957ec5 100644 --- a/drivers/opp/core.c +++ b/drivers/opp/core.c @@ -2105,13 +2105,20 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_put_prop_name); * This must be called before any OPPs are initialized for the device. */ struct opp_table *dev_pm_opp_set_regulators(struct device *dev, - const char * const names[], - unsigned int count) + const char * const names[]) { struct dev_pm_opp_supply *supplies; + const char * const *temp = names; struct opp_table *opp_table; struct regulator *reg; - int ret, i; + int count = 0, ret, i; + + /* Count number of regulators */ + while (*temp++) + count++; + + if (!count) + return ERR_PTR(-EINVAL); opp_table = _add_opp_table(dev, false); if (IS_ERR(opp_table)) @@ -2236,12 +2243,11 @@ static void devm_pm_opp_regulators_release(void *data) * Return: 0 on success and errorno otherwise. */ int devm_pm_opp_set_regulators(struct device *dev, - const char * const names[], - unsigned int count) + const char * const names[]) { struct opp_table *opp_table; - opp_table = dev_pm_opp_set_regulators(dev, names, count); + opp_table = dev_pm_opp_set_regulators(dev, names); if (IS_ERR(opp_table)) return PTR_ERR(opp_table); diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c index 5611d14d3ba2..6a4b8f7e7948 100644 --- a/drivers/soc/tegra/pmc.c +++ b/drivers/soc/tegra/pmc.c @@ -1384,7 +1384,7 @@ tegra_pmc_core_pd_opp_to_performance_state(struct generic_pm_domain *genpd, static int tegra_pmc_core_pd_add(struct tegra_pmc *pmc, struct device_node *np) { struct generic_pm_domain *genpd; - const char *rname = "core"; + const char *rname[] = { "core", NULL}; int err; genpd = devm_kzalloc(pmc->dev, sizeof(*genpd), GFP_KERNEL); @@ -1395,7 +1395,7 @@ static int tegra_pmc_core_pd_add(struct tegra_pmc *pmc, struct device_node *np) genpd->set_performance_state = tegra_pmc_core_pd_set_performance_state; genpd->opp_to_performance_state = tegra_pmc_core_pd_opp_to_performance_state; - err = devm_pm_opp_set_regulators(pmc->dev, &rname, 1); + err = devm_pm_opp_set_regulators(pmc->dev, rname); if (err) return dev_err_probe(pmc->dev, err, "failed to set core OPP regulator\n"); diff --git a/include/linux/pm_opp.h b/include/linux/pm_opp.h index 6708b4ec244d..4c490865d574 100644 --- a/include/linux/pm_opp.h +++ b/include/linux/pm_opp.h @@ -159,9 +159,9 @@ void dev_pm_opp_put_supported_hw(struct opp_table *opp_table); int devm_pm_opp_set_supported_hw(struct device *dev, const u32 *versions, unsigned int count); struct opp_table *dev_pm_opp_set_prop_name(struct device *dev, const char *name); void dev_pm_opp_put_prop_name(struct opp_table *opp_table); -struct opp_table *dev_pm_opp_set_regulators(struct device *dev, const char * const names[], unsigned int count); +struct opp_table *dev_pm_opp_set_regulators(struct device *dev, const char * const names[]); void dev_pm_opp_put_regulators(struct opp_table *opp_table); -int devm_pm_opp_set_regulators(struct device *dev, const char * const names[], unsigned int count); +int devm_pm_opp_set_regulators(struct device *dev, const char * const names[]); struct opp_table *dev_pm_opp_set_clkname(struct device *dev, const char *name); void dev_pm_opp_put_clkname(struct opp_table *opp_table); int devm_pm_opp_set_clkname(struct device *dev, const char *name); @@ -379,7 +379,7 @@ static inline struct opp_table *dev_pm_opp_set_prop_name(struct device *dev, con static inline void dev_pm_opp_put_prop_name(struct opp_table *opp_table) {} -static inline struct opp_table *dev_pm_opp_set_regulators(struct device *dev, const char * const names[], unsigned int count) +static inline struct opp_table *dev_pm_opp_set_regulators(struct device *dev, const char * const names[]) { return ERR_PTR(-EOPNOTSUPP); } @@ -387,8 +387,7 @@ static inline struct opp_table *dev_pm_opp_set_regulators(struct device *dev, co static inline void dev_pm_opp_put_regulators(struct opp_table *opp_table) {} static inline int devm_pm_opp_set_regulators(struct device *dev, - const char * const names[], - unsigned int count) + const char * const names[]) { return -EOPNOTSUPP; } From patchwork Mon Jul 4 12:07:48 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 12905210 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B58ACC433EF for ; Mon, 4 Jul 2022 12:09:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234233AbiGDMJY (ORCPT ); Mon, 4 Jul 2022 08:09:24 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44160 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233653AbiGDMIz (ORCPT ); Mon, 4 Jul 2022 08:08:55 -0400 Received: from mail-pj1-x1035.google.com (mail-pj1-x1035.google.com [IPv6:2607:f8b0:4864:20::1035]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 88434120BA for ; Mon, 4 Jul 2022 05:08:39 -0700 (PDT) Received: by mail-pj1-x1035.google.com with SMTP id s21so4607461pjq.4 for ; Mon, 04 Jul 2022 05:08:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=gC67fAeym71rEkFE9k+oqzY1p3FNiw9zFdZR8va6dpY=; b=Pml5WBPxzc1XEVvLTl/1ecRTpGQ07MA7iG8JyddspRVnPUQwLWFmlJQftSxz63Yxza K/GZWSVVmo2hxQsLGAap3J5G/2M4hNoblfZzpKMNGBodMzTorddM7t170hRgv1w4lmtg S2jdLbuWRGg/F5wsQMSdJM24vBhopvX9UNO40jOdGxaYYPSDEJJ5U/myb/5tbHsidLX9 e7+vnKrVOLwGubQi+FJLwBxPtvWwoEv2MMT0SRw3NRtnPitqQ5rFabe3y+qSVe/lCf/G lUjN5UKK5YebywPhB9hnEYQWwHqeuChDYfkYR0Yc56F3Yw3rGbqdjBhh0mGyzY+orwut HFkg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=gC67fAeym71rEkFE9k+oqzY1p3FNiw9zFdZR8va6dpY=; b=GeNP6y7Y5rGfNKm43rXT4Fll0au3leArIN2xVCLmEKyMBPURtZaRO9g/T2d+bUJYq/ qJaXf6mmJB2QTNZjXdAOUiWEum9bcZaseTGTVocN9aFCuzibUuCRSqSDDBDhNQKS7Iw7 bbVI3vk6y/xFeqPAEV9JM889YwamZWVDdOp0anOPU+9YzbHQ+REGb65IDDL8vhW+XMuW VVHt/XHHP5p6daQsWDFnOVAPXlDXlfBxBbZKT0lNiMuPuq85ggoPPqjXl4+pU9DnrpXS WB0tI2tlOyhBh7l5RwkrwPKPEi6r4d8iomWEvxgppIhipKzj9jMWSIGTstCMdKYd3IL1 kAXw== X-Gm-Message-State: AJIora+LZZUicsmUB/PZyetIEByEaMinykFPbVIGZ8gC7P66nLGfMFcR D2e+wgRoAw1OOPZlqrTYP1nIig== X-Google-Smtp-Source: AGRyM1s+vQ3aYmJZ6251w1IjsHZYQ2vqP9sfRwH11QyT+Pb7osqxW45+tzLdW7RxYOIhMU62h93xoA== X-Received: by 2002:a17:90b:17cb:b0:1ec:9d52:46f7 with SMTP id me11-20020a17090b17cb00b001ec9d5246f7mr34220040pjb.221.1656936519213; Mon, 04 Jul 2022 05:08:39 -0700 (PDT) Received: from localhost ([122.171.18.80]) by smtp.gmail.com with ESMTPSA id m11-20020a170902768b00b001637997d0d4sm20922989pll.206.2022.07.04.05.08.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 04 Jul 2022 05:08:38 -0700 (PDT) From: Viresh Kumar To: "Rafael J. Wysocki" , Viresh Kumar , Chanwoo Choi , MyungJoo Ham , Kyungmin Park , Krzysztof Kozlowski , Alim Akhtar , Nishanth Menon , Stephen Boyd Cc: linux-pm@vger.kernel.org, Vincent Guittot , linux-kernel@vger.kernel.org, linux-samsung-soc@vger.kernel.org, linux-arm-kernel@lists.infradead.org Subject: [PATCH V3 10/20] OPP: Migrate set-regulators API to use set-config helpers Date: Mon, 4 Jul 2022 17:37:48 +0530 Message-Id: <57b3f53e71550be92e28f4e2fa619f93bb5f3d78.1656935522.git.viresh.kumar@linaro.org> X-Mailer: git-send-email 2.31.1.272.g89b43f80a514 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-samsung-soc@vger.kernel.org Now that we have a central API to handle all OPP table configurations, migrate the set-regulators family of helpers to use the new infrastructure. The return type and parameter to the APIs change a bit due to this, update the current users as well in the same commit in order to avoid breaking builds. Signed-off-by: Viresh Kumar Reviewed-by: Chanwoo Choi --- drivers/cpufreq/cpufreq-dt.c | 12 ++--- drivers/devfreq/exynos-bus.c | 19 +++----- drivers/opp/core.c | 91 ++++++++---------------------------- include/linux/pm_opp.h | 44 ++++++++++------- 4 files changed, 60 insertions(+), 106 deletions(-) diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c index be0c19b3ffa5..d69d13a26414 100644 --- a/drivers/cpufreq/cpufreq-dt.c +++ b/drivers/cpufreq/cpufreq-dt.c @@ -29,9 +29,9 @@ struct private_data { cpumask_var_t cpus; struct device *cpu_dev; - struct opp_table *opp_table; struct cpufreq_frequency_table *freq_table; bool have_static_opps; + int opp_token; }; static LIST_HEAD(priv_list); @@ -220,9 +220,9 @@ static int dt_cpufreq_early_init(struct device *dev, int cpu) */ reg_name[0] = find_supply_name(cpu_dev); if (reg_name[0]) { - priv->opp_table = dev_pm_opp_set_regulators(cpu_dev, reg_name); - if (IS_ERR(priv->opp_table)) { - ret = PTR_ERR(priv->opp_table); + priv->opp_token = dev_pm_opp_set_regulators(cpu_dev, reg_name); + if (priv->opp_token < 0) { + ret = priv->opp_token; if (ret != -EPROBE_DEFER) dev_err(cpu_dev, "failed to set regulators: %d\n", ret); @@ -294,7 +294,7 @@ static int dt_cpufreq_early_init(struct device *dev, int cpu) out: if (priv->have_static_opps) dev_pm_opp_of_cpumask_remove_table(priv->cpus); - dev_pm_opp_put_regulators(priv->opp_table); + dev_pm_opp_put_regulators(priv->opp_token); free_cpumask: free_cpumask_var(priv->cpus); return ret; @@ -308,7 +308,7 @@ static void dt_cpufreq_release(void) dev_pm_opp_free_cpufreq_table(priv->cpu_dev, &priv->freq_table); if (priv->have_static_opps) dev_pm_opp_of_cpumask_remove_table(priv->cpus); - dev_pm_opp_put_regulators(priv->opp_table); + dev_pm_opp_put_regulators(priv->opp_token); free_cpumask_var(priv->cpus); list_del(&priv->node); } diff --git a/drivers/devfreq/exynos-bus.c b/drivers/devfreq/exynos-bus.c index 541baff93ee8..d1235242367f 100644 --- a/drivers/devfreq/exynos-bus.c +++ b/drivers/devfreq/exynos-bus.c @@ -33,7 +33,7 @@ struct exynos_bus { unsigned long curr_freq; - struct opp_table *opp_table; + int opp_token; struct clk *clk; unsigned int ratio; }; @@ -161,8 +161,7 @@ static void exynos_bus_exit(struct device *dev) dev_pm_opp_of_remove_table(dev); clk_disable_unprepare(bus->clk); - dev_pm_opp_put_regulators(bus->opp_table); - bus->opp_table = NULL; + dev_pm_opp_put_regulators(bus->opp_token); } static void exynos_bus_passive_exit(struct device *dev) @@ -179,18 +178,16 @@ static int exynos_bus_parent_parse_of(struct device_node *np, struct exynos_bus *bus) { struct device *dev = bus->dev; - struct opp_table *opp_table; const char *supplies[] = { "vdd", NULL }; int i, ret, count, size; - opp_table = dev_pm_opp_set_regulators(dev, supplies); - if (IS_ERR(opp_table)) { - ret = PTR_ERR(opp_table); + ret = dev_pm_opp_set_regulators(dev, supplies); + if (ret < 0) { dev_err(dev, "failed to set regulators %d\n", ret); return ret; } - bus->opp_table = opp_table; + bus->opp_token = ret; /* * Get the devfreq-event devices to get the current utilization of @@ -236,8 +233,7 @@ static int exynos_bus_parent_parse_of(struct device_node *np, return 0; err_regulator: - dev_pm_opp_put_regulators(bus->opp_table); - bus->opp_table = NULL; + dev_pm_opp_put_regulators(bus->opp_token); return ret; } @@ -459,8 +455,7 @@ static int exynos_bus_probe(struct platform_device *pdev) dev_pm_opp_of_remove_table(dev); clk_disable_unprepare(bus->clk); err_reg: - dev_pm_opp_put_regulators(bus->opp_table); - bus->opp_table = NULL; + dev_pm_opp_put_regulators(bus->opp_token); return ret; } diff --git a/drivers/opp/core.c b/drivers/opp/core.c index 7ab20c3b91ed..6ff9b5b69d07 100644 --- a/drivers/opp/core.c +++ b/drivers/opp/core.c @@ -991,8 +991,8 @@ static int _set_opp_custom(const struct opp_table *opp_table, int size; /* - * We support this only if dev_pm_opp_set_regulators() was called - * earlier. + * We support this only if dev_pm_opp_set_config() was called + * earlier to set regulators. */ if (opp_table->sod_supplies) { size = sizeof(*old_opp->supplies) * opp_table->regulator_count; @@ -2097,7 +2097,7 @@ void dev_pm_opp_put_prop_name(struct opp_table *opp_table) EXPORT_SYMBOL_GPL(dev_pm_opp_put_prop_name); /** - * dev_pm_opp_set_regulators() - Set regulator names for the device + * _opp_set_regulators() - Set regulator names for the device * @dev: Device for which regulator name is being set. * @names: Array of pointers to the names of the regulator. * @count: Number of regulators. @@ -2108,12 +2108,11 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_put_prop_name); * * This must be called before any OPPs are initialized for the device. */ -struct opp_table *dev_pm_opp_set_regulators(struct device *dev, - const char * const names[]) +static int _opp_set_regulators(struct opp_table *opp_table, struct device *dev, + const char * const names[]) { struct dev_pm_opp_supply *supplies; const char * const *temp = names; - struct opp_table *opp_table; struct regulator *reg; int count = 0, ret, i; @@ -2122,29 +2121,17 @@ struct opp_table *dev_pm_opp_set_regulators(struct device *dev, count++; if (!count) - return ERR_PTR(-EINVAL); - - opp_table = _add_opp_table(dev, false); - if (IS_ERR(opp_table)) - return opp_table; - - /* This should be called before OPPs are initialized */ - if (WARN_ON(!list_empty(&opp_table->opp_list))) { - ret = -EBUSY; - goto err; - } + return -EINVAL; /* Another CPU that shares the OPP table has set the regulators ? */ if (opp_table->regulators) - return opp_table; + return 0; opp_table->regulators = kmalloc_array(count, sizeof(*opp_table->regulators), GFP_KERNEL); - if (!opp_table->regulators) { - ret = -ENOMEM; - goto err; - } + if (!opp_table->regulators) + return -ENOMEM; for (i = 0; i < count; i++) { reg = regulator_get_optional(dev, names[i]); @@ -2174,7 +2161,7 @@ struct opp_table *dev_pm_opp_set_regulators(struct device *dev, } mutex_unlock(&opp_table->lock); - return opp_table; + return 0; free_regulators: while (i != 0) @@ -2183,26 +2170,20 @@ struct opp_table *dev_pm_opp_set_regulators(struct device *dev, kfree(opp_table->regulators); opp_table->regulators = NULL; opp_table->regulator_count = -1; -err: - dev_pm_opp_put_opp_table(opp_table); - return ERR_PTR(ret); + return ret; } -EXPORT_SYMBOL_GPL(dev_pm_opp_set_regulators); /** - * dev_pm_opp_put_regulators() - Releases resources blocked for regulator - * @opp_table: OPP table returned from dev_pm_opp_set_regulators(). + * _opp_put_regulators() - Releases resources blocked for regulator + * @opp_table: OPP table returned from _opp_set_regulators(). */ -void dev_pm_opp_put_regulators(struct opp_table *opp_table) +static void _opp_put_regulators(struct opp_table *opp_table) { int i; - if (unlikely(!opp_table)) - return; - if (!opp_table->regulators) - goto put_opp_table; + return; if (opp_table->enabled) { for (i = opp_table->regulator_count - 1; i >= 0; i--) @@ -2225,40 +2206,7 @@ void dev_pm_opp_put_regulators(struct opp_table *opp_table) kfree(opp_table->regulators); opp_table->regulators = NULL; opp_table->regulator_count = -1; - -put_opp_table: - dev_pm_opp_put_opp_table(opp_table); -} -EXPORT_SYMBOL_GPL(dev_pm_opp_put_regulators); - -static void devm_pm_opp_regulators_release(void *data) -{ - dev_pm_opp_put_regulators(data); -} - -/** - * devm_pm_opp_set_regulators() - Set regulator names for the device - * @dev: Device for which regulator name is being set. - * @names: Array of pointers to the names of the regulator. - * @count: Number of regulators. - * - * This is a resource-managed variant of dev_pm_opp_set_regulators(). - * - * Return: 0 on success and errorno otherwise. - */ -int devm_pm_opp_set_regulators(struct device *dev, - const char * const names[]) -{ - struct opp_table *opp_table; - - opp_table = dev_pm_opp_set_regulators(dev, names); - if (IS_ERR(opp_table)) - return PTR_ERR(opp_table); - - return devm_add_action_or_reset(dev, devm_pm_opp_regulators_release, - opp_table); } -EXPORT_SYMBOL_GPL(devm_pm_opp_set_regulators); /** * dev_pm_opp_set_clkname() - Set clk name for the device @@ -2633,7 +2581,7 @@ static void _opp_clear_config(struct opp_config_data *data) if (data->flags & OPP_CONFIG_GENPD) dev_pm_opp_detach_genpd(data->opp_table); if (data->flags & OPP_CONFIG_REGULATOR) - dev_pm_opp_put_regulators(data->opp_table); + _opp_put_regulators(data->opp_table); if (data->flags & OPP_CONFIG_SUPPORTED_HW) dev_pm_opp_put_supported_hw(data->opp_table); if (data->flags & OPP_CONFIG_REGULATOR_HELPER) @@ -2758,11 +2706,10 @@ int dev_pm_opp_set_config(struct device *dev, struct dev_pm_opp_config *config) /* Configure supplies */ if (config->regulator_names) { - err = dev_pm_opp_set_regulators(dev, config->regulator_names); - if (IS_ERR(err)) { - ret = PTR_ERR(err); + ret = _opp_set_regulators(opp_table, dev, + config->regulator_names); + if (ret) goto err; - } data->flags |= OPP_CONFIG_REGULATOR; } diff --git a/include/linux/pm_opp.h b/include/linux/pm_opp.h index a08f9481efb3..f014bd172c99 100644 --- a/include/linux/pm_opp.h +++ b/include/linux/pm_opp.h @@ -189,9 +189,6 @@ void dev_pm_opp_put_supported_hw(struct opp_table *opp_table); int devm_pm_opp_set_supported_hw(struct device *dev, const u32 *versions, unsigned int count); struct opp_table *dev_pm_opp_set_prop_name(struct device *dev, const char *name); void dev_pm_opp_put_prop_name(struct opp_table *opp_table); -struct opp_table *dev_pm_opp_set_regulators(struct device *dev, const char * const names[]); -void dev_pm_opp_put_regulators(struct opp_table *opp_table); -int devm_pm_opp_set_regulators(struct device *dev, const char * const names[]); struct opp_table *dev_pm_opp_set_clkname(struct device *dev, const char *name); void dev_pm_opp_put_clkname(struct opp_table *opp_table); int devm_pm_opp_set_clkname(struct device *dev, const char *name); @@ -409,19 +406,6 @@ static inline struct opp_table *dev_pm_opp_set_prop_name(struct device *dev, con static inline void dev_pm_opp_put_prop_name(struct opp_table *opp_table) {} -static inline struct opp_table *dev_pm_opp_set_regulators(struct device *dev, const char * const names[]) -{ - return ERR_PTR(-EOPNOTSUPP); -} - -static inline void dev_pm_opp_put_regulators(struct opp_table *opp_table) {} - -static inline int devm_pm_opp_set_regulators(struct device *dev, - const char * const names[]) -{ - return -EOPNOTSUPP; -} - static inline struct opp_table *dev_pm_opp_set_clkname(struct device *dev, const char *name) { return ERR_PTR(-EOPNOTSUPP); @@ -606,4 +590,32 @@ static inline int dev_pm_opp_of_find_icc_paths(struct device *dev, struct opp_ta } #endif +/* OPP Configuration helpers */ + +/* Regulators helpers */ +static inline int dev_pm_opp_set_regulators(struct device *dev, + const char * const names[]) +{ + struct dev_pm_opp_config config = { + .regulator_names = names, + }; + + return dev_pm_opp_set_config(dev, &config); +} + +static inline void dev_pm_opp_put_regulators(int token) +{ + dev_pm_opp_clear_config(token); +} + +static inline int devm_pm_opp_set_regulators(struct device *dev, + const char * const names[]) +{ + struct dev_pm_opp_config config = { + .regulator_names = names, + }; + + return devm_pm_opp_set_config(dev, &config); +} + #endif /* __LINUX_OPP_H__ */