Message ID | 20200624151736.95785-3-alexandru.tachici@analog.com (mailing list archive) |
---|---|
State | Changes Requested |
Headers | show |
Series | hwmon: pmbus: adm1266: add support | expand |
Hi, I love your patch! Perhaps something to improve: [auto build test WARNING on hwmon/hwmon-next] [also build test WARNING on linux/master robh/for-next linus/master v5.8-rc2 next-20200624] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use as documented in https://git-scm.com/docs/git-format-patch] url: https://github.com/0day-ci/linux/commits/alexandru-tachici-analog-com/hwmon-pmbus-adm1266-add-support/20200624-232203 base: https://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git hwmon-next config: mips-allyesconfig (attached as .config) compiler: mips-linux-gcc (GCC) 9.3.0 reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=mips If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot <lkp@intel.com> All warnings (new ones prefixed by >>): >> drivers/hwmon/pmbus/adm1266.c:27:5: warning: no previous prototype for 'pmbus_block_xfer' [-Wmissing-prototypes] 27 | int pmbus_block_xfer(struct i2c_client *client, u8 cmd, u8 w_len, | ^~~~~~~~~~~~~~~~ vim +/pmbus_block_xfer +27 drivers/hwmon/pmbus/adm1266.c 21 22 /* Different from Block Read as it sends data and waits for the slave to 23 * return a value dependent on that data. The protocol is simply a Write Block 24 * followed by a Read Block without the Read-Block command field and the 25 * Write-Block STOP bit. 26 */ > 27 int pmbus_block_xfer(struct i2c_client *client, u8 cmd, u8 w_len, 28 u8 *data_w, u8 *data_r) 29 { 30 u8 write_buf[ADM1266_PMBUS_BLOCK_MAX + 2]; 31 struct i2c_msg msgs[2] = { 32 { 33 .addr = client->addr, 34 .flags = 0, 35 .buf = write_buf, 36 .len = w_len + 2, 37 }, 38 { 39 .addr = client->addr, 40 .flags = I2C_M_RD, 41 .len = ADM1266_PMBUS_BLOCK_MAX + 2, 42 } 43 }; 44 u8 addr = 0; 45 u8 crc = 0; 46 int ret; 47 48 msgs[0].buf[0] = cmd; 49 msgs[0].buf[1] = w_len; 50 memcpy(&msgs[0].buf[2], data_w, w_len); 51 52 msgs[0].buf = i2c_get_dma_safe_msg_buf(&msgs[0], 1); 53 if (!msgs[0].buf) 54 return -ENOMEM; 55 56 msgs[1].buf = i2c_get_dma_safe_msg_buf(&msgs[1], 1); 57 if (!msgs[1].buf) { 58 i2c_put_dma_safe_msg_buf(msgs[0].buf, &msgs[0], false); 59 return -ENOMEM; 60 } 61 62 ret = i2c_transfer(client->adapter, msgs, 2); 63 if (ret != 2) { 64 ret = -EPROTO; 65 goto cleanup; 66 } 67 68 if (client->flags & I2C_CLIENT_PEC) { 69 addr = i2c_8bit_addr_from_msg(&msgs[0]); 70 crc = crc8(pmbus_crc_table, &addr, 1, crc); 71 crc = crc8(pmbus_crc_table, msgs[0].buf, msgs[0].len, crc); 72 73 addr = i2c_8bit_addr_from_msg(&msgs[1]); 74 crc = crc8(pmbus_crc_table, &addr, 1, crc); 75 crc = crc8(pmbus_crc_table, msgs[1].buf, msgs[1].buf[0] + 1, 76 crc); 77 78 if (crc != msgs[1].buf[msgs[1].buf[0] + 1]) { 79 ret = -EBADMSG; 80 goto cleanup; 81 } 82 } 83 84 memcpy(data_r, &msgs[1].buf[1], msgs[1].buf[0]); 85 ret = msgs[1].buf[0]; 86 87 cleanup: 88 i2c_put_dma_safe_msg_buf(msgs[0].buf, &msgs[0], true); 89 i2c_put_dma_safe_msg_buf(msgs[1].buf, &msgs[1], true); 90 91 return ret; 92 } 93 --- 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 a7ef048a9a5c..381d89a8569f 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> @@ -14,6 +15,82 @@ #include "pmbus.h" +#define ADM1266_PMBUS_BLOCK_MAX 255 + +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. + */ +int pmbus_block_xfer(struct i2c_client *client, u8 cmd, u8 w_len, + u8 *data_w, u8 *data_r) +{ + u8 write_buf[ADM1266_PMBUS_BLOCK_MAX + 2]; + struct i2c_msg msgs[2] = { + { + .addr = client->addr, + .flags = 0, + .buf = write_buf, + .len = w_len + 2, + }, + { + .addr = client->addr, + .flags = I2C_M_RD, + .len = ADM1266_PMBUS_BLOCK_MAX + 2, + } + }; + u8 addr = 0; + u8 crc = 0; + int ret; + + msgs[0].buf[0] = cmd; + msgs[0].buf[1] = w_len; + memcpy(&msgs[0].buf[2], data_w, w_len); + + msgs[0].buf = i2c_get_dma_safe_msg_buf(&msgs[0], 1); + if (!msgs[0].buf) + return -ENOMEM; + + msgs[1].buf = i2c_get_dma_safe_msg_buf(&msgs[1], 1); + if (!msgs[1].buf) { + i2c_put_dma_safe_msg_buf(msgs[0].buf, &msgs[0], false); + return -ENOMEM; + } + + ret = i2c_transfer(client->adapter, msgs, 2); + if (ret != 2) { + ret = -EPROTO; + goto cleanup; + } + + if (client->flags & I2C_CLIENT_PEC) { + addr = i2c_8bit_addr_from_msg(&msgs[0]); + crc = crc8(pmbus_crc_table, &addr, 1, crc); + 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]) { + ret = -EBADMSG; + goto cleanup; + } + } + + memcpy(data_r, &msgs[1].buf[1], msgs[1].buf[0]); + ret = msgs[1].buf[0]; + +cleanup: + i2c_put_dma_safe_msg_buf(msgs[0].buf, &msgs[0], true); + i2c_put_dma_safe_msg_buf(msgs[1].buf, &msgs[1], true); + + return ret; +} + static int adm1266_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -24,6 +101,8 @@ static int adm1266_probe(struct i2c_client *client, info = devm_kzalloc(&client->dev, sizeof(struct pmbus_driver_info), GFP_KERNEL); + crc8_populate_msb(pmbus_crc_table, 0x7); + info->pages = 17; info->format[PSC_VOLTAGE_OUT] = linear; funcs = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT;