Received: by 2002:ad5:4acb:0:0:0:0:0 with SMTP id n11csp197203imw; Mon, 4 Jul 2022 07:37:46 -0700 (PDT) X-Google-Smtp-Source: AGRyM1vkMuyVY9OoaFAnJrjVDW0DXop6a8RieP5EqMYiA5HA51a5WbqYHh+fbXYzs3t+8OBRWZ6t X-Received: by 2002:a17:902:ce10:b0:16b:d4a7:2097 with SMTP id k16-20020a170902ce1000b0016bd4a72097mr5977475plg.116.1656945466565; Mon, 04 Jul 2022 07:37:46 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1656945466; cv=none; d=google.com; s=arc-20160816; b=zFpEtdbN+HcjorcZC777ZPi/q84ZVPaZy/FzI8wISbwDIioHLFJ9xBwm1Pbo4f08Rg 7F5iDIcatZuT13dxeT568f6BZ6A/GxJdHfVUTKMGVJRPO/nDC36l8nMOeJR1ETABtGik gUJ/asAVfWA/WZ5wZLoXzsl8TKWJQWPViCirlhyI6w0RO5XDOkemfTHeTVaJgFAqw4g4 F+If30VG4Qio7C1E0orWQsp3xOYcGSm9pTQLWuQip4AT+F+Nyn4F22jDeGBOn4xPe9tG zsOSAobRHZtxU0HVP3NT8bWvozcBz2uyY72prrg/Aa60L7pVWcT2maTh/e/C4cv006wn fwyA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:in-reply-to:from :references:cc:to:content-language:subject:user-agent:mime-version :date:message-id; bh=7FMJOv1GKRizwdfcKrp1QtfQo8LMR4TVh7xZui7Xx+w=; b=iiC3Ep78gYp/iHnT0lcuNVaH3NEEJ1O2qBNSxdfJmcw7Qg0a2vZW2Jb86hyhjPquoJ txyaJh9Yb8mUNL8ENDNwKUu5nCbgBbJ71iQ5BAapJtwVwQXmQ+7X2SKOe2gegU12guJZ fHyIeHhwa1cXArwFaP4Qal4hdz4H8wM3fyHb1i4VnHgYIR57rLZY/quxCAZ/qAUAEOtG Ay8MA5Ze5QPrsypUURKUUqh4K+PDsDY0hug43Ps14emRfNBBl33qLxC8j7jgQz2dD5x0 tP4jfrwaprLRzo7dgwvl4C2l/TiRMdolZYuvIdWtil94HNmC7rn/zOC05eW21mAT6hFW VOEw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=arm.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id s19-20020a056a00195300b00525425b20f0si15022137pfk.257.2022.07.04.07.37.34; Mon, 04 Jul 2022 07:37:46 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=arm.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234546AbiGDOfO (ORCPT + 99 others); Mon, 4 Jul 2022 10:35:14 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35212 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232123AbiGDOfM (ORCPT ); Mon, 4 Jul 2022 10:35:12 -0400 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 081F41136; Mon, 4 Jul 2022 07:35:10 -0700 (PDT) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id DBF9423A; Mon, 4 Jul 2022 07:35:10 -0700 (PDT) Received: from [10.57.41.70] (unknown [10.57.41.70]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 419853F66F; Mon, 4 Jul 2022 07:35:07 -0700 (PDT) Message-ID: <48d865e8-6c0d-99c0-a43b-89793d5c3f85@arm.com> Date: Mon, 4 Jul 2022 15:35:05 +0100 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.9.1 Subject: Re: [PATCH V3 02/20] OPP: Make dev_pm_opp_set_regulators() accept NULL terminated list Content-Language: en-GB To: Viresh Kumar , "Rafael J. Wysocki" , Chanwoo Choi , MyungJoo Ham , Kyungmin Park , Krzysztof Kozlowski , Alim Akhtar , Qiang Yu , Rob Herring , Tomeu Vizoso , 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 References: <9730e011004b7526e79c6f409f5147fb235b414a.1656935522.git.viresh.kumar@linaro.org> From: Steven Price In-Reply-To: <9730e011004b7526e79c6f409f5147fb235b414a.1656935522.git.viresh.kumar@linaro.org> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00,NICE_REPLY_A, RCVD_IN_DNSWL_HI,SPF_HELO_NONE,SPF_NONE,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 04/07/2022 13:07, Viresh Kumar wrote: > 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 > --- > 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/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) { I have to say the 'new improved' list ending with NULL approach doesn't work out so well for Panfrost. We already have to have a separate 'num_supplies' variable for devm_regulator_bulk_get() / regulator_bulk_{en,dis}able(), so the keeping everything in sync argument is lost here. I would suggest added the NULL on the end of the lists in panfrost_drv.c but then it would break the use of ARRAY_SIZE() to automagically keep the length correct... For now the approach isn't too bad because Panfrost doesn't yet support enabling devfreq with more than one supply. But that array isn't going to work so nicely when that restriction is removed. The only sane way I can see of handling this in Panfrost would be replicating the loop to count the supplies in the Panfrost code which would allow dropping num_supplies from struct panfrost_compatible and then supply_names in the same struct could be NULL terminated ready for devm_pm_opp_set_regulators(). Steve > 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; > }