public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Bjorn Andersson <bjorn.andersson@linaro.org>
To: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Cc: Andy Gross <agross@kernel.org>,
	Michael Turquette <mturquette@baylibre.com>,
	Stephen Boyd <sboyd@kernel.org>, Rob Herring <robh+dt@kernel.org>,
	Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>,
	Viresh Kumar <vireshk@kernel.org>, Nishanth Menon <nm@ti.com>,
	Alim Akhtar <alim.akhtar@samsung.com>,
	Avri Altman <avri.altman@wdc.com>,
	"James E.J. Bottomley" <jejb@linux.ibm.com>,
	"Martin K. Petersen" <martin.petersen@oracle.com>,
	"Rafael J. Wysocki" <rafael@kernel.org>,
	Taniya Das <tdas@codeaurora.org>,
	linux-arm-msm@vger.kernel.org, linux-clk@vger.kernel.org,
	devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-pm@vger.kernel.org, linux-scsi@vger.kernel.org
Subject: Re: [RFC PATCH v2 4/6] PM: opp: allow control of multiple clocks
Date: Tue, 12 Apr 2022 10:15:33 -0700	[thread overview]
Message-ID: <YlWztZknl4OBmekp@ripper> (raw)
In-Reply-To: <20220411154347.491396-5-krzysztof.kozlowski@linaro.org>

On Mon 11 Apr 08:43 PDT 2022, Krzysztof Kozlowski wrote:

