All of lore.kernel.org
 help / color / mirror / Atom feed
From: Leonard Crestez <leonard.crestez@nxp.com>
To: "kyungmin.park@samsung.com" <kyungmin.park@samsung.com>,
	"rjw@rjwysocki.net" <rjw@rjwysocki.net>,
	"cw00.choi@samsung.com" <cw00.choi@samsung.com>,
	"myungjoo.ham@samsung.com" <myungjoo.ham@samsung.com>
Cc: dl-linux-imx <linux-imx@nxp.com>,
	"mka@chromium.org" <mka@chromium.org>,
	"krzk@kernel.org" <krzk@kernel.org>,
	"linux-pm@vger.kernel.org" <linux-pm@vger.kernel.org>,
	"a.swigon@partner.samsung.com" <a.swigon@partner.samsung.com>,
	Jacky Bai <ping.bai@nxp.com>,
	"viresh.kumar@linaro.org" <viresh.kumar@linaro.org>,
	"saravanak@google.com" <saravanak@google.com>,
	Abel Vesa <abel.vesa@nxp.com>,
	"linux-arm-kernel@lists.infradead.org" 
	<linux-arm-kernel@lists.infradead.org>,
	"georgi.djakov@linaro.org" <georgi.djakov@linaro.org>,
	"abailon@baylibre.com" <abailon@baylibre.com>
Subject: Re: [PATCH v10 09/11] PM / devfreq: Introduce get_freq_range helper
Date: Mon, 11 Nov 2019 14:37:17 +0000	[thread overview]
Message-ID: <914b491c38aa7130cbf0c76203cdb7dd92a42299.camel@nxp.com> (raw)
In-Reply-To: <b6662a88-af9b-6948-a1ea-921a10ca937d@samsung.com>

