2023-06-08 11:04:27

by Andrej Picej

[permalink] [raw]
Subject: [PATCH] rtc: rv3028: Improve trickle charger logic

Property "trickle-resistor-ohms" allows us to set trickle charger
resistor. However there is no possibility to disable it afterwards.

From now on, disable trickle charger circuit in case device-tree
property "trickle-resistor-ohms" is not present. RV3029 RTC driver uses
the same trickle charger disable logic.

Additionally, lets make sure we only update internal EEPROM in case of a
change. This prevents wear due to excessive EEPROM writes on each probe.

Signed-off-by: Andrej Picej <[email protected]>
---
drivers/rtc/rtc-rv3028.c | 28 ++++++++++++++++++++++------
1 file changed, 22 insertions(+), 6 deletions(-)

diff --git a/drivers/rtc/rtc-rv3028.c b/drivers/rtc/rtc-rv3028.c
index ec5d7a614e2d..190507bf97d0 100644
--- a/drivers/rtc/rtc-rv3028.c
+++ b/drivers/rtc/rtc-rv3028.c
@@ -860,6 +860,7 @@ static int rv3028_probe(struct i2c_client *client)
struct rv3028_data *rv3028;
int ret, status;
u32 ohms;
+ int val_old, val;
struct nvmem_config nvmem_cfg = {
.name = "rv3028_nvram",
.word_size = 1,
@@ -937,9 +938,18 @@ static int rv3028_probe(struct i2c_client *client)
if (ret)
return ret;

+ ret = regmap_read(rv3028->regmap, RV3028_BACKUP, &val_old);
+ if (ret < 0)
+ return ret;
+
+ /* mask out only trickle charger bits */
+ val_old = val_old & (RV3028_BACKUP_TCE | RV3028_BACKUP_TCR_MASK);
+
/* setup trickle charger */
- if (!device_property_read_u32(&client->dev, "trickle-resistor-ohms",
- &ohms)) {
+ if (device_property_read_u32(&client->dev, "trickle-resistor-ohms", &ohms)) {
+ /* disable the trickle charger */
+ val = 0;
+ } else {
int i;

for (i = 0; i < ARRAY_SIZE(rv3028_trickle_resistors); i++)
@@ -947,15 +957,21 @@ static int rv3028_probe(struct i2c_client *client)
break;

if (i < ARRAY_SIZE(rv3028_trickle_resistors)) {
- ret = rv3028_update_cfg(rv3028, RV3028_BACKUP, RV3028_BACKUP_TCE |
- RV3028_BACKUP_TCR_MASK, RV3028_BACKUP_TCE | i);
- if (ret)
- return ret;
+ /* enable the trickle charger and setup its resistor accordingly */
+ val = RV3028_BACKUP_TCE | i;
} else {
dev_warn(&client->dev, "invalid trickle resistor value\n");
}
}

+ /* only update EEPROM if changes are necessary */
+ if (val_old != val) {
+ ret = rv3028_update_cfg(rv3028, RV3028_BACKUP, RV3028_BACKUP_TCE |
+ RV3028_BACKUP_TCR_MASK, val);
+ if (ret)
+ return ret;
+ }
+
ret = rtc_add_group(rv3028->rtc, &rv3028_attr_group);
if (ret)
return ret;
--
2.25.1



2023-06-08 15:29:02

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH] rtc: rv3028: Improve trickle charger logic

Hi Andrej,

kernel test robot noticed the following build warnings:

[auto build test WARNING on abelloni/rtc-next]
[also build test WARNING on linus/master v6.4-rc5 next-20230608]
[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#_base_tree_information]

url: https://github.com/intel-lab-lkp/linux/commits/Andrej-Picej/rtc-rv3028-Improve-trickle-charger-logic/20230608-190234
base: https://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux.git rtc-next
patch link: https://lore.kernel.org/r/20230608090446.2899646-1-andrej.picej%40norik.com
patch subject: [PATCH] rtc: rv3028: Improve trickle charger logic
config: x86_64-randconfig-x062-20230608 (https://download.01.org/0day-ci/archive/20230608/[email protected]/config)
compiler: clang version 15.0.7 (https://github.com/llvm/llvm-project.git 8dfdcc7b7bf66834a761bd8de445840ef68e4d1a)
reproduce (this is a W=1 build):
mkdir -p ~/bin
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
git remote add abelloni https://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux.git
git fetch abelloni rtc-next
git checkout abelloni/rtc-next
b4 shazam https://lore.kernel.org/r/[email protected]
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang ~/bin/make.cross W=1 O=build_dir ARCH=x86_64 olddefconfig
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang ~/bin/make.cross W=1 O=build_dir ARCH=x86_64 SHELL=/bin/bash drivers/rtc/

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/

All warnings (new ones prefixed by >>):

>> drivers/rtc/rtc-rv3028.c:959:7: warning: variable 'val' is used uninitialized whenever 'if' condition is false [-Wsometimes-uninitialized]
if (i < ARRAY_SIZE(rv3028_trickle_resistors)) {
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/rtc/rtc-rv3028.c:968:17: note: uninitialized use occurs here
if (val_old != val) {
^~~
drivers/rtc/rtc-rv3028.c:959:3: note: remove the 'if' if its condition is always true
if (i < ARRAY_SIZE(rv3028_trickle_resistors)) {
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/rtc/rtc-rv3028.c:863:18: note: initialize the variable 'val' to silence this warning
int val_old, val;
^
= 0
1 warning generated.


vim +959 drivers/rtc/rtc-rv3028.c

e6e7376cfd7b3f Alexandre Belloni 2019-02-13 857
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 858 static int rv3028_probe(struct i2c_client *client)
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 859 {
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 860 struct rv3028_data *rv3028;
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 861 int ret, status;
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 862 u32 ohms;
7982492c6d02c7 Andrej Picej 2023-06-08 863 int val_old, val;
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 864 struct nvmem_config nvmem_cfg = {
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 865 .name = "rv3028_nvram",
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 866 .word_size = 1,
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 867 .stride = 1,
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 868 .size = 2,
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 869 .type = NVMEM_TYPE_BATTERY_BACKED,
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 870 .reg_read = rv3028_nvram_read,
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 871 .reg_write = rv3028_nvram_write,
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 872 };
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 873 struct nvmem_config eeprom_cfg = {
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 874 .name = "rv3028_eeprom",
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 875 .word_size = 1,
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 876 .stride = 1,
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 877 .size = 43,
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 878 .type = NVMEM_TYPE_EEPROM,
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 879 .reg_read = rv3028_eeprom_read,
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 880 .reg_write = rv3028_eeprom_write,
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 881 };
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 882
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 883 rv3028 = devm_kzalloc(&client->dev, sizeof(struct rv3028_data),
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 884 GFP_KERNEL);
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 885 if (!rv3028)
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 886 return -ENOMEM;
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 887
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 888 rv3028->regmap = devm_regmap_init_i2c(client, &regmap_config);
c3b29bf6f166f6 Chuhong Yuan 2020-05-28 889 if (IS_ERR(rv3028->regmap))
c3b29bf6f166f6 Chuhong Yuan 2020-05-28 890 return PTR_ERR(rv3028->regmap);
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 891
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 892 i2c_set_clientdata(client, rv3028);
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 893
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 894 ret = regmap_read(rv3028->regmap, RV3028_STATUS, &status);
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 895 if (ret < 0)
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 896 return ret;
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 897
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 898 if (status & RV3028_STATUS_AF)
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 899 dev_warn(&client->dev, "An alarm may have been missed.\n");
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 900
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 901 rv3028->rtc = devm_rtc_allocate_device(&client->dev);
44c638ce4ec6fb Alexandre Belloni 2019-08-19 902 if (IS_ERR(rv3028->rtc))
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 903 return PTR_ERR(rv3028->rtc);
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 904
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 905 if (client->irq > 0) {
16b26f6027588b Wadim Egorov 2022-12-08 906 unsigned long flags;
16b26f6027588b Wadim Egorov 2022-12-08 907
16b26f6027588b Wadim Egorov 2022-12-08 908 /*
16b26f6027588b Wadim Egorov 2022-12-08 909 * If flags = 0, devm_request_threaded_irq() will use IRQ flags
16b26f6027588b Wadim Egorov 2022-12-08 910 * obtained from device tree.
16b26f6027588b Wadim Egorov 2022-12-08 911 */
16b26f6027588b Wadim Egorov 2022-12-08 912 if (dev_fwnode(&client->dev))
16b26f6027588b Wadim Egorov 2022-12-08 913 flags = 0;
16b26f6027588b Wadim Egorov 2022-12-08 914 else
16b26f6027588b Wadim Egorov 2022-12-08 915 flags = IRQF_TRIGGER_LOW;
16b26f6027588b Wadim Egorov 2022-12-08 916
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 917 ret = devm_request_threaded_irq(&client->dev, client->irq,
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 918 NULL, rv3028_handle_irq,
16b26f6027588b Wadim Egorov 2022-12-08 919 flags | IRQF_ONESHOT,
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 920 "rv3028", rv3028);
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 921 if (ret) {
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 922 dev_warn(&client->dev, "unable to request IRQ, alarms disabled\n");
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 923 client->irq = 0;
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 924 }
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 925 }
0f7695691be617 Alexandre Belloni 2021-01-11 926 if (!client->irq)
0f7695691be617 Alexandre Belloni 2021-01-11 927 clear_bit(RTC_FEATURE_ALARM, rv3028->rtc->features);
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 928
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 929 ret = regmap_update_bits(rv3028->regmap, RV3028_CTRL1,
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 930 RV3028_CTRL1_WADA, RV3028_CTRL1_WADA);
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 931 if (ret)
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 932 return ret;
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 933
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 934 /* setup timestamping */
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 935 ret = regmap_update_bits(rv3028->regmap, RV3028_CTRL2,
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 936 RV3028_CTRL2_EIE | RV3028_CTRL2_TSE,
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 937 RV3028_CTRL2_EIE | RV3028_CTRL2_TSE);
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 938 if (ret)
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 939 return ret;
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 940
7982492c6d02c7 Andrej Picej 2023-06-08 941 ret = regmap_read(rv3028->regmap, RV3028_BACKUP, &val_old);
7982492c6d02c7 Andrej Picej 2023-06-08 942 if (ret < 0)
7982492c6d02c7 Andrej Picej 2023-06-08 943 return ret;
7982492c6d02c7 Andrej Picej 2023-06-08 944
7982492c6d02c7 Andrej Picej 2023-06-08 945 /* mask out only trickle charger bits */
7982492c6d02c7 Andrej Picej 2023-06-08 946 val_old = val_old & (RV3028_BACKUP_TCE | RV3028_BACKUP_TCR_MASK);
7982492c6d02c7 Andrej Picej 2023-06-08 947
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 948 /* setup trickle charger */
7982492c6d02c7 Andrej Picej 2023-06-08 949 if (device_property_read_u32(&client->dev, "trickle-resistor-ohms", &ohms)) {
7982492c6d02c7 Andrej Picej 2023-06-08 950 /* disable the trickle charger */
7982492c6d02c7 Andrej Picej 2023-06-08 951 val = 0;
7982492c6d02c7 Andrej Picej 2023-06-08 952 } else {
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 953 int i;
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 954
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 955 for (i = 0; i < ARRAY_SIZE(rv3028_trickle_resistors); i++)
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 956 if (ohms == rv3028_trickle_resistors[i])
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 957 break;
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 958
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 @959 if (i < ARRAY_SIZE(rv3028_trickle_resistors)) {
7982492c6d02c7 Andrej Picej 2023-06-08 960 /* enable the trickle charger and setup its resistor accordingly */
7982492c6d02c7 Andrej Picej 2023-06-08 961 val = RV3028_BACKUP_TCE | i;
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 962 } else {
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 963 dev_warn(&client->dev, "invalid trickle resistor value\n");
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 964 }
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 965 }
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 966
7982492c6d02c7 Andrej Picej 2023-06-08 967 /* only update EEPROM if changes are necessary */
7982492c6d02c7 Andrej Picej 2023-06-08 968 if (val_old != val) {
7982492c6d02c7 Andrej Picej 2023-06-08 969 ret = rv3028_update_cfg(rv3028, RV3028_BACKUP, RV3028_BACKUP_TCE |
7982492c6d02c7 Andrej Picej 2023-06-08 970 RV3028_BACKUP_TCR_MASK, val);
7982492c6d02c7 Andrej Picej 2023-06-08 971 if (ret)
7982492c6d02c7 Andrej Picej 2023-06-08 972 return ret;
7982492c6d02c7 Andrej Picej 2023-06-08 973 }
7982492c6d02c7 Andrej Picej 2023-06-08 974
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 975 ret = rtc_add_group(rv3028->rtc, &rv3028_attr_group);
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 976 if (ret)
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 977 return ret;
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 978
018d959ba7ffca Alexandre Belloni 2021-10-18 979 set_bit(RTC_FEATURE_BACKUP_SWITCH_MODE, rv3028->rtc->features);
018d959ba7ffca Alexandre Belloni 2021-10-18 980
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 981 rv3028->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 982 rv3028->rtc->range_max = RTC_TIMESTAMP_END_2099;
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 983 rv3028->rtc->ops = &rv3028_rtc_ops;
fdcfd854333be5 Bartosz Golaszewski 2020-11-09 984 ret = devm_rtc_register_device(rv3028->rtc);
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 985 if (ret)
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 986 return ret;
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 987
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 988 nvmem_cfg.priv = rv3028->regmap;
3a905c2d9544a4 Bartosz Golaszewski 2020-11-09 989 devm_rtc_nvmem_register(rv3028->rtc, &nvmem_cfg);
de0ad60e79e1ce Alexandre Belloni 2020-10-09 990 eeprom_cfg.priv = rv3028;
3a905c2d9544a4 Bartosz Golaszewski 2020-11-09 991 devm_rtc_nvmem_register(rv3028->rtc, &eeprom_cfg);
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 992
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 993 rv3028->rtc->max_user_freq = 1;
e6e7376cfd7b3f Alexandre Belloni 2019-02-13 994

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki