This is a note to let you know that I've just added the patch titled usb: dwc2: Fix some error handling paths to the 5.15-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: usb-dwc2-fix-some-error-handling-paths.patch and it can be found in the queue-5.15 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. commit 0d342324626a067e042bbdb0294568706ad2b4f1 Author: Christophe JAILLET <christophe.jaillet@xxxxxxxxxx> Date: Fri May 5 19:15:08 2023 +0200 usb: dwc2: Fix some error handling paths [ Upstream commit ada050c69108bc34be13ecc11f7fad0f20ebadc4 ] 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> Link: https://lore.kernel.org/r/c64537b5339342bd00f7c2152b8fc23792b9f95a.1683306479.git.christophe.jaillet@xxxxxxxxxx Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx> diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index ad8c7de4bfb19..6496bfbd34ed9 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -205,6 +205,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; @@ -217,6 +222,10 @@ static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg) } 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)) { @@ -226,6 +235,10 @@ static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg) } 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 @@ -352,9 +365,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; }