Re: [PATCH 2/4] rtc: abx80x: Enable SQW output
Hi Dan, Thank you very much for pointing out the issues. However, I'm not sure that the code, you have analyzed, will be a part of final patch set. I intend to redesign all the code deeply, as Alexandre Belloni suggested [1]. Thank you again! -- Best Regards, Kirill Kapranov Software Engineer CompuLab Ltd. [1] https://marc.info/?l=linux-rtc&m=161696606727215&w=2 On 3/29/21 9:19 AM, Dan Carpenter wrote: Hi Kirill, url: https://github.com/0day-ci/linux/commits/Kirill-Kapranov/rtc-abx80x-Enable-distributed-digital-calibration/20210329-053233 base: https://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux.git rtc-next config: i386-randconfig-m021-20210328 (attached as .config) compiler: gcc-9 (Debian 9.3.0-22) 9.3.0 If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot Reported-by: Dan Carpenter smatch warnings: drivers/rtc/rtc-abx80x.c:561 sqw_set() error: uninitialized symbol 'retval'. vim +/retval +561 drivers/rtc/rtc-abx80x.c 3f6d456de4f347 Kirill Kapranov 2021-03-29 527 static int sqw_set(struct i2c_client *client, const char *buf) 3f6d456de4f347 Kirill Kapranov 2021-03-29 528 { 3f6d456de4f347 Kirill Kapranov 2021-03-29 529 union abx8xx_reg_sqw reg_sqw; 3f6d456de4f347 Kirill Kapranov 2021-03-29 530 int retval; 3f6d456de4f347 Kirill Kapranov 2021-03-29 531 3f6d456de4f347 Kirill Kapranov 2021-03-29 532 reg_sqw.val = i2c_smbus_read_byte_data(client, ABX8XX_REG_SQW); 3f6d456de4f347 Kirill Kapranov 2021-03-29 533 if (reg_sqw.val < 0) 3f6d456de4f347 Kirill Kapranov 2021-03-29 534 goto err; "retval" not set. Forgetting to set the error code is the canonical bug for do nothing gotos like this. 3f6d456de4f347 Kirill Kapranov 2021-03-29 535 3f6d456de4f347 Kirill Kapranov 2021-03-29 536 if (sysfs_streq(buf, "none")) { 3f6d456de4f347 Kirill Kapranov 2021-03-29 537 reg_sqw.sqwe = 0; 3f6d456de4f347 Kirill Kapranov 2021-03-29 538 dev_info(&client->dev, "sqw output disabled\n"); 3f6d456de4f347 Kirill Kapranov 2021-03-29 539 } else { 3f6d456de4f347 Kirill Kapranov 2021-03-29 540 int idx = __sysfs_match_string(sqfs, SQFS_COUNT, buf); 3f6d456de4f347 Kirill Kapranov 2021-03-29 541 3f6d456de4f347 Kirill Kapranov 2021-03-29 542 if (idx < 0) 3f6d456de4f347 Kirill Kapranov 2021-03-29 543 return idx; ^^^ These are direct returns. Just do direct returns everywhere (more readably, fewer bugs). 3f6d456de4f347 Kirill Kapranov 2021-03-29 544 3f6d456de4f347 Kirill Kapranov 2021-03-29 545 if (abx80x_is_rc_mode(client) && !valid_for_rc_mode[idx]) 3f6d456de4f347 Kirill Kapranov 2021-03-29 546 dev_warn(&client->dev, "sqw frequency %s valid only in xt mode\n", 3f6d456de4f347 Kirill Kapranov 2021-03-29 547 sqfs[idx]); 3f6d456de4f347 Kirill Kapranov 2021-03-29 548 3f6d456de4f347 Kirill Kapranov 2021-03-29 549 dev_info(&client->dev, "sqw output enabled @ %s\n", sqfs[idx]); 3f6d456de4f347 Kirill Kapranov 2021-03-29 550 reg_sqw.sqwe = 1; 3f6d456de4f347 Kirill Kapranov 2021-03-29 551 reg_sqw.sqws = idx; 3f6d456de4f347 Kirill Kapranov 2021-03-29 552 } 3f6d456de4f347 Kirill Kapranov 2021-03-29 553 3f6d456de4f347 Kirill Kapranov 2021-03-29 554 retval = i2c_smbus_write_byte_data(client, ABX8XX_REG_SQW, reg_sqw.val); 3f6d456de4f347 Kirill Kapranov 2021-03-29 555 if (retval < 0) 3f6d456de4f347 Kirill Kapranov 2021-03-29 556 goto err; 3f6d456de4f347 Kirill Kapranov 2021-03-29 557 3f6d456de4f347 Kirill Kapranov 2021-03-29 558 return 0; 3f6d456de4f347 Kirill Kapranov 2021-03-29 559 err: 3f6d456de4f347 Kirill Kapranov 2021-03-29 560 dev_err(&client->dev, "Failed to set SQW\n"); 3f6d456de4f347 Kirill Kapranov 2021-03-29 @561 return retval; ^ 3f6d456de4f347 Kirill Kapranov 2021-03-29 562 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org
Re: [PATCH 2/4] rtc: abx80x: Enable SQW output
Hi Kirill, url: https://github.com/0day-ci/linux/commits/Kirill-Kapranov/rtc-abx80x-Enable-distributed-digital-calibration/20210329-053233 base: https://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux.git rtc-next config: i386-randconfig-m021-20210328 (attached as .config) compiler: gcc-9 (Debian 9.3.0-22) 9.3.0 If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot Reported-by: Dan Carpenter smatch warnings: drivers/rtc/rtc-abx80x.c:561 sqw_set() error: uninitialized symbol 'retval'. vim +/retval +561 drivers/rtc/rtc-abx80x.c 3f6d456de4f347 Kirill Kapranov 2021-03-29 527 static int sqw_set(struct i2c_client *client, const char *buf) 3f6d456de4f347 Kirill Kapranov 2021-03-29 528 { 3f6d456de4f347 Kirill Kapranov 2021-03-29 529 union abx8xx_reg_sqw reg_sqw; 3f6d456de4f347 Kirill Kapranov 2021-03-29 530 int retval; 3f6d456de4f347 Kirill Kapranov 2021-03-29 531 3f6d456de4f347 Kirill Kapranov 2021-03-29 532 reg_sqw.val = i2c_smbus_read_byte_data(client, ABX8XX_REG_SQW); 3f6d456de4f347 Kirill Kapranov 2021-03-29 533 if (reg_sqw.val < 0) 3f6d456de4f347 Kirill Kapranov 2021-03-29 534 goto err; "retval" not set. Forgetting to set the error code is the canonical bug for do nothing gotos like this. 3f6d456de4f347 Kirill Kapranov 2021-03-29 535 3f6d456de4f347 Kirill Kapranov 2021-03-29 536 if (sysfs_streq(buf, "none")) { 3f6d456de4f347 Kirill Kapranov 2021-03-29 537 reg_sqw.sqwe = 0; 3f6d456de4f347 Kirill Kapranov 2021-03-29 538 dev_info(&client->dev, "sqw output disabled\n"); 3f6d456de4f347 Kirill Kapranov 2021-03-29 539 } else { 3f6d456de4f347 Kirill Kapranov 2021-03-29 540 int idx = __sysfs_match_string(sqfs, SQFS_COUNT, buf); 3f6d456de4f347 Kirill Kapranov 2021-03-29 541 3f6d456de4f347 Kirill Kapranov 2021-03-29 542 if (idx < 0) 3f6d456de4f347 Kirill Kapranov 2021-03-29 543 return idx; ^^^ These are direct returns. Just do direct returns everywhere (more readably, fewer bugs). 3f6d456de4f347 Kirill Kapranov 2021-03-29 544 3f6d456de4f347 Kirill Kapranov 2021-03-29 545 if (abx80x_is_rc_mode(client) && !valid_for_rc_mode[idx]) 3f6d456de4f347 Kirill Kapranov 2021-03-29 546 dev_warn(&client->dev, "sqw frequency %s valid only in xt mode\n", 3f6d456de4f347 Kirill Kapranov 2021-03-29 547 sqfs[idx]); 3f6d456de4f347 Kirill Kapranov 2021-03-29 548 3f6d456de4f347 Kirill Kapranov 2021-03-29 549 dev_info(&client->dev, "sqw output enabled @ %s\n", sqfs[idx]); 3f6d456de4f347 Kirill Kapranov 2021-03-29 550 reg_sqw.sqwe = 1; 3f6d456de4f347 Kirill Kapranov 2021-03-29 551 reg_sqw.sqws = idx; 3f6d456de4f347 Kirill Kapranov 2021-03-29 552 } 3f6d456de4f347 Kirill Kapranov 2021-03-29 553 3f6d456de4f347 Kirill Kapranov 2021-03-29 554 retval = i2c_smbus_write_byte_data(client, ABX8XX_REG_SQW, reg_sqw.val); 3f6d456de4f347 Kirill Kapranov 2021-03-29 555 if (retval < 0) 3f6d456de4f347 Kirill Kapranov 2021-03-29 556 goto err; 3f6d456de4f347 Kirill Kapranov 2021-03-29 557 3f6d456de4f347 Kirill Kapranov 2021-03-29 558 return 0; 3f6d456de4f347 Kirill Kapranov 2021-03-29 559 err: 3f6d456de4f347 Kirill Kapranov 2021-03-29 560 dev_err(&client->dev, "Failed to set SQW\n"); 3f6d456de4f347 Kirill Kapranov 2021-03-29 @561 return retval; ^ 3f6d456de4f347 Kirill Kapranov 2021-03-29 562 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org .config.gz Description: application/gzip
Re: [PATCH 2/4] rtc: abx80x: Enable SQW output
Hi Kirill, Thank you for the patch! Perhaps something to improve: [auto build test WARNING on abelloni/rtc-next] [also build test WARNING on v5.12-rc5 next-20210326] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch] url: https://github.com/0day-ci/linux/commits/Kirill-Kapranov/rtc-abx80x-Enable-distributed-digital-calibration/20210329-053233 base: https://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux.git rtc-next config: arm-randconfig-r034-20210329 (attached as .config) compiler: clang version 13.0.0 (https://github.com/llvm/llvm-project 821547cabb5819ed42245376a9afcd11cdee5ddd) 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 # install arm cross compiling tool for clang build # apt-get install binutils-arm-linux-gnueabi # https://github.com/0day-ci/linux/commit/3f6d456de4f347f0d2fd0af648b1ca21b1212d17 git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Kirill-Kapranov/rtc-abx80x-Enable-distributed-digital-calibration/20210329-053233 git checkout 3f6d456de4f347f0d2fd0af648b1ca21b1212d17 # save the attached .config to linux build tree COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=arm If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot All warnings (new ones prefixed by >>): >> drivers/rtc/rtc-abx80x.c:533:6: warning: variable 'retval' is used >> uninitialized whenever 'if' condition is true [-Wsometimes-uninitialized] if (reg_sqw.val < 0) ^~~ drivers/rtc/rtc-abx80x.c:561:9: note: uninitialized use occurs here return retval; ^~ drivers/rtc/rtc-abx80x.c:533:2: note: remove the 'if' if its condition is always false if (reg_sqw.val < 0) ^~~~ drivers/rtc/rtc-abx80x.c:530:12: note: initialize the variable 'retval' to silence this warning int retval; ^ = 0 1 warning generated. vim +533 drivers/rtc/rtc-abx80x.c 526 527 static int sqw_set(struct i2c_client *client, const char *buf) 528 { 529 union abx8xx_reg_sqw reg_sqw; 530 int retval; 531 532 reg_sqw.val = i2c_smbus_read_byte_data(client, ABX8XX_REG_SQW); > 533 if (reg_sqw.val < 0) 534 goto err; 535 536 if (sysfs_streq(buf, "none")) { 537 reg_sqw.sqwe = 0; 538 dev_info(&client->dev, "sqw output disabled\n"); 539 } else { 540 int idx = __sysfs_match_string(sqfs, SQFS_COUNT, buf); 541 542 if (idx < 0) 543 return idx; 544 545 if (abx80x_is_rc_mode(client) && !valid_for_rc_mode[idx]) 546 dev_warn(&client->dev, "sqw frequency %s valid only in xt mode\n", 547 sqfs[idx]); 548 549 dev_info(&client->dev, "sqw output enabled @ %s\n", sqfs[idx]); 550 reg_sqw.sqwe = 1; 551 reg_sqw.sqws = idx; 552 } 553 554 retval = i2c_smbus_write_byte_data(client, ABX8XX_REG_SQW, reg_sqw.val); 555 if (retval < 0) 556 goto err; 557 558 return 0; 559 err: 560 dev_err(&client->dev, "Failed to set SQW\n"); 561 return retval; 562 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org .config.gz Description: application/gzip
[PATCH 2/4] rtc: abx80x: Enable SQW output
The RTCs of the family are able to produce square wave output for RTC calibration purposes or for an external usage. Signed-off-by: Kirill Kapranov --- drivers/rtc/rtc-abx80x.c | 126 +++ 1 file changed, 126 insertions(+) diff --git a/drivers/rtc/rtc-abx80x.c b/drivers/rtc/rtc-abx80x.c index 9b0138d07232..153d89b56da9 100644 --- a/drivers/rtc/rtc-abx80x.c +++ b/drivers/rtc/rtc-abx80x.c @@ -51,6 +51,9 @@ #define ABX8XX_IRQ_AIE BIT(2) #define ABX8XX_IRQ_IM_1_4 (0x3 << 5) +#define ABX8XX_REG_SQW 0x13 +#define ABX8XX_SQW_MODE_BITS 5 + #define ABX8XX_REG_CD_TIMER_CTL0x18 #define ABX8XX_REG_OSC 0x1c @@ -117,6 +120,15 @@ struct abx80x_priv { struct watchdog_device wdog; }; +union abx8xx_reg_sqw { + struct { + unsigned int sqws:5; + int:2; + unsigned int sqwe:2; + }; + int val; +} __packed; + static int abx80x_write_config_key(struct i2c_client *client, u8 key) { if (i2c_smbus_write_byte_data(client, ABX8XX_REG_CFG_KEY, key) < 0) { @@ -486,9 +498,119 @@ static ssize_t oscillator_show(struct device *dev, static DEVICE_ATTR_RW(oscillator); +#define SQFS_COUNT (1 << ABX8XX_SQW_MODE_BITS) +/* The index of the array is the value to be written to the 'Square Wave Function + * Select' register to make the RTC generate the required square wave. + */ +static const char *const sqfs[SQFS_COUNT] = { + "1_century", "32768_Hz", "8192_Hz", "4096_Hz", + "2048_Hz", "1024_Hz", "512_Hz", "256_Hz", + "128_Hz", "64_Hz", "32_Hz", "16_Hz", + "8_Hz", "4_Hz", "2_Hz", "1_Hz", + "1/2_Hz", "1/4_Hz", "1/8_Hz", "1/16_Hz", + "1/32_Hz", "1_min", "16384_Hz", "100_Hz", + "1_hour", "1_day", "TIRQ", "nTIRQ", + "1_year", "1_Hz_to_Counters", "1/32_Hz_from_Acal", "1/8_Hz_from_Acal", +}; + +static const bool valid_for_rc_mode[SQFS_COUNT] = { + true, false, false, false, + false, false, false, false, + true, true, true, true, + true, true, true, true, + true, true, true, true, + true, true, false, false, + true, true, true, true, + true, true, true, true, +}; + +static int sqw_set(struct i2c_client *client, const char *buf) +{ + union abx8xx_reg_sqw reg_sqw; + int retval; + + reg_sqw.val = i2c_smbus_read_byte_data(client, ABX8XX_REG_SQW); + if (reg_sqw.val < 0) + goto err; + + if (sysfs_streq(buf, "none")) { + reg_sqw.sqwe = 0; + dev_info(&client->dev, "sqw output disabled\n"); + } else { + int idx = __sysfs_match_string(sqfs, SQFS_COUNT, buf); + + if (idx < 0) + return idx; + + if (abx80x_is_rc_mode(client) && !valid_for_rc_mode[idx]) + dev_warn(&client->dev, "sqw frequency %s valid only in xt mode\n", + sqfs[idx]); + + dev_info(&client->dev, "sqw output enabled @ %s\n", sqfs[idx]); + reg_sqw.sqwe = 1; + reg_sqw.sqws = idx; + } + + retval = i2c_smbus_write_byte_data(client, ABX8XX_REG_SQW, reg_sqw.val); + if (retval < 0) + goto err; + + return 0; +err: + dev_err(&client->dev, "Failed to set SQW\n"); + return retval; + +} + +static ssize_t sqw_store(struct device *dev, +struct device_attribute *attr, +const char *buf, size_t count) +{ + int retval; + + retval = sqw_set(to_i2c_client(dev->parent), buf); + if (retval) + return retval; + else + return count; +} + +static ssize_t sqw_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev->parent); + union abx8xx_reg_sqw reg_sqw; + int len = 0; + int i; + + reg_sqw.val = i2c_smbus_read_byte_data(client, ABX8XX_REG_SQW); + if (reg_sqw.val < 0) { + dev_err(dev, "Failed to read SQW\n"); + sprintf(buf, "\n"); + return reg_sqw.val; + } + + if (reg_sqw.sqwe) + len += scnprintf(buf+len, PAGE_SIZE - len, "none "); + else + len += scnprintf(buf+len, PAGE_SIZE - len, "[none] "); + + for (i = 0; i < SQFS_COUNT; ++i) { + if (reg_sqw.sqwe && i == reg_sqw.sqws) + len += scnprintf(buf+len, PAGE_SIZE - len, "[%s] ", sqfs[i]); + else + len += scnprintf(buf+len, PAGE_SIZE - len, "%s ", sqfs[i]); + } + + return len; +} + +static DEVICE_ATTR_RW(sqw); + static struct attribute *rtc_calib_attrs[] = { &dev_attr_autocalibration.attr, &dev_attr_oscillator.attr, + &dev_attr_sqw.attr, NULL, }; @@ -686,6 +808,7 @@ static int abx80x_probe(struct i2c_clien