On 5/5/23 21:15, Christophe JAILLET wrote: > dwc2_driver_probe() calls dwc2_lowlevel_hw_init() which deassert some reset > lines. > Should an error happen in dwc2_lowlevel_hw_init() after calling > reset_control_deassert() or in the probe after calling > dwc2_lowlevel_hw_init(), the reset lines remain deasserted. > > Add some devm_add_action_or_reset() calls to re-assert the lines if needed. > > Update the remove function accordingly. > > This change is compile-tested only. > > Fixes: 83f8da562f8b ("usb: dwc2: Add reset control to dwc2") > Signed-off-by: Christophe JAILLET <christophe.jaillet@xxxxxxxxxx> Acked-by: Minas Harutyunyan <Minas.Harutyunyan@xxxxxxxxxxxx> > --- > drivers/usb/dwc2/platform.c | 16 +++++++++++++--- > 1 file changed, 13 insertions(+), 3 deletions(-) > > diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c > index 5aee284018c0..5cf025511cce 100644 > --- a/drivers/usb/dwc2/platform.c > +++ b/drivers/usb/dwc2/platform.c > @@ -203,6 +203,11 @@ int dwc2_lowlevel_hw_disable(struct dwc2_hsotg *hsotg) > return ret; > } > > +static void dwc2_reset_control_assert(void *data) > +{ > + reset_control_assert(data); > +} > + > static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg) > { > int i, ret; > @@ -213,6 +218,10 @@ static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg) > "error getting reset control\n"); > > reset_control_deassert(hsotg->reset); > + ret = devm_add_action_or_reset(hsotg->dev, dwc2_reset_control_assert, > + hsotg->reset); > + if (ret) > + return ret; > > hsotg->reset_ecc = devm_reset_control_get_optional(hsotg->dev, "dwc2-ecc"); > if (IS_ERR(hsotg->reset_ecc)) > @@ -220,6 +229,10 @@ static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg) > "error getting reset control for ecc\n"); > > reset_control_deassert(hsotg->reset_ecc); > + ret = devm_add_action_or_reset(hsotg->dev, dwc2_reset_control_assert, > + hsotg->reset_ecc); > + if (ret) > + return ret; > > /* > * Attempt to find a generic PHY, then look for an old style > @@ -339,9 +352,6 @@ static int dwc2_driver_remove(struct platform_device *dev) > if (hsotg->ll_hw_enabled) > dwc2_lowlevel_hw_disable(hsotg); > > - reset_control_assert(hsotg->reset); > - reset_control_assert(hsotg->reset_ecc); > - > return 0; > } >