[PATCH 6.12.y-cip v2 09/17] usb: host: ehci-platform: Call reset assert/deassert on suspend/resume
Claudiu Beznea <[email protected]> Wed, 8 Jul 2026 11:12:29 +0300
| Newsgroups | org.cip-project.lists.cip-dev |
|---|---|
| Message-ID | <[email protected]> |
From: Claudiu Beznea <[email protected]> commit c31a401fe7abedabb5c05b5cbf36e2fdb3e6be63 upstream. The Renesas RZ/G3S SoC supports a power-saving mode in which power to most of the SoC components is turned off, including the USB blocks. On the resume path, the reset signal must be de-asserted before applying any settings to the USB registers. To handle this properly, call reset_control_assert() and reset_control_deassert() during suspend and resume, respectively. Signed-off-by: Claudiu Beznea <[email protected]> Acked-by: Alan Stern <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]> [claudiu.beznea: execute the code based on the ehci_platform_reset_control_allowed() return value] Signed-off-by: Claudiu Beznea <[email protected]> --- Changes in v2: - added ehci_platform_reset_control_allowed() and use it in suspend/resume path to avoid executing code introduced by commit c31a401fe7abedabb5c05b5cbf36e2fdb3e6be63 on targets other than the Renesas RZ/G3S drivers/usb/host/ehci-platform.c | 39 ++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c index cca129c70276..1b85fd01cb2b 100644 --- a/drivers/usb/host/ehci-platform.c +++ b/drivers/usb/host/ehci-platform.c @@ -424,6 +424,16 @@ static void ehci_platform_remove(struct platform_device *dev) dev->dev.platform_data = NULL; } +static bool __maybe_unused ehci_platform_reset_control_allowed(void) +{ + static const char * const reset_control_allow_list[] = { + "renesas,r9a08g045", /* Renesas RZ/G3S */ + NULL + }; + + return of_machine_compatible_match(reset_control_allow_list); +} + static int __maybe_unused ehci_platform_suspend(struct device *dev) { struct usb_hcd *hcd = dev_get_drvdata(dev); @@ -443,6 +453,20 @@ static int __maybe_unused ehci_platform_suspend(struct device *dev) if (pdata->power_suspend) pdata->power_suspend(pdev); + if (!ehci_platform_reset_control_allowed()) + return ret; + + ret = reset_control_assert(priv->rsts); + if (ret) { + if (pdata->power_on) + pdata->power_on(pdev); + + ehci_resume(hcd, false); + + if (priv->quirk_poll) + quirk_poll_init(priv); + } + return ret; } @@ -452,12 +476,23 @@ static int __maybe_unused ehci_platform_resume(struct device *dev) struct usb_ehci_pdata *pdata = dev_get_platdata(dev); struct platform_device *pdev = to_platform_device(dev); struct ehci_platform_priv *priv = hcd_to_ehci_priv(hcd); + bool reset_control_allowed = ehci_platform_reset_control_allowed(); struct device *companion_dev; + int err; + + if (reset_control_allowed) { + err = reset_control_deassert(priv->rsts); + if (err) + return err; + } if (pdata->power_on) { - int err = pdata->power_on(pdev); - if (err < 0) + err = pdata->power_on(pdev); + if (err < 0) { + if (reset_control_allowed) + reset_control_assert(priv->rsts); return err; + } } companion_dev = usb_of_get_companion_dev(hcd->self.controller); -- 2.43.0