mirror of
https://github.com/torvalds/linux.git
synced 2024-11-26 06:02:05 +00:00
hwmon: (pmbus) Introduce and use cached vout margins
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@axis.com> Link: https://lore.kernel.org/r/20220614093856.3470672-2-marten.lindahl@axis.com Signed-off-by: Guenter Roeck <linux@roeck-us.net>
This commit is contained in:
parent
b674bcb13f
commit
07fb76273d
@ -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 {
|
||||
@ -2848,6 +2851,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);
|
||||
@ -2883,24 +2938,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)
|
||||
|
Loading…
Reference in New Issue
Block a user