> Devices might need to control several clocks when scaling the frequency
> and voltage.  Example is the Universal Flash Storage (UFS) which scales
> several independent clocks with change of performance levels.
> 
> Add parsing of multiple clocks and clock names and scale all of them,
> when needed.  If only one clock is provided, the code should behave the
> same as before.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
> ---
>  drivers/opp/core.c     | 205 ++++++++++++++++++++++++++++++++---------
>  drivers/opp/of.c       |  48 ++++++++++
>  drivers/opp/opp.h      |   9 +-
>  include/linux/pm_opp.h |  23 +++++
>  4 files changed, 242 insertions(+), 43 deletions(-)
> 
> diff --git a/drivers/opp/core.c b/drivers/opp/core.c
[..]
> @@ -1295,21 +1344,32 @@ static struct opp_table *_update_opp_table_clk(struct device *dev,
>  	 * Return early if we don't need to get clk or we have already tried it
>  	 * earlier.
>  	 */
> -	if (!getclk || IS_ERR(opp_table) || opp_table->clk)
> +	if (!getclk || IS_ERR(opp_table) || opp_table->clks)
>  		return opp_table;
>  
> +	opp_table->clks = kmalloc_array(1, sizeof(*opp_table->clks),
> +					GFP_KERNEL);

This seems to be 81 chars long, perhaps worth not line breaking?

> +	if (!opp_table->clks)
> +		return ERR_PTR(-ENOMEM);
> +
>  	/* Find clk for the device */
> -	opp_table->clk = clk_get(dev, NULL);
> +	opp_table->clks[0] = clk_get(dev, NULL);
>  
> -	ret = PTR_ERR_OR_ZERO(opp_table->clk);
> -	if (!ret)
> +	ret = PTR_ERR_OR_ZERO(opp_table->clks[0]);
> +	if (!ret) {
> +		opp_table->clk_count = 1;
>  		return opp_table;
> +	}
[..]
> +struct opp_table *dev_pm_opp_set_clknames(struct device *dev,
> +					  const char * const names[],
> +					  unsigned int count)
>  {
>  	struct opp_table *opp_table;
> -	int ret;
> +	struct clk *clk;
> +	int ret, i;
>  
>  	opp_table = _add_opp_table(dev, false);
>  	if (IS_ERR(opp_table))
> @@ -2159,70 +2259,92 @@ struct opp_table *dev_pm_opp_set_clkname(struct device *dev, const char *name)
>  	}
>  
>  	/* clk shouldn't be initialized at this point */
> -	if (WARN_ON(opp_table->clk)) {
> +	if (WARN_ON(opp_table->clks)) {
>  		ret = -EBUSY;
>  		goto err;
>  	}
>  
> -	/* Find clk for the device */
> -	opp_table->clk = clk_get(dev, name);
> -	if (IS_ERR(opp_table->clk)) {
> -		ret = dev_err_probe(dev, PTR_ERR(opp_table->clk),
> -				    "%s: Couldn't find clock\n", __func__);
> +	opp_table->clks = kmalloc_array(count, sizeof(*opp_table->clks),
> +					GFP_KERNEL);
> +	if (!opp_table->clks) {
> +		ret = -ENOMEM;
>  		goto err;
>  	}
>  
> +	for (i = 0; i < count; i++) {
> +		clk = clk_get(dev, names[i]);
> +		if (IS_ERR(clk)) {
> +			ret =  dev_err_probe(dev, PTR_ERR(clk),
> +					     "%s: Couldn't find clock %s\n",
> +					     __func__, names[i]);
> +			goto free_clks;
> +		}
> +
> +		opp_table->clks[i] = clk;
> +	}

Wouldn't it be convenient to make clks a struct clk_bulk_data array
and use clk_bulk_get()/clk_bulk_put() instead?

> +
> +	opp_table->clk_count = count;
> +
>  	return opp_table;
>  
> +free_clks:
> +	while (i != 0)
> +		clk_put(opp_table->clks[--i]);
> +
> +	kfree(opp_table->clks);
> +	opp_table->clks = NULL;
> +	opp_table->clk_count = -1;
>  err:
>  	dev_pm_opp_put_opp_table(opp_table);
>  
>  	return ERR_PTR(ret);
>  }
> -EXPORT_SYMBOL_GPL(dev_pm_opp_set_clkname);
> +EXPORT_SYMBOL_GPL(dev_pm_opp_set_clknames);
[..]
> +static int _read_clocks(struct dev_pm_opp *opp, struct opp_table *opp_table,
> +			struct device_node *np)
> +{
> +	int count, ret;
> +	u64 *freq;
> +
> +	count = of_property_count_u64_elems(np, "opp-hz");
> +	if (count < 0) {
> +		pr_err("%s: Invalid %s property (%d)\n",
> +			__func__, of_node_full_name(np), count);

Wouldn't %pOF be convenient to use here, seems like it becomes short
enough that you don't have to wrap this line then.

> +		return count;
> +	}
> +
> +	if (count != opp_table->clk_count) {
> +		pr_err("%s: number of rates %d does not match number of clocks %d in %s\n",
> +		       __func__, count, opp_table->clk_count,
> +		       of_node_full_name(np));
> +		return -EINVAL;
> +	}
> +
> +	freq = kmalloc_array(count, sizeof(*freq), GFP_KERNEL);
> +	if (!freq)
> +		return -ENOMEM;
> +
> +	ret = of_property_read_u64_array(np, "opp-hz", freq, count);
> +	if (ret) {
> +		pr_err("%s: error parsing %s: %d\n", __func__,
> +		       of_node_full_name(np), ret);
> +		ret = -EINVAL;
> +		goto free_freq;
> +	}

Regards,
Bjorn

  reply	other threads:[~2022-04-12 17:13 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-04-11 15:43 [RFC PATCH v2 0/6] ufs: set power domain performance state when scaling gears Krzysztof Kozlowski
2022-04-11 15:43 ` [RFC PATCH v2 1/6] dt-bindings: clock: qcom,gcc-sdm845: add parent power domain Krzysztof Kozlowski
2022-04-12 15:22   ` Bjorn Andersson
2022-04-14 15:20   ` Rob Herring
2022-04-11 15:43 ` [RFC PATCH v2 2/6] dt-bindings: opp: accept array of frequencies Krzysztof Kozlowski
2022-04-12 15:23   ` Bjorn Andersson
2022-04-19 16:48   ` Rob Herring
2022-04-11 15:43 ` [RFC PATCH v2 3/6] dt-bindings: ufs: common: add OPP table Krzysztof Kozlowski
2022-04-14 15:25   ` Rob Herring
2022-04-14 15:29     ` Rob Herring
2022-04-11 15:43 ` [RFC PATCH v2 4/6] PM: opp: allow control of multiple clocks Krzysztof Kozlowski
2022-04-12 17:15   ` Bjorn Andersson [this message]
2022-04-13  9:07     ` Krzysztof Kozlowski
2022-04-20  3:06       ` Bjorn Andersson
2022-04-25  7:27   ` Viresh Kumar
2022-05-09 10:38     ` Krzysztof Kozlowski
2022-05-10  4:40       ` Viresh Kumar
2022-05-10 13:09         ` Krzysztof Kozlowski
2022-05-11  5:06           ` Viresh Kumar
     [not found]             ` <20220518235708.1A04CC385A9@smtp.kernel.org>
2022-05-19  8:03               ` Krzysztof Kozlowski
     [not found]                 ` <20220520005934.8AB1DC385AA@smtp.kernel.org>
2022-05-25  7:05                   ` Viresh Kumar
     [not found]                     ` <20220525160455.67E2BC385B8@smtp.kernel.org>
2022-05-26 10:27                       ` Viresh Kumar
2022-05-31 10:30                 ` Viresh Kumar
2022-06-01 11:23                   ` Krzysztof Kozlowski
2022-06-10  8:22                     ` Viresh Kumar
     [not found]   ` <20220422234402.B66DDC385A4@smtp.kernel.org>
2022-04-25 10:03     ` Krzysztof Kozlowski
2022-04-11 15:43 ` [RFC PATCH v2 5/6] ufs: use PM OPP when scaling gears Krzysztof Kozlowski
2022-04-12 18:15   ` Bjorn Andersson
2022-04-19 17:01   ` Manivannan Sadhasivam
2022-04-20 10:04     ` Krzysztof Kozlowski
2022-04-11 15:43 ` [RFC PATCH v2 6/6] arm64: dts: qcom: sdm845: control RPMHPD performance states with UFS Krzysztof Kozlowski

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=YlWztZknl4OBmekp@ripper \
    --to=bjorn.andersson@linaro.org \
    --cc=agross@kernel.org \
    --cc=alim.akhtar@samsung.com \
    --cc=avri.altman@wdc.com \
    --cc=devicetree@vger.kernel.org \
    --cc=jejb@linux.ibm.com \
    --cc=krzysztof.kozlowski+dt@linaro.org \
    --cc=krzysztof.kozlowski@linaro.org \
    --cc=linux-arm-msm@vger.kernel.org \
    --cc=linux-clk@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pm@vger.kernel.org \
    --cc=linux-scsi@vger.kernel.org \
    --cc=martin.petersen@oracle.com \
    --cc=mturquette@baylibre.com \
    --cc=nm@ti.com \
    --cc=rafael@kernel.org \
    --cc=robh+dt@kernel.org \
    --cc=sboyd@kernel.org \
    --cc=tdas@codeaurora.org \
    --cc=vireshk@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox