Message ID | d01d23e2473407af37c42acb6ca4815ae5fd256e.1618464534.git.Arthur.Petrosyan@synopsys.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [01/15] usb: dwc2: Update exit hibernation when port reset is asserted | expand |
On 15.04.2021 8:41, Artur Petrosyan wrote: > When dwc2 core is in hibernation mode loading > driver again causes driver fail. Because in > that mode registers are not accessible. > > In order to exit from hibernation checking > dwc2 core power saving state in "dwc2_driver_remove()" > function. If core is in hibernation, then checking the > operational mode of the driver. To check whether dwc2 core > is operating in host mode or device mode there is one way > which is retrieving the backup value of "gotgctl" and compare > the "CurMod" value. If previously core entered hibernation > in host mode then the exit is performed for host if not then > exit is performed for device mode. The introduced checking > is because in hibernation state all registers are not > accessible. > > Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com> > --- > drivers/usb/dwc2/platform.c | 16 ++++++++++++++++ > 1 file changed, 16 insertions(+) > > diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c > index f8b819cfa80e..2ae4748ed5ec 100644 > --- a/drivers/usb/dwc2/platform.c > +++ b/drivers/usb/dwc2/platform.c > @@ -316,8 +316,24 @@ static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg) > static int dwc2_driver_remove(struct platform_device *dev) > { > struct dwc2_hsotg *hsotg = platform_get_drvdata(dev); > + struct dwc2_gregs_backup *gr; > int ret = 0; > > + /* Exit Hibernation when driver is removed. */ > + if (hsotg->hibernated) { > + if (gr->gotgctl & GOTGCTL_CURMODE_HOST) { > + ret = dwc2_exit_hibernation(hsotg, 0, 0, 1); > + if (ret) > + dev_err(hsotg->dev, > + "exit hibernation failed.\n"); > + } else { > + ret = dwc2_exit_hibernation(hsotg, 0, 0, 0); > + if (ret) > + dev_err(hsotg->dev, > + "exit hibernation failed.\n"); Again, why duplicate the innermost *if*? > + } > + } > + > /* Exit Partial Power Down when driver is removed. */ > if (hsotg->in_ppd) { > ret = dwc2_exit_partial_power_down(hsotg, 0, true); MBR, Sergei
Hi Artur, Thank you for the patch! Perhaps something to improve: [auto build test WARNING on usb/usb-testing] [also build test WARNING on next-20210414] [cannot apply to peter.chen-usb/for-usb-next linus/master balbi-usb/testing/next v5.12-rc7] [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/Artur-Petrosyan/usb-dwc2-Update-exit-hibernation-when-port-reset-is-asserted/20210415-144021 base: https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git usb-testing config: x86_64-randconfig-a014-20210415 (attached as .config) compiler: clang version 13.0.0 (https://github.com/llvm/llvm-project 6a18cc23efad410db48a3ccfc233d215de7d4cb9) 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 x86_64 cross compiling tool for clang build # apt-get install binutils-x86-64-linux-gnu # https://github.com/0day-ci/linux/commit/8e4dbc0200040af9c752aca4090cd41572e6fb86 git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Artur-Petrosyan/usb-dwc2-Update-exit-hibernation-when-port-reset-is-asserted/20210415-144021 git checkout 8e4dbc0200040af9c752aca4090cd41572e6fb86 # save the attached .config to linux build tree COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 ARCH=x86_64 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/usb/dwc2/platform.c:324:7: warning: variable 'gr' is uninitialized when used here [-Wuninitialized] if (gr->gotgctl & GOTGCTL_CURMODE_HOST) { ^~ drivers/usb/dwc2/platform.c:319:30: note: initialize the variable 'gr' to silence this warning struct dwc2_gregs_backup *gr; ^ = NULL 1 warning generated. vim +/gr +324 drivers/usb/dwc2/platform.c 304 305 /** 306 * dwc2_driver_remove() - Called when the DWC_otg core is unregistered with the 307 * DWC_otg driver 308 * 309 * @dev: Platform device 310 * 311 * This routine is called, for example, when the rmmod command is executed. The 312 * device may or may not be electrically present. If it is present, the driver 313 * stops device processing. Any resources used on behalf of this device are 314 * freed. 315 */ 316 static int dwc2_driver_remove(struct platform_device *dev) 317 { 318 struct dwc2_hsotg *hsotg = platform_get_drvdata(dev); 319 struct dwc2_gregs_backup *gr; 320 int ret = 0; 321 322 /* Exit Hibernation when driver is removed. */ 323 if (hsotg->hibernated) { > 324 if (gr->gotgctl & GOTGCTL_CURMODE_HOST) { 325 ret = dwc2_exit_hibernation(hsotg, 0, 0, 1); 326 if (ret) 327 dev_err(hsotg->dev, 328 "exit hibernation failed.\n"); 329 } else { 330 ret = dwc2_exit_hibernation(hsotg, 0, 0, 0); 331 if (ret) 332 dev_err(hsotg->dev, 333 "exit hibernation failed.\n"); 334 } 335 } 336 337 /* Exit Partial Power Down when driver is removed. */ 338 if (hsotg->in_ppd) { 339 ret = dwc2_exit_partial_power_down(hsotg, 0, true); 340 if (ret) 341 dev_err(hsotg->dev, 342 "exit partial_power_down failed\n"); 343 } 344 345 /* Exit clock gating when driver is removed. */ 346 if (hsotg->params.power_down == DWC2_POWER_DOWN_PARAM_NONE && 347 hsotg->bus_suspended) { 348 if (dwc2_is_device_mode(hsotg)) 349 dwc2_gadget_exit_clock_gating(hsotg, 0); 350 else 351 dwc2_host_exit_clock_gating(hsotg, 0); 352 } 353 354 dwc2_debugfs_exit(hsotg); 355 if (hsotg->hcd_enabled) 356 dwc2_hcd_remove(hsotg); 357 if (hsotg->gadget_enabled) 358 dwc2_hsotg_remove(hsotg); 359 360 dwc2_drd_exit(hsotg); 361 362 if (hsotg->params.activate_stm_id_vb_detection) 363 regulator_disable(hsotg->usb33d); 364 365 if (hsotg->ll_hw_enabled) 366 dwc2_lowlevel_hw_disable(hsotg); 367 368 reset_control_assert(hsotg->reset); 369 reset_control_assert(hsotg->reset_ecc); 370 371 return ret; 372 } 373 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
Hi Artur, https://git-scm.com/docs/git-format-patch ] url: https://github.com/0day-ci/linux/commits/Artur-Petrosyan/usb-dwc2-Update-exit-hibernation-when-port-reset-is-asserted/20210415-144021 base: https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git usb-testing config: i386-randconfig-m021-20210415 (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 <lkp@intel.com> Reported-by: Dan Carpenter <dan.carpenter@oracle.com> smatch warnings: drivers/usb/dwc2/platform.c:324 dwc2_driver_remove() error: potentially dereferencing uninitialized 'gr'. vim +/gr +324 drivers/usb/dwc2/platform.c 5b9974b13e3648 drivers/staging/dwc2/platform.c Matthijs Kooijman 2013-04-22 316 static int dwc2_driver_remove(struct platform_device *dev) 5b9974b13e3648 drivers/staging/dwc2/platform.c Matthijs Kooijman 2013-04-22 317 { 5b9974b13e3648 drivers/staging/dwc2/platform.c Matthijs Kooijman 2013-04-22 318 struct dwc2_hsotg *hsotg = platform_get_drvdata(dev); 8e4dbc0200040a drivers/usb/dwc2/platform.c Artur Petrosyan 2021-04-15 319 struct dwc2_gregs_backup *gr; ^^ b46b1ef7b0da5c drivers/usb/dwc2/platform.c Artur Petrosyan 2021-04-08 320 int ret = 0; b46b1ef7b0da5c drivers/usb/dwc2/platform.c Artur Petrosyan 2021-04-08 321 8e4dbc0200040a drivers/usb/dwc2/platform.c Artur Petrosyan 2021-04-15 322 /* Exit Hibernation when driver is removed. */ 8e4dbc0200040a drivers/usb/dwc2/platform.c Artur Petrosyan 2021-04-15 323 if (hsotg->hibernated) { 8e4dbc0200040a drivers/usb/dwc2/platform.c Artur Petrosyan 2021-04-15 @324 if (gr->gotgctl & GOTGCTL_CURMODE_HOST) { ^^^^^^^^^^^ 8e4dbc0200040a drivers/usb/dwc2/platform.c Artur Petrosyan 2021-04-15 325 ret = dwc2_exit_hibernation(hsotg, 0, 0, 1); 8e4dbc0200040a drivers/usb/dwc2/platform.c Artur Petrosyan 2021-04-15 326 if (ret) 8e4dbc0200040a drivers/usb/dwc2/platform.c Artur Petrosyan 2021-04-15 327 dev_err(hsotg->dev, 8e4dbc0200040a drivers/usb/dwc2/platform.c Artur Petrosyan 2021-04-15 328 "exit hibernation failed.\n"); 8e4dbc0200040a drivers/usb/dwc2/platform.c Artur Petrosyan 2021-04-15 329 } else { 8e4dbc0200040a drivers/usb/dwc2/platform.c Artur Petrosyan 2021-04-15 330 ret = dwc2_exit_hibernation(hsotg, 0, 0, 0); 8e4dbc0200040a drivers/usb/dwc2/platform.c Artur Petrosyan 2021-04-15 331 if (ret) 8e4dbc0200040a drivers/usb/dwc2/platform.c Artur Petrosyan 2021-04-15 332 dev_err(hsotg->dev, 8e4dbc0200040a drivers/usb/dwc2/platform.c Artur Petrosyan 2021-04-15 333 "exit hibernation failed.\n"); 8e4dbc0200040a drivers/usb/dwc2/platform.c Artur Petrosyan 2021-04-15 334 } 8e4dbc0200040a drivers/usb/dwc2/platform.c Artur Petrosyan 2021-04-15 335 } --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
Hi Sergei, On 4/15/2021 13:24, Sergei Shtylyov wrote: > On 15.04.2021 8:41, Artur Petrosyan wrote: > >> When dwc2 core is in hibernation mode loading >> driver again causes driver fail. Because in >> that mode registers are not accessible. >> >> In order to exit from hibernation checking >> dwc2 core power saving state in "dwc2_driver_remove()" >> function. If core is in hibernation, then checking the >> operational mode of the driver. To check whether dwc2 core >> is operating in host mode or device mode there is one way >> which is retrieving the backup value of "gotgctl" and compare >> the "CurMod" value. If previously core entered hibernation >> in host mode then the exit is performed for host if not then >> exit is performed for device mode. The introduced checking >> is because in hibernation state all registers are not >> accessible. >> >> Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com> >> --- >> drivers/usb/dwc2/platform.c | 16 ++++++++++++++++ >> 1 file changed, 16 insertions(+) >> >> diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c >> index f8b819cfa80e..2ae4748ed5ec 100644 >> --- a/drivers/usb/dwc2/platform.c >> +++ b/drivers/usb/dwc2/platform.c >> @@ -316,8 +316,24 @@ static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg) >> static int dwc2_driver_remove(struct platform_device *dev) >> { >> struct dwc2_hsotg *hsotg = platform_get_drvdata(dev); >> + struct dwc2_gregs_backup *gr; >> int ret = 0; >> >> + /* Exit Hibernation when driver is removed. */ >> + if (hsotg->hibernated) { >> + if (gr->gotgctl & GOTGCTL_CURMODE_HOST) { >> + ret = dwc2_exit_hibernation(hsotg, 0, 0, 1); >> + if (ret) >> + dev_err(hsotg->dev, >> + "exit hibernation failed.\n"); >> + } else { >> + ret = dwc2_exit_hibernation(hsotg, 0, 0, 0); >> + if (ret) >> + dev_err(hsotg->dev, >> + "exit hibernation failed.\n"); > > Again, why duplicate the innermost *if*? Again the reason is that combination of inner and outside ifs would give as a situation when core would not be hibernated but driver would try to exit from host or device hibernation. > >> + } >> + } >> + >> /* Exit Partial Power Down when driver is removed. */ >> if (hsotg->in_ppd) { >> ret = dwc2_exit_partial_power_down(hsotg, 0, true); > > MBR, Sergei > Regards, Artur
diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index f8b819cfa80e..2ae4748ed5ec 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -316,8 +316,24 @@ static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg) static int dwc2_driver_remove(struct platform_device *dev) { struct dwc2_hsotg *hsotg = platform_get_drvdata(dev); + struct dwc2_gregs_backup *gr; int ret = 0; + /* Exit Hibernation when driver is removed. */ + if (hsotg->hibernated) { + if (gr->gotgctl & GOTGCTL_CURMODE_HOST) { + ret = dwc2_exit_hibernation(hsotg, 0, 0, 1); + if (ret) + dev_err(hsotg->dev, + "exit hibernation failed.\n"); + } else { + ret = dwc2_exit_hibernation(hsotg, 0, 0, 0); + if (ret) + dev_err(hsotg->dev, + "exit hibernation failed.\n"); + } + } + /* Exit Partial Power Down when driver is removed. */ if (hsotg->in_ppd) { ret = dwc2_exit_partial_power_down(hsotg, 0, true);
When dwc2 core is in hibernation mode loading driver again causes driver fail. Because in that mode registers are not accessible. In order to exit from hibernation checking dwc2 core power saving state in "dwc2_driver_remove()" function. If core is in hibernation, then checking the operational mode of the driver. To check whether dwc2 core is operating in host mode or device mode there is one way which is retrieving the backup value of "gotgctl" and compare the "CurMod" value. If previously core entered hibernation in host mode then the exit is performed for host if not then exit is performed for device mode. The introduced checking is because in hibernation state all registers are not accessible. Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com> --- drivers/usb/dwc2/platform.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)