Message ID | 20200727161928.14122-3-alexandru.tachici@analog.com (mailing list archive) |
---|---|
State | Changes Requested |
Headers | show |
Series | hwmon: pmbus: adm1266: add support | expand |
Hi, url: https://github.com/0day-ci/linux/commits/alexandru-tachici-analog-com/hwmon-pmbus-adm1266-add-support/20200728-002155 base: https://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git hwmon-next config: x86_64-randconfig-m001-20200731 (attached as .config) compiler: gcc-9 (Debian 9.3.0-14) 9.3.0 If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot <lkp@intel.com> Reported-by: Dan Carpenter <dan.carpenter@oracle.com> smatch warnings: drivers/hwmon/pmbus/adm1266.c:88 adm1266_pmbus_block_xfer() warn: inconsistent returns 'data->buf_mutex'. # https://github.com/0day-ci/linux/commit/878684621a66ce0c9e2bdd10f9232b07e48ede96 git remote add linux-review https://github.com/0day-ci/linux git remote update linux-review git checkout 878684621a66ce0c9e2bdd10f9232b07e48ede96 vim +88 drivers/hwmon/pmbus/adm1266.c 878684621a66ce0 Alexandru Tachici 2020-07-27 35 static int adm1266_pmbus_block_xfer(struct adm1266_data *data, u8 cmd, u8 w_len, u8 *data_w, 878684621a66ce0 Alexandru Tachici 2020-07-27 36 u8 *data_r) 878684621a66ce0 Alexandru Tachici 2020-07-27 37 { 878684621a66ce0 Alexandru Tachici 2020-07-27 38 struct i2c_client *client = data->client; 878684621a66ce0 Alexandru Tachici 2020-07-27 39 struct i2c_msg msgs[2] = { 878684621a66ce0 Alexandru Tachici 2020-07-27 40 { 878684621a66ce0 Alexandru Tachici 2020-07-27 41 .addr = client->addr, 878684621a66ce0 Alexandru Tachici 2020-07-27 42 .flags = I2C_M_DMA_SAFE, 878684621a66ce0 Alexandru Tachici 2020-07-27 43 .buf = data->write_buf, 878684621a66ce0 Alexandru Tachici 2020-07-27 44 .len = w_len + 2, 878684621a66ce0 Alexandru Tachici 2020-07-27 45 }, 878684621a66ce0 Alexandru Tachici 2020-07-27 46 { 878684621a66ce0 Alexandru Tachici 2020-07-27 47 .addr = client->addr, 878684621a66ce0 Alexandru Tachici 2020-07-27 48 .flags = I2C_M_RD | I2C_M_DMA_SAFE, 878684621a66ce0 Alexandru Tachici 2020-07-27 49 .buf = data->read_buf, 878684621a66ce0 Alexandru Tachici 2020-07-27 50 .len = ADM1266_PMBUS_BLOCK_MAX + 2, 878684621a66ce0 Alexandru Tachici 2020-07-27 51 } ac5fec412db3640 Alexandru Tachici 2020-07-27 52 }; 878684621a66ce0 Alexandru Tachici 2020-07-27 53 u8 addr; 878684621a66ce0 Alexandru Tachici 2020-07-27 54 u8 crc; 878684621a66ce0 Alexandru Tachici 2020-07-27 55 int ret; 878684621a66ce0 Alexandru Tachici 2020-07-27 56 878684621a66ce0 Alexandru Tachici 2020-07-27 57 mutex_lock(&data->buf_mutex); 878684621a66ce0 Alexandru Tachici 2020-07-27 58 878684621a66ce0 Alexandru Tachici 2020-07-27 59 msgs[0].buf[0] = cmd; 878684621a66ce0 Alexandru Tachici 2020-07-27 60 msgs[0].buf[1] = w_len; 878684621a66ce0 Alexandru Tachici 2020-07-27 61 memcpy(&msgs[0].buf[2], data_w, w_len); 878684621a66ce0 Alexandru Tachici 2020-07-27 62 878684621a66ce0 Alexandru Tachici 2020-07-27 63 ret = i2c_transfer(client->adapter, msgs, 2); 878684621a66ce0 Alexandru Tachici 2020-07-27 64 if (ret != 2) { 878684621a66ce0 Alexandru Tachici 2020-07-27 65 if (ret >= 0) 878684621a66ce0 Alexandru Tachici 2020-07-27 66 ret = -EPROTO; 878684621a66ce0 Alexandru Tachici 2020-07-27 67 return ret; Unlock 878684621a66ce0 Alexandru Tachici 2020-07-27 68 } 878684621a66ce0 Alexandru Tachici 2020-07-27 69 878684621a66ce0 Alexandru Tachici 2020-07-27 70 if (client->flags & I2C_CLIENT_PEC) { 878684621a66ce0 Alexandru Tachici 2020-07-27 71 addr = i2c_8bit_addr_from_msg(&msgs[0]); 878684621a66ce0 Alexandru Tachici 2020-07-27 72 crc = crc8(pmbus_crc_table, &addr, 1, 0); 878684621a66ce0 Alexandru Tachici 2020-07-27 73 crc = crc8(pmbus_crc_table, msgs[0].buf, msgs[0].len, crc); 878684621a66ce0 Alexandru Tachici 2020-07-27 74 878684621a66ce0 Alexandru Tachici 2020-07-27 75 addr = i2c_8bit_addr_from_msg(&msgs[1]); 878684621a66ce0 Alexandru Tachici 2020-07-27 76 crc = crc8(pmbus_crc_table, &addr, 1, crc); 878684621a66ce0 Alexandru Tachici 2020-07-27 77 crc = crc8(pmbus_crc_table, msgs[1].buf, msgs[1].buf[0] + 1, crc); 878684621a66ce0 Alexandru Tachici 2020-07-27 78 878684621a66ce0 Alexandru Tachici 2020-07-27 79 if (crc != msgs[1].buf[msgs[1].buf[0] + 1]) 878684621a66ce0 Alexandru Tachici 2020-07-27 80 return -EBADMSG; And unlock here. 878684621a66ce0 Alexandru Tachici 2020-07-27 81 } 878684621a66ce0 Alexandru Tachici 2020-07-27 82 878684621a66ce0 Alexandru Tachici 2020-07-27 83 memcpy(data_r, &msgs[1].buf[1], msgs[1].buf[0]); 878684621a66ce0 Alexandru Tachici 2020-07-27 84 878684621a66ce0 Alexandru Tachici 2020-07-27 85 ret = msgs[1].buf[0]; 878684621a66ce0 Alexandru Tachici 2020-07-27 86 mutex_unlock(&data->buf_mutex); 878684621a66ce0 Alexandru Tachici 2020-07-27 87 878684621a66ce0 Alexandru Tachici 2020-07-27 @88 return ret; 878684621a66ce0 Alexandru Tachici 2020-07-27 89 } --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
diff --git a/drivers/hwmon/pmbus/Kconfig b/drivers/hwmon/pmbus/Kconfig index da34083e1ffd..c04068b665e6 100644 --- a/drivers/hwmon/pmbus/Kconfig +++ b/drivers/hwmon/pmbus/Kconfig @@ -28,6 +28,7 @@ config SENSORS_PMBUS config SENSORS_ADM1266 tristate "Analog Devices ADM1266 Sequencer" + select CRC8 help If you say yes here you get hardware monitoring support for Analog Devices ADM1266 Cascadable Super Sequencer. diff --git a/drivers/hwmon/pmbus/adm1266.c b/drivers/hwmon/pmbus/adm1266.c index 79e8d90886b8..63975eba34ad 100644 --- a/drivers/hwmon/pmbus/adm1266.c +++ b/drivers/hwmon/pmbus/adm1266.c @@ -6,6 +6,7 @@ * Copyright 2020 Analog Devices Inc. */ +#include <linux/crc8.h> #include <linux/i2c.h> #include <linux/init.h> #include <linux/kernel.h> @@ -13,11 +14,80 @@ #include "pmbus.h" #include <linux/slab.h> +#define ADM1266_PMBUS_BLOCK_MAX 255 + struct adm1266_data { struct pmbus_driver_info info; struct i2c_client *client; + struct mutex buf_mutex; + u8 write_buf[ADM1266_PMBUS_BLOCK_MAX + 1] ____cacheline_aligned; + u8 read_buf[ADM1266_PMBUS_BLOCK_MAX + 1] ____cacheline_aligned; }; +DECLARE_CRC8_TABLE(pmbus_crc_table); + +/* + * Different from Block Read as it sends data and waits for the slave to + * return a value dependent on that data. The protocol is simply a Write Block + * followed by a Read Block without the Read-Block command field and the + * Write-Block STOP bit. + */ +static int adm1266_pmbus_block_xfer(struct adm1266_data *data, u8 cmd, u8 w_len, u8 *data_w, + u8 *data_r) +{ + struct i2c_client *client = data->client; + struct i2c_msg msgs[2] = { + { + .addr = client->addr, + .flags = I2C_M_DMA_SAFE, + .buf = data->write_buf, + .len = w_len + 2, + }, + { + .addr = client->addr, + .flags = I2C_M_RD | I2C_M_DMA_SAFE, + .buf = data->read_buf, + .len = ADM1266_PMBUS_BLOCK_MAX + 2, + } + }; + u8 addr; + u8 crc; + int ret; + + mutex_lock(&data->buf_mutex); + + msgs[0].buf[0] = cmd; + msgs[0].buf[1] = w_len; + memcpy(&msgs[0].buf[2], data_w, w_len); + + ret = i2c_transfer(client->adapter, msgs, 2); + if (ret != 2) { + if (ret >= 0) + ret = -EPROTO; + return ret; + } + + if (client->flags & I2C_CLIENT_PEC) { + addr = i2c_8bit_addr_from_msg(&msgs[0]); + crc = crc8(pmbus_crc_table, &addr, 1, 0); + crc = crc8(pmbus_crc_table, msgs[0].buf, msgs[0].len, crc); + + addr = i2c_8bit_addr_from_msg(&msgs[1]); + crc = crc8(pmbus_crc_table, &addr, 1, crc); + crc = crc8(pmbus_crc_table, msgs[1].buf, msgs[1].buf[0] + 1, crc); + + if (crc != msgs[1].buf[msgs[1].buf[0] + 1]) + return -EBADMSG; + } + + memcpy(data_r, &msgs[1].buf[1], msgs[1].buf[0]); + + ret = msgs[1].buf[0]; + mutex_unlock(&data->buf_mutex); + + return ret; +} + static int adm1266_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct adm1266_data *data; @@ -33,6 +103,9 @@ static int adm1266_probe(struct i2c_client *client, const struct i2c_device_id * for (i = 0; i < data->info.pages; i++) data->info.func[i] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT; + crc8_populate_msb(pmbus_crc_table, 0x7); + mutex_init(&data->buf_mutex); + return pmbus_do_probe(client, id, &data->info); }