On Mon, 2019-11-11 at 14:56 +0900, Chanwoo Choi wrote:
> On 11/1/19 6:34 AM, Leonard Crestez wrote:
> > Moving handling of min/max freq to a single function and call it from
> > update_devfreq and for printing min/max freq values in sysfs.
> > 
> > This changes the behavior of out-of-range min_freq/max_freq: clamping
> > is now done at evaluation time. This means that if an out-of-range
> > constraint is imposed by sysfs and it later becomes valid then it will
> > be enforced.
> > 
> > Signed-off-by: Leonard Crestez <leonard.crestez@nxp.com>
> > Reviewed-by: Matthias Kaehlcke <mka@chromium.org>
> > Reviewed-by: Chanwoo Choi <cw00.choi@samsung.com>
> > ---
> >  drivers/devfreq/devfreq.c | 108 +++++++++++++++++++++-----------------
> >  1 file changed, 60 insertions(+), 48 deletions(-)
> > 
> > diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
> > index ab12fd22aa08..ba3b53ee23fd 100644
> > --- a/drivers/devfreq/devfreq.c
> > +++ b/drivers/devfreq/devfreq.c
> > @@ -96,10 +96,51 @@ static unsigned long find_available_max_freq(struct devfreq *devfreq)
> >  		dev_pm_opp_put(opp);
> >  
> >  	return max_freq;
> >  }
> >  
> > +/**
> > + * get_freq_range() - Get the current freq range
> > + * @devfreq:	the devfreq instance
> > + * @min_freq:	the min frequency
> > + * @max_freq:	the max frequency
> > + *
> > + * This takes into consideration all constraints.
> > + */
> > +static void get_freq_range(struct devfreq *devfreq,
> > +			   unsigned long *min_freq,
> > +			   unsigned long *max_freq)
> > +{
> > +	unsigned long *freq_table = devfreq->profile->freq_table;
> > +
> > +	lockdep_assert_held(&devfreq->lock);
> > +
> > +	/*
> > +	 * Initialize minimum/maximum frequency from freq table.
> > +	 * The devfreq drivers can initialize this in either ascending or
> > +	 * descending order and devfreq core supports both.
> > +	 */
> > +	if (freq_table[0] < freq_table[devfreq->profile->max_state - 1]) {
> > +		*min_freq = freq_table[0];
> > +		*max_freq = freq_table[devfreq->profile->max_state - 1];
> > +	} else {
> > +		*min_freq = freq_table[devfreq->profile->max_state - 1];
> > +		*max_freq = freq_table[0];
> > +	}
> > +
> > +	/* Apply constraints from sysfs */
> > +	*min_freq = max(*min_freq, devfreq->min_freq);
> > +	*max_freq = min(*max_freq, devfreq->max_freq);
> > +
> > +	/* Apply constraints from OPP interface */
> > +	*min_freq = max(*min_freq, devfreq->scaling_min_freq);
> > +	*max_freq = min(*max_freq, devfreq->scaling_max_freq);
> > +
> > +	if (*min_freq > *max_freq)
> > +		*min_freq = *max_freq;
> > +}
> > +
> >  /**
> >   * devfreq_get_freq_level() - Lookup freq_table for the frequency
> >   * @devfreq:	the devfreq instance
> >   * @freq:	the target frequency
> >   */
> > @@ -348,20 +389,11 @@ int update_devfreq(struct devfreq *devfreq)
> >  
> >  	/* Reevaluate the proper frequency */
> >  	err = devfreq->governor->get_target_freq(devfreq, &freq);
> >  	if (err)
> >  		return err;
> > -
> > -	/*
> > -	 * Adjust the frequency with user freq, QoS and available freq.
> > -	 *
> > -	 * List from the highest priority
> > -	 * max_freq
> > -	 * min_freq
> > -	 */
> > -	max_freq = min(devfreq->scaling_max_freq, devfreq->max_freq);
> > -	min_freq = max(devfreq->scaling_min_freq, devfreq->min_freq);
> > +	get_freq_range(devfreq, &min_freq, &max_freq);
> >  
> >  	if (freq < min_freq) {
> >  		freq = min_freq;
> >  		flags &= ~DEVFREQ_FLAG_LEAST_UPPER_BOUND; /* Use GLB */
> >  	}
> > @@ -1292,40 +1324,28 @@ static ssize_t min_freq_store(struct device *dev, struct device_attribute *attr,
> >  	ret = sscanf(buf, "%lu", &value);
> >  	if (ret != 1)
> >  		return -EINVAL;
> >  
> >  	mutex_lock(&df->lock);
> > -
> > -	if (value) {
> > -		if (value > df->max_freq) {
> > -			ret = -EINVAL;
> > -			goto unlock;
> > -		}
> > -	} else {
> > -		unsigned long *freq_table = df->profile->freq_table;
> > -
> > -		/* Get minimum frequency according to sorting order */
> > -		if (freq_table[0] < freq_table[df->profile->max_state - 1])
> > -			value = freq_table[0];
> > -		else
> > -			value = freq_table[df->profile->max_state - 1];
> > -	}
> > -
> >  	df->min_freq = value;
> >  	update_devfreq(df);
> > -	ret = count;
> > -unlock:
> >  	mutex_unlock(&df->lock);
> > -	return ret;
> > +
> > +	return count;
> >  }
> >  
> >  static ssize_t min_freq_show(struct device *dev, struct device_attribute *attr,
> >  			     char *buf)
> >  {
> >  	struct devfreq *df = to_devfreq(dev);
> > +	unsigned long min_freq, max_freq;
> >  
> > -	return sprintf(buf, "%lu\n", max(df->scaling_min_freq, df->min_freq));
> > +	mutex_lock(&df->lock);
> > +	get_freq_range(df, &min_freq, &max_freq);
> > +	mutex_unlock(&df->lock);
> > +
> > +	return sprintf(buf, "%lu\n", min_freq);
> >  }
> >  
> >  static ssize_t max_freq_store(struct device *dev, struct device_attribute *attr,
> >  			      const char *buf, size_t count)
> >  {
> > @@ -1337,40 +1357,32 @@ static ssize_t max_freq_store(struct device *dev, struct device_attribute *attr,
> >  	if (ret != 1)
> >  		return -EINVAL;
> >  
> >  	mutex_lock(&df->lock);
> >  
> > -	if (value) {
> > -		if (value < df->min_freq) {
> > -			ret = -EINVAL;
> > -			goto unlock;
> > -		}
> > -	} else {
> > -		unsigned long *freq_table = df->profile->freq_table;
> > -
> > -		/* Get maximum frequency according to sorting order */
> > -		if (freq_table[0] < freq_table[df->profile->max_state - 1])
> > -			value = freq_table[df->profile->max_state - 1];
> > -		else
> > -			value = freq_table[0];
> > -	}
> > +	if (!value)
> > +		value = ULONG_MAX;
> >  
> >  	df->max_freq = value;
> >  	update_devfreq(df);
> > -	ret = count;
> > -unlock:
> >  	mutex_unlock(&df->lock);
> > -	return ret;
> > +
> > +	return count;
> >  }
> >  static DEVICE_ATTR_RW(min_freq);
> >  
> >  static ssize_t max_freq_show(struct device *dev, struct device_attribute *attr,
> >  			     char *buf)
> >  {
> >  	struct devfreq *df = to_devfreq(dev);
> > +	unsigned long min_freq, max_freq;
> > +
> > +	mutex_lock(&df->lock);
> > +	get_freq_range(df, &min_freq, &max_freq);
> > +	mutex_unlock(&df->lock);
> >  
> > -	return sprintf(buf, "%lu\n", min(df->scaling_max_freq, df->max_freq));
> > +	return sprintf(buf, "%lu\n", max_freq);
> >  }
> >  static DEVICE_ATTR_RW(max_freq);
> >  
> >  static ssize_t available_frequencies_show(struct device *d,
> >  					  struct device_attribute *attr,
> > 
> 
> Applied it because it doesn't depend on the pm_qos feature.

Thanks, this will make it easier to move forward.

--
Regards,
Leonard

WARNING: multiple messages have this Message-ID (diff)
From: Leonard Crestez <leonard.crestez@nxp.com>
To: "kyungmin.park@samsung.com" <kyungmin.park@samsung.com>,
	"rjw@rjwysocki.net" <rjw@rjwysocki.net>,
	"cw00.choi@samsung.com" <cw00.choi@samsung.com>,
	"myungjoo.ham@samsung.com" <myungjoo.ham@samsung.com>
Cc: "a.swigon@partner.samsung.com" <a.swigon@partner.samsung.com>,
	Jacky Bai <ping.bai@nxp.com>,
	"saravanak@google.com" <saravanak@google.com>,
	"linux-pm@vger.kernel.org" <linux-pm@vger.kernel.org>,
	"viresh.kumar@linaro.org" <viresh.kumar@linaro.org>,
	"krzk@kernel.org" <krzk@kernel.org>,
	"abailon@baylibre.com" <abailon@baylibre.com>,
	"mka@chromium.org" <mka@chromium.org>,
	dl-linux-imx <linux-imx@nxp.com>,
	"georgi.djakov@linaro.org" <georgi.djakov@linaro.org>,
	"linux-arm-kernel@lists.infradead.org"
	<linux-arm-kernel@lists.infradead.org>,
	Abel Vesa <abel.vesa@nxp.com>
Subject: Re: [PATCH v10 09/11] PM / devfreq: Introduce get_freq_range helper
Date: Mon, 11 Nov 2019 14:37:17 +0000	[thread overview]
Message-ID: <914b491c38aa7130cbf0c76203cdb7dd92a42299.camel@nxp.com> (raw)
In-Reply-To: <b6662a88-af9b-6948-a1ea-921a10ca937d@samsung.com>

On Mon, 2019-11-11 at 14:56 +0900, Chanwoo Choi wrote:
> On 11/1/19 6:34 AM, Leonard Crestez wrote:
> > Moving handling of min/max freq to a single function and call it from
> > update_devfreq and for printing min/max freq values in sysfs.
> > 
> > This changes the behavior of out-of-range min_freq/max_freq: clamping
> > is now done at evaluation time. This means that if an out-of-range
> > constraint is imposed by sysfs and it later becomes valid then it will
> > be enforced.
> > 
> > Signed-off-by: Leonard Crestez <leonard.crestez@nxp.com>
> > Reviewed-by: Matthias Kaehlcke <mka@chromium.org>
> > Reviewed-by: Chanwoo Choi <cw00.choi@samsung.com>
> > ---
> >  drivers/devfreq/devfreq.c | 108 +++++++++++++++++++++-----------------
> >  1 file changed, 60 insertions(+), 48 deletions(-)
> > 
> > diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
> > index ab12fd22aa08..ba3b53ee23fd 100644
> > --- a/drivers/devfreq/devfreq.c
> > +++ b/drivers/devfreq/devfreq.c
> > @@ -96,10 +96,51 @@ static unsigned long find_available_max_freq(struct devfreq *devfreq)
> >  		dev_pm_opp_put(opp);
> >  
> >  	return max_freq;
> >  }
> >  
> > +/**
> > + * get_freq_range() - Get the current freq range
> > + * @devfreq:	the devfreq instance
> > + * @min_freq:	the min frequency
> > + * @max_freq:	the max frequency
> > + *
> > + * This takes into consideration all constraints.
> > + */
> > +static void get_freq_range(struct devfreq *devfreq,
> > +			   unsigned long *min_freq,
> > +			   unsigned long *max_freq)
> > +{
> > +	unsigned long *freq_table = devfreq->profile->freq_table;
> > +
> > +	lockdep_assert_held(&devfreq->lock);
> > +
> > +	/*
> > +	 * Initialize minimum/maximum frequency from freq table.
> > +	 * The devfreq drivers can initialize this in either ascending or
> > +	 * descending order and devfreq core supports both.
> > +	 */
> > +	if (freq_table[0] < freq_table[devfreq->profile->max_state - 1]) {
> > +		*min_freq = freq_table[0];
> > +		*max_freq = freq_table[devfreq->profile->max_state - 1];
> > +	} else {
> > +		*min_freq = freq_table[devfreq->profile->max_state - 1];
> > +		*max_freq = freq_table[0];
> > +	}
> > +
> > +	/* Apply constraints from sysfs */
> > +	*min_freq = max(*min_freq, devfreq->min_freq);
> > +	*max_freq = min(*max_freq, devfreq->max_freq);
> > +
> > +	/* Apply constraints from OPP interface */
> > +	*min_freq = max(*min_freq, devfreq->scaling_min_freq);
> > +	*max_freq = min(*max_freq, devfreq->scaling_max_freq);
> > +
> > +	if (*min_freq > *max_freq)
> > +		*min_freq = *max_freq;
> > +}
> > +
> >  /**
> >   * devfreq_get_freq_level() - Lookup freq_table for the frequency
> >   * @devfreq:	the devfreq instance
> >   * @freq:	the target frequency
> >   */
> > @@ -348,20 +389,11 @@ int update_devfreq(struct devfreq *devfreq)
> >  
> >  	/* Reevaluate the proper frequency */
> >  	err = devfreq->governor->get_target_freq(devfreq, &freq);
> >  	if (err)
> >  		return err;
> > -
> > -	/*
> > -	 * Adjust the frequency with user freq, QoS and available freq.
> > -	 *
> > -	 * List from the highest priority
> > -	 * max_freq
> > -	 * min_freq
> > -	 */
> > -	max_freq = min(devfreq->scaling_max_freq, devfreq->max_freq);
> > -	min_freq = max(devfreq->scaling_min_freq, devfreq->min_freq);
> > +	get_freq_range(devfreq, &min_freq, &max_freq);
> >  
> >  	if (freq < min_freq) {
> >  		freq = min_freq;
> >  		flags &= ~DEVFREQ_FLAG_LEAST_UPPER_BOUND; /* Use GLB */
> >  	}
> > @@ -1292,40 +1324,28 @@ static ssize_t min_freq_store(struct device *dev, struct device_attribute *attr,
> >  	ret = sscanf(buf, "%lu", &value);
> >  	if (ret != 1)
> >  		return -EINVAL;
> >  
> >  	mutex_lock(&df->lock);
> > -
> > -	if (value) {
> > -		if (value > df->max_freq) {
> > -			ret = -EINVAL;
> > -			goto unlock;
> > -		}
> > -	} else {
> > -		unsigned long *freq_table = df->profile->freq_table;
> > -
> > -		/* Get minimum frequency according to sorting order */
> > -		if (freq_table[0] < freq_table[df->profile->max_state - 1])
> > -			value = freq_table[0];
> > -		else
> > -			value = freq_table[df->profile->max_state - 1];
> > -	}
> > -
> >  	df->min_freq = value;
> >  	update_devfreq(df);
> > -	ret = count;
> > -unlock:
> >  	mutex_unlock(&df->lock);
> > -	return ret;
> > +
> > +	return count;
> >  }
> >  
> >  static ssize_t min_freq_show(struct device *dev, struct device_attribute *attr,
> >  			     char *buf)
> >  {
> >  	struct devfreq *df = to_devfreq(dev);
> > +	unsigned long min_freq, max_freq;
> >  
> > -	return sprintf(buf, "%lu\n", max(df->scaling_min_freq, df->min_freq));
> > +	mutex_lock(&df->lock);
> > +	get_freq_range(df, &min_freq, &max_freq);
> > +	mutex_unlock(&df->lock);
> > +
> > +	return sprintf(buf, "%lu\n", min_freq);
> >  }
> >  
> >  static ssize_t max_freq_store(struct device *dev, struct device_attribute *attr,
> >  			      const char *buf, size_t count)
> >  {
> > @@ -1337,40 +1357,32 @@ static ssize_t max_freq_store(struct device *dev, struct device_attribute *attr,
> >  	if (ret != 1)
> >  		return -EINVAL;
> >  
> >  	mutex_lock(&df->lock);
> >  
> > -	if (value) {
> > -		if (value < df->min_freq) {
> > -			ret = -EINVAL;
> > -			goto unlock;
> > -		}
> > -	} else {
> > -		unsigned long *freq_table = df->profile->freq_table;
> > -
> > -		/* Get maximum frequency according to sorting order */
> > -		if (freq_table[0] < freq_table[df->profile->max_state - 1])
> > -			value = freq_table[df->profile->max_state - 1];
> > -		else
> > -			value = freq_table[0];
> > -	}
> > +	if (!value)
> > +		value = ULONG_MAX;
> >  
> >  	df->max_freq = value;
> >  	update_devfreq(df);
> > -	ret = count;
> > -unlock:
> >  	mutex_unlock(&df->lock);
> > -	return ret;
> > +
> > +	return count;
> >  }
> >  static DEVICE_ATTR_RW(min_freq);
> >  
> >  static ssize_t max_freq_show(struct device *dev, struct device_attribute *attr,
> >  			     char *buf)
> >  {
> >  	struct devfreq *df = to_devfreq(dev);
> > +	unsigned long min_freq, max_freq;
> > +
> > +	mutex_lock(&df->lock);
> > +	get_freq_range(df, &min_freq, &max_freq);
> > +	mutex_unlock(&df->lock);
> >  
> > -	return sprintf(buf, "%lu\n", min(df->scaling_max_freq, df->max_freq));
> > +	return sprintf(buf, "%lu\n", max_freq);
> >  }
> >  static DEVICE_ATTR_RW(max_freq);
> >  
> >  static ssize_t available_frequencies_show(struct device *d,
> >  					  struct device_attribute *attr,
> > 
> 
> Applied it because it doesn't depend on the pm_qos feature.

Thanks, this will make it easier to move forward.

--
Regards,
Leonard
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  reply	other threads:[~2019-11-11 14:37 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-10-31 21:34 [PATCH v10] PM / devfreq: Add dev_pm_qos support Leonard Crestez
2019-10-31 21:34 ` Leonard Crestez
2019-10-31 21:34 ` [PATCH v10 01/11] PM / devfreq: Fix devfreq_notifier_call returning errno Leonard Crestez
2019-10-31 21:34   ` Leonard Crestez
2019-11-11  5:55   ` Chanwoo Choi
2019-11-11  5:55     ` Chanwoo Choi
2019-10-31 21:34 ` [PATCH v10 02/11] PM / devfreq: Set scaling_max_freq to max on OPP notifier error Leonard Crestez
2019-10-31 21:34   ` Leonard Crestez
2019-11-11  5:55   ` Chanwoo Choi
2019-11-11  5:55     ` Chanwoo Choi
2019-10-31 21:34 ` [PATCH v10 03/11] PM / devfreq: Split device_register usage Leonard Crestez
2019-10-31 21:34   ` Leonard Crestez
2019-10-31 21:34 ` [PATCH v10 04/11] PM / devfreq: Move more initialization before registration Leonard Crestez
2019-10-31 21:34   ` Leonard Crestez
2019-10-31 21:34 ` [PATCH v10 05/11] PM / devfreq: Don't take lock in devfreq_add_device Leonard Crestez
2019-10-31 21:34   ` Leonard Crestez
2019-10-31 21:34 ` [PATCH v10 06/11] PM / QoS: Reorder pm_qos/freq_qos/dev_pm_qos structs Leonard Crestez
2019-10-31 21:34   ` Leonard Crestez
2019-11-01  2:13   ` Chanwoo Choi
2019-11-01  2:13     ` Chanwoo Choi
2019-11-01 14:45     ` Leonard Crestez
2019-11-01 14:45       ` Leonard Crestez
2019-11-11  5:52       ` Chanwoo Choi
2019-11-11  5:52         ` Chanwoo Choi
2019-10-31 21:34 ` [PATCH v10 07/11] PM / QoS: Export _freq_qos_apply Leonard Crestez
2019-10-31 21:34   ` Leonard Crestez
2019-10-31 21:34 ` [PATCH v10 08/11] PM / QoS: Restore DEV_PM_QOS_MIN/MAX_FREQUENCY Leonard Crestez
2019-10-31 21:34   ` Leonard Crestez
2019-10-31 21:34 ` [PATCH v10 09/11] PM / devfreq: Introduce get_freq_range helper Leonard Crestez
2019-10-31 21:34   ` Leonard Crestez
2019-11-11  5:56   ` Chanwoo Choi
2019-11-11  5:56     ` Chanwoo Choi
2019-11-11 14:37     ` Leonard Crestez [this message]
2019-11-11 14:37       ` Leonard Crestez
2019-10-31 21:34 ` [PATCH v10 10/11] PM / devfreq: Add PM QoS support Leonard Crestez
2019-10-31 21:34   ` Leonard Crestez
2019-10-31 21:34 ` [PATCH v10 11/11] PM / devfreq: Use PM QoS for sysfs min/max_freq Leonard Crestez
2019-10-31 21:34   ` Leonard Crestez

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=914b491c38aa7130cbf0c76203cdb7dd92a42299.camel@nxp.com \
    --to=leonard.crestez@nxp.com \
    --cc=a.swigon@partner.samsung.com \
    --cc=abailon@baylibre.com \
    --cc=abel.vesa@nxp.com \
    --cc=cw00.choi@samsung.com \
    --cc=georgi.djakov@linaro.org \
    --cc=krzk@kernel.org \
    --cc=kyungmin.park@samsung.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-imx@nxp.com \
    --cc=linux-pm@vger.kernel.org \
    --cc=mka@chromium.org \
    --cc=myungjoo.ham@samsung.com \
    --cc=ping.bai@nxp.com \
    --cc=rjw@rjwysocki.net \
    --cc=saravanak@google.com \
    --cc=viresh.kumar@linaro.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.