Skip to content

Commit d1baf7a

Browse files
awujekgroeck
authored andcommitted
hwmon: (pmbus) Check PEC support before reading other registers
Make sure that the support of PEC is determined before the read of other registers. Otherwise the validation of PEC can trigger an error on the read of STATUS_BYTE or STATUS_WORD registers. The problematic scenario is the following. A device with enabled PEC support is up and running and a kernel driver is loaded. Then the driver is unloaded (or device unbound), the HW device is reconfigured externally (e.g. by i2cset) to advertise itself as not supporting PEC. Without the move of the code, at the second load of the driver (or bind) the STATUS_BYTE or STATUS_WORD register is always read with PEC enabled, which is likely to cause a read error resulting with fail of a driver load (or bind). Signed-off-by: Adam Wujek <dev_public@wujek.eu> Link: https://lore.kernel.org/r/20220519233334.438621-1-dev_public@wujek.eu Fixes: 75d2b2b ("hwmon: (pmbus) disable PEC if not enabled") Fixes: 4e5418f ("hwmon: (pmbus_core) Check adapter PEC support") [groeck: Added Fixes: tags, dropped continuation line] Signed-off-by: Guenter Roeck <linux@roeck-us.net>
1 parent 9baabde commit d1baf7a

1 file changed

Lines changed: 15 additions & 13 deletions

File tree

drivers/hwmon/pmbus/pmbus_core.c

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2394,6 +2394,21 @@ static int pmbus_init_common(struct i2c_client *client, struct pmbus_data *data,
23942394
struct device *dev = &client->dev;
23952395
int page, ret;
23962396

2397+
/*
2398+
* Figure out if PEC is enabled before accessing any other register.
2399+
* Make sure PEC is disabled, will be enabled later if needed.
2400+
*/
2401+
client->flags &= ~I2C_CLIENT_PEC;
2402+
2403+
/* Enable PEC if the controller and bus supports it */
2404+
if (!(data->flags & PMBUS_NO_CAPABILITY)) {
2405+
ret = i2c_smbus_read_byte_data(client, PMBUS_CAPABILITY);
2406+
if (ret >= 0 && (ret & PB_CAPABILITY_ERROR_CHECK)) {
2407+
if (i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_PEC))
2408+
client->flags |= I2C_CLIENT_PEC;
2409+
}
2410+
}
2411+
23972412
/*
23982413
* Some PMBus chips don't support PMBUS_STATUS_WORD, so try
23992414
* to use PMBUS_STATUS_BYTE instead if that is the case.
@@ -2412,19 +2427,6 @@ static int pmbus_init_common(struct i2c_client *client, struct pmbus_data *data,
24122427
data->has_status_word = true;
24132428
}
24142429

2415-
/* Make sure PEC is disabled, will be enabled later if needed */
2416-
client->flags &= ~I2C_CLIENT_PEC;
2417-
2418-
/* Enable PEC if the controller and bus supports it */
2419-
if (!(data->flags & PMBUS_NO_CAPABILITY)) {
2420-
ret = i2c_smbus_read_byte_data(client, PMBUS_CAPABILITY);
2421-
if (ret >= 0 && (ret & PB_CAPABILITY_ERROR_CHECK)) {
2422-
if (i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_PEC)) {
2423-
client->flags |= I2C_CLIENT_PEC;
2424-
}
2425-
}
2426-
}
2427-
24282430
/*
24292431
* Check if the chip is write protected. If it is, we can not clear
24302432
* faults, and we should not try it. Also, in that case, writes into

0 commit comments

Comments
 (0)