Message ID | 20210818010956.1446770-1-jay.xu@rock-chips.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [v3] soc: rockchip: io-domain: set 3.3V before regulator disable | expand |
Hi Jianqun, Thank you for the patch! Yet something to improve: [auto build test ERROR on rockchip/for-next] [also build test ERROR on asoc/for-next v5.14-rc6 next-20210817] [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/Jianqun-Xu/soc-rockchip-io-domain-set-3-3V-before-regulator-disable/20210818-091213 base: https://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git for-next config: arm64-randconfig-r011-20210816 (attached as .config) compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project af7818093677dcb4c0840aef96bc029deb219e57) 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 arm64 cross compiling tool for clang build # apt-get install binutils-aarch64-linux-gnu # https://github.com/0day-ci/linux/commit/883d33a4052a54385679fe84a17345d7083f3a76 git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Jianqun-Xu/soc-rockchip-io-domain-set-3-3V-before-regulator-disable/20210818-091213 git checkout 883d33a4052a54385679fe84a17345d7083f3a76 # save the attached .config to linux build tree mkdir build_dir COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross O=build_dir ARCH=arm64 SHELL=/bin/bash drivers/soc/rockchip/ If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot <lkp@intel.com> All errors (new ones prefixed by >>): >> drivers/soc/rockchip/io-domain.c:173:21: error: use of undeclared identifier 'REGULATOR_EVENT_PRE_ENABLE' } else if (event & REGULATOR_EVENT_PRE_ENABLE) { ^ 1 error generated. vim +/REGULATOR_EVENT_PRE_ENABLE +173 drivers/soc/rockchip/io-domain.c 143 144 static int rockchip_iodomain_notify(struct notifier_block *nb, 145 unsigned long event, 146 void *data) 147 { 148 struct rockchip_iodomain_supply *supply = 149 container_of(nb, struct rockchip_iodomain_supply, nb); 150 int uV; 151 int ret; 152 153 /* 154 * According to Rockchip it's important to keep the SoC IO domain 155 * higher than (or equal to) the external voltage. That means we need 156 * to change it before external voltage changes happen in the case 157 * of an increase. 158 * 159 * Note that in the "pre" change we pick the max possible voltage that 160 * the regulator might end up at (the client requests a range and we 161 * don't know for certain the exact voltage). Right now we rely on the 162 * slop in MAX_VOLTAGE_1_8 and MAX_VOLTAGE_3_3 to save us if clients 163 * request something like a max of 3.6V when they really want 3.3V. 164 * We could attempt to come up with better rules if this fails. 165 */ 166 if (event & REGULATOR_EVENT_PRE_VOLTAGE_CHANGE) { 167 struct pre_voltage_change_data *pvc_data = data; 168 169 uV = max_t(unsigned long, pvc_data->old_uV, pvc_data->max_uV); 170 } else if (event & (REGULATOR_EVENT_VOLTAGE_CHANGE | 171 REGULATOR_EVENT_ABORT_VOLTAGE_CHANGE)) { 172 uV = (unsigned long)data; > 173 } else if (event & REGULATOR_EVENT_PRE_ENABLE) { 174 uV = MAX_VOLTAGE_3_3; 175 } else if (event & REGULATOR_EVENT_PRE_DISABLE) { 176 uV = MAX_VOLTAGE_3_3; 177 } else if (event & REGULATOR_EVENT_ENABLE) { 178 uV = regulator_get_voltage(supply->reg); 179 } else { 180 return NOTIFY_OK; 181 } 182 183 dev_dbg(supply->iod->dev, "Setting to %d\n", uV); 184 185 if (uV > MAX_VOLTAGE_3_3) { 186 dev_err(supply->iod->dev, "Voltage too high: %d\n", uV); 187 188 if (event == REGULATOR_EVENT_PRE_VOLTAGE_CHANGE) 189 return NOTIFY_BAD; 190 } 191 192 ret = supply->iod->write(supply, uV); 193 if (ret && event == REGULATOR_EVENT_PRE_VOLTAGE_CHANGE) 194 return NOTIFY_BAD; 195 196 dev_dbg(supply->iod->dev, "Setting to %d done\n", uV); 197 return NOTIFY_OK; 198 } 199 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
Hi Jianqun, Thank you for the patch! Yet something to improve: [auto build test ERROR on rockchip/for-next] [also build test ERROR on asoc/for-next v5.14-rc6 next-20210817] [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/Jianqun-Xu/soc-rockchip-io-domain-set-3-3V-before-regulator-disable/20210818-091213 base: https://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git for-next config: arm-defconfig (attached as .config) compiler: arm-linux-gnueabi-gcc (GCC) 11.2.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 # https://github.com/0day-ci/linux/commit/883d33a4052a54385679fe84a17345d7083f3a76 git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Jianqun-Xu/soc-rockchip-io-domain-set-3-3V-before-regulator-disable/20210818-091213 git checkout 883d33a4052a54385679fe84a17345d7083f3a76 # save the attached .config to linux build tree mkdir build_dir COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=arm SHELL=/bin/bash If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot <lkp@intel.com> All errors (new ones prefixed by >>): drivers/soc/rockchip/io-domain.c: In function 'rockchip_iodomain_notify': >> drivers/soc/rockchip/io-domain.c:173:28: error: 'REGULATOR_EVENT_PRE_ENABLE' undeclared (first use in this function); did you mean 'REGULATOR_EVENT_PRE_DISABLE'? 173 | } else if (event & REGULATOR_EVENT_PRE_ENABLE) { | ^~~~~~~~~~~~~~~~~~~~~~~~~~ | REGULATOR_EVENT_PRE_DISABLE drivers/soc/rockchip/io-domain.c:173:28: note: each undeclared identifier is reported only once for each function it appears in vim +173 drivers/soc/rockchip/io-domain.c 143 144 static int rockchip_iodomain_notify(struct notifier_block *nb, 145 unsigned long event, 146 void *data) 147 { 148 struct rockchip_iodomain_supply *supply = 149 container_of(nb, struct rockchip_iodomain_supply, nb); 150 int uV; 151 int ret; 152 153 /* 154 * According to Rockchip it's important to keep the SoC IO domain 155 * higher than (or equal to) the external voltage. That means we need 156 * to change it before external voltage changes happen in the case 157 * of an increase. 158 * 159 * Note that in the "pre" change we pick the max possible voltage that 160 * the regulator might end up at (the client requests a range and we 161 * don't know for certain the exact voltage). Right now we rely on the 162 * slop in MAX_VOLTAGE_1_8 and MAX_VOLTAGE_3_3 to save us if clients 163 * request something like a max of 3.6V when they really want 3.3V. 164 * We could attempt to come up with better rules if this fails. 165 */ 166 if (event & REGULATOR_EVENT_PRE_VOLTAGE_CHANGE) { 167 struct pre_voltage_change_data *pvc_data = data; 168 169 uV = max_t(unsigned long, pvc_data->old_uV, pvc_data->max_uV); 170 } else if (event & (REGULATOR_EVENT_VOLTAGE_CHANGE | 171 REGULATOR_EVENT_ABORT_VOLTAGE_CHANGE)) { 172 uV = (unsigned long)data; > 173 } else if (event & REGULATOR_EVENT_PRE_ENABLE) { 174 uV = MAX_VOLTAGE_3_3; 175 } else if (event & REGULATOR_EVENT_PRE_DISABLE) { 176 uV = MAX_VOLTAGE_3_3; 177 } else if (event & REGULATOR_EVENT_ENABLE) { 178 uV = regulator_get_voltage(supply->reg); 179 } else { 180 return NOTIFY_OK; 181 } 182 183 dev_dbg(supply->iod->dev, "Setting to %d\n", uV); 184 185 if (uV > MAX_VOLTAGE_3_3) { 186 dev_err(supply->iod->dev, "Voltage too high: %d\n", uV); 187 188 if (event == REGULATOR_EVENT_PRE_VOLTAGE_CHANGE) 189 return NOTIFY_BAD; 190 } 191 192 ret = supply->iod->write(supply, uV); 193 if (ret && event == REGULATOR_EVENT_PRE_VOLTAGE_CHANGE) 194 return NOTIFY_BAD; 195 196 dev_dbg(supply->iod->dev, "Setting to %d done\n", uV); 197 return NOTIFY_OK; 198 } 199 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
On Wed, Aug 18, 2021 at 09:09:56AM +0800, Jianqun Xu wrote: > + } else if (event & REGULATOR_EVENT_ENABLE) { > + uV = regulator_get_voltage(supply->reg); I'm still not clear that the locking is safe here - the notifier is called with the regulator lock held but regulator_get_voltage() wants to take that lock. Have you tried this with the various lock debugging stuff turned on?
diff --git a/drivers/soc/rockchip/io-domain.c b/drivers/soc/rockchip/io-domain.c index cf8182fc3642..3c59077fafb1 100644 --- a/drivers/soc/rockchip/io-domain.c +++ b/drivers/soc/rockchip/io-domain.c @@ -123,6 +123,12 @@ static int rockchip_iodomain_notify(struct notifier_block *nb, } else if (event & (REGULATOR_EVENT_VOLTAGE_CHANGE | REGULATOR_EVENT_ABORT_VOLTAGE_CHANGE)) { uV = (unsigned long)data; + } else if (event & REGULATOR_EVENT_PRE_ENABLE) { + uV = MAX_VOLTAGE_3_3; + } else if (event & REGULATOR_EVENT_PRE_DISABLE) { + uV = MAX_VOLTAGE_3_3; + } else if (event & REGULATOR_EVENT_ENABLE) { + uV = regulator_get_voltage(supply->reg); } else { return NOTIFY_OK; }
Do a fix to rockchip io-domain, follow this orders: * system running state -> io-domain vsel to 3.3V (actually is done by pre-disable) -> regulator_enable -> vsel change according to regulator voltage * system running state -> io-domain vsel to 3.3V -> regulator_disable Found on some Rockchip SoCs, the regulator enable or disable without care about the io-domain maybe caused soc damaged. Tested on RV1126 EVB. Signed-off-by: Jianqun Xu <jay.xu@rock-chips.com> --- v3: - abandon PRE-ENABLE patch - delete the EVENT_PRE_ENABLE case v2: none v1: first version drivers/soc/rockchip/io-domain.c | 6 ++++++ 1 file changed, 6 insertions(+)