5.15-stable review patch. If anyone has any objections, please let me know. ------------------ From: Mårten Lindahl <marten.lindahl@xxxxxxxx> [ Upstream commit 5de3e13f7f6b496bd7bd9ff4d2b915b7d3e67cda ] Some of the pmbus core functions uses pmbus_write_byte_data, which does not support driver callbacks for chip specific write operations. This could potentially influence some specific regulator chips that for example need a time delay before each data access. Lets add support for driver callback with _pmbus_write_byte_data. Signed-off-by: Mårten Lindahl <marten.lindahl@xxxxxxxx> Link: https://lore.kernel.org/r/20220428144039.2464667-2-marten.lindahl@xxxxxxxx Signed-off-by: Guenter Roeck <linux@xxxxxxxxxxxx> Stable-dep-of: 20471071f198 ("hwmon: (pmbus) Conditionally clear individual status bits for pmbus rev >= 1.2") Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx> --- drivers/hwmon/pmbus/pmbus.h | 2 ++ drivers/hwmon/pmbus/pmbus_core.c | 24 +++++++++++++++++++++--- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/drivers/hwmon/pmbus/pmbus.h b/drivers/hwmon/pmbus/pmbus.h index ef3a8ecde4df..e2a570930bd7 100644 --- a/drivers/hwmon/pmbus/pmbus.h +++ b/drivers/hwmon/pmbus/pmbus.h @@ -438,6 +438,8 @@ struct pmbus_driver_info { int (*read_byte_data)(struct i2c_client *client, int page, int reg); int (*read_word_data)(struct i2c_client *client, int page, int phase, int reg); + int (*write_byte_data)(struct i2c_client *client, int page, int reg, + u8 byte); int (*write_word_data)(struct i2c_client *client, int page, int reg, u16 word); int (*write_byte)(struct i2c_client *client, int page, u8 value); diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c index 63b616ce3a6e..cc9ce5b2f0f2 100644 --- a/drivers/hwmon/pmbus/pmbus_core.c +++ b/drivers/hwmon/pmbus/pmbus_core.c @@ -276,6 +276,24 @@ static int _pmbus_write_word_data(struct i2c_client *client, int page, int reg, return pmbus_write_word_data(client, page, reg, word); } +/* + * _pmbus_write_byte_data() is similar to pmbus_write_byte_data(), but checks if + * a device specific mapping function exists and calls it if necessary. + */ +static int _pmbus_write_byte_data(struct i2c_client *client, int page, int reg, u8 value) +{ + struct pmbus_data *data = i2c_get_clientdata(client); + const struct pmbus_driver_info *info = data->info; + int status; + + if (info->write_byte_data) { + status = info->write_byte_data(client, page, reg, value); + if (status != -ENODATA) + return status; + } + return pmbus_write_byte_data(client, page, reg, value); +} + int pmbus_update_fan(struct i2c_client *client, int page, int id, u8 config, u8 mask, u16 command) { @@ -290,7 +308,7 @@ int pmbus_update_fan(struct i2c_client *client, int page, int id, to = (from & ~mask) | (config & mask); if (to != from) { - rv = pmbus_write_byte_data(client, page, + rv = _pmbus_write_byte_data(client, page, pmbus_fan_config_registers[id], to); if (rv < 0) return rv; @@ -397,7 +415,7 @@ int pmbus_update_byte_data(struct i2c_client *client, int page, u8 reg, tmp = (rv & ~mask) | (value & mask); if (tmp != rv) - rv = pmbus_write_byte_data(client, page, reg, tmp); + rv = _pmbus_write_byte_data(client, page, reg, tmp); return rv; } @@ -912,7 +930,7 @@ static int pmbus_get_boolean(struct i2c_client *client, struct pmbus_boolean *b, regval = status & mask; if (regval) { - ret = pmbus_write_byte_data(client, page, reg, regval); + ret = _pmbus_write_byte_data(client, page, reg, regval); if (ret) goto unlock; } -- 2.43.0