usb: dwc2: host: Fix remote wakeup from hibernation
authorMinas Harutyunyan <Minas.Harutyunyan@synopsys.com>
Wed, 13 Mar 2024 09:21:21 +0000 (09:21 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 26 Mar 2024 13:56:20 +0000 (14:56 +0100)
Starting from core v4.30a changed order of programming
GPWRDN_PMUACTV to 0 in case of exit from hibernation on
remote wakeup signaling from device.

Fixes: c5c403dc4336 ("usb: dwc2: Add host/device hibernation functions")
CC: stable@vger.kernel.org
Signed-off-by: Minas Harutyunyan <Minas.Harutyunyan@synopsys.com>
Link: https://lore.kernel.org/r/99385ec55ce73445b6fbd0f471c9bd40eb1c9b9e.1708939799.git.Minas.Harutyunyan@synopsys.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/dwc2/core.h
drivers/usb/dwc2/hcd.c

index 40f0af171bac7b74e06e55cc08284a7071bdd813..5568448a977b1fd00b3a63d48bf57100c664295e 100644 (file)
@@ -1098,6 +1098,7 @@ struct dwc2_hsotg {
        bool needs_byte_swap;
 
        /* DWC OTG HW Release versions */
+#define DWC2_CORE_REV_4_30a    0x4f54430a
 #define DWC2_CORE_REV_2_71a    0x4f54271a
 #define DWC2_CORE_REV_2_72a     0x4f54272a
 #define DWC2_CORE_REV_2_80a    0x4f54280a
index 83d5b2548f59265ac5735d5ac3508e3351c8bc9d..6de999c7513eb7d0717e3ba8aa36bc1c6c3509f5 100644 (file)
@@ -5624,10 +5624,12 @@ int dwc2_host_exit_hibernation(struct dwc2_hsotg *hsotg, int rem_wakeup,
        dwc2_writel(hsotg, hr->hcfg, HCFG);
 
        /* De-assert Wakeup Logic */
-       gpwrdn = dwc2_readl(hsotg, GPWRDN);
-       gpwrdn &= ~GPWRDN_PMUACTV;
-       dwc2_writel(hsotg, gpwrdn, GPWRDN);
-       udelay(10);
+       if (!(rem_wakeup && hsotg->hw_params.snpsid >= DWC2_CORE_REV_4_30a)) {
+               gpwrdn = dwc2_readl(hsotg, GPWRDN);
+               gpwrdn &= ~GPWRDN_PMUACTV;
+               dwc2_writel(hsotg, gpwrdn, GPWRDN);
+               udelay(10);
+       }
 
        hprt0 = hr->hprt0;
        hprt0 |= HPRT0_PWR;
@@ -5652,6 +5654,13 @@ int dwc2_host_exit_hibernation(struct dwc2_hsotg *hsotg, int rem_wakeup,
                hprt0 |= HPRT0_RES;
                dwc2_writel(hsotg, hprt0, HPRT0);
 
+               /* De-assert Wakeup Logic */
+               if ((rem_wakeup && hsotg->hw_params.snpsid >= DWC2_CORE_REV_4_30a)) {
+                       gpwrdn = dwc2_readl(hsotg, GPWRDN);
+                       gpwrdn &= ~GPWRDN_PMUACTV;
+                       dwc2_writel(hsotg, gpwrdn, GPWRDN);
+                       udelay(10);
+               }
                /* Wait for Resume time and then program HPRT again */
                mdelay(100);
                hprt0 &= ~HPRT0_RES;