Message ID | c64537b5339342bd00f7c2152b8fc23792b9f95a.1683306479.git.christophe.jaillet@wanadoo.fr (mailing list archive) |
---|---|
State | Accepted |
Commit | ada050c69108bc34be13ecc11f7fad0f20ebadc4 |
Headers | show |
Series | usb: dwc2: Fix some error handling paths | expand |
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@wanadoo.fr> Acked-by: Minas Harutyunyan <Minas.Harutyunyan@synopsys.com> > --- > 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; > } >
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; }
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@wanadoo.fr> --- drivers/usb/dwc2/platform.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-)