Re: [PATCH v3 1/3] hwmon: (pmbus) Introduce and use cached vout margins

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Jun 14, 2022 at 11:38:54AM +0200, Mårten Lindahl wrote:
> When setting a new voltage the voltage boundaries are read every time to
> check that the new voltage is within the proper range. Checking these
> voltage boundaries consists of reading one of PMBUS_MFR_VOUT_MIN/
> PMBUS_VOUT_MARGIN_LOW registers and then PMBUS_MFR_VOUT_MAX/
> PMBUS_VOUT_MARGIN_HIGH together with writing the PMBUS_CLEAR_FAULTS
> register.
> 
> Since these boundaries are never being changed, it can be cached and
> thus saving unnecessary smbus transmissions.
> 
> Signed-off-by: Mårten Lindahl <marten.lindahl@xxxxxxxx>

Applied to hwmon-next.

Thanks,
Guenter

> ---
>  drivers/hwmon/pmbus/pmbus_core.c | 78 +++++++++++++++++++++++++-------
>  1 file changed, 61 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c
> index 02912022853d..5e0d16512fa6 100644
> --- a/drivers/hwmon/pmbus/pmbus_core.c
> +++ b/drivers/hwmon/pmbus/pmbus_core.c
> @@ -104,6 +104,9 @@ struct pmbus_data {
>  
>  	s16 currpage;	/* current page, -1 for unknown/unset */
>  	s16 currphase;	/* current phase, 0xff for all, -1 for unknown/unset */
> +
> +	int vout_low[PMBUS_PAGES];	/* voltage low margin */
> +	int vout_high[PMBUS_PAGES];	/* voltage high margin */
>  };
>  
>  struct pmbus_debugfs_entry {
> @@ -2636,6 +2639,58 @@ static int pmbus_regulator_get_error_flags(struct regulator_dev *rdev, unsigned
>  	return 0;
>  }
>  
> +static int pmbus_regulator_get_low_margin(struct i2c_client *client, int page)
> +{
> +	struct pmbus_data *data = i2c_get_clientdata(client);
> +	struct pmbus_sensor s = {
> +		.page = page,
> +		.class = PSC_VOLTAGE_OUT,
> +		.convert = true,
> +		.data = -1,
> +	};
> +
> +	if (!data->vout_low[page]) {
> +		if (pmbus_check_word_register(client, page, PMBUS_MFR_VOUT_MIN))
> +			s.data = _pmbus_read_word_data(client, page, 0xff,
> +						       PMBUS_MFR_VOUT_MIN);
> +		if (s.data < 0) {
> +			s.data = _pmbus_read_word_data(client, page, 0xff,
> +						       PMBUS_VOUT_MARGIN_LOW);
> +			if (s.data < 0)
> +				return s.data;
> +		}
> +		data->vout_low[page] = pmbus_reg2data(data, &s);
> +	}
> +
> +	return data->vout_low[page];
> +}
> +
> +static int pmbus_regulator_get_high_margin(struct i2c_client *client, int page)
> +{
> +	struct pmbus_data *data = i2c_get_clientdata(client);
> +	struct pmbus_sensor s = {
> +		.page = page,
> +		.class = PSC_VOLTAGE_OUT,
> +		.convert = true,
> +		.data = -1,
> +	};
> +
> +	if (!data->vout_high[page]) {
> +		if (pmbus_check_word_register(client, page, PMBUS_MFR_VOUT_MAX))
> +			s.data = _pmbus_read_word_data(client, page, 0xff,
> +						       PMBUS_MFR_VOUT_MAX);
> +		if (s.data < 0) {
> +			s.data = _pmbus_read_word_data(client, page, 0xff,
> +						       PMBUS_VOUT_MARGIN_HIGH);
> +			if (s.data < 0)
> +				return s.data;
> +		}
> +		data->vout_high[page] = pmbus_reg2data(data, &s);
> +	}
> +
> +	return data->vout_high[page];
> +}
> +
>  static int pmbus_regulator_get_voltage(struct regulator_dev *rdev)
>  {
>  	struct device *dev = rdev_get_dev(rdev);
> @@ -2671,24 +2726,13 @@ static int pmbus_regulator_set_voltage(struct regulator_dev *rdev, int min_uv,
>  
>  	*selector = 0;
>  
> -	if (pmbus_check_word_register(client, s.page, PMBUS_MFR_VOUT_MIN))
> -		s.data = _pmbus_read_word_data(client, s.page, 0xff, PMBUS_MFR_VOUT_MIN);
> -	if (s.data < 0) {
> -		s.data = _pmbus_read_word_data(client, s.page, 0xff, PMBUS_VOUT_MARGIN_LOW);
> -		if (s.data < 0)
> -			return s.data;
> -	}
> -	low = pmbus_reg2data(data, &s);
> +	low = pmbus_regulator_get_low_margin(client, s.page);
> +	if (low < 0)
> +		return low;
>  
> -	s.data = -1;
> -	if (pmbus_check_word_register(client, s.page, PMBUS_MFR_VOUT_MAX))
> -		s.data = _pmbus_read_word_data(client, s.page, 0xff, PMBUS_MFR_VOUT_MAX);
> -	if (s.data < 0) {
> -		s.data = _pmbus_read_word_data(client, s.page, 0xff, PMBUS_VOUT_MARGIN_HIGH);
> -		if (s.data < 0)
> -			return s.data;
> -	}
> -	high = pmbus_reg2data(data, &s);
> +	high = pmbus_regulator_get_high_margin(client, s.page);
> +	if (high < 0)
> +		return high;
>  
>  	/* Make sure we are within margins */
>  	if (low > val)



[Index of Archives]     [LM Sensors]     [Linux Sound]     [ALSA Users]     [ALSA Devel]     [Linux Audio Users]     [Linux Media]     [Kernel]     [Gimp]     [Yosemite News]     [Linux Media]

  Powered by Linux