usb: dwc2: gadget: Fix exiting from clock gating
authorMinas Harutyunyan <Minas.Harutyunyan@synopsys.com>
Wed, 13 Mar 2024 09:22:01 +0000 (09:22 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 26 Mar 2024 13:56:25 +0000 (14:56 +0100)
Added exiting from the clock gating mode on USB Reset Detect interrupt
if core in the clock gating mode.
Added new condition to check core in clock gating mode or no.

Fixes: 9b4965d77e11 ("usb: dwc2: Add exit clock gating from session request interrupt")
Fixes: 5d240efddc7f ("usb: dwc2: Add exit clock gating from wakeup interrupt")
Fixes: 16c729f90bdf ("usb: dwc2: Allow exit clock gating in urb enqueue")
Fixes: 401411bbc4e6 ("usb: dwc2: Add exit clock gating before removing driver")
CC: stable@vger.kernel.org
Signed-off-by: Minas Harutyunyan <Minas.Harutyunyan@synopsys.com>
Link: https://lore.kernel.org/r/cbcc2ccd37e89e339130797ed68ae4597db773ac.1708938774.git.Minas.Harutyunyan@synopsys.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/dwc2/core_intr.c
drivers/usb/dwc2/gadget.c
drivers/usb/dwc2/hcd.c
drivers/usb/dwc2/platform.c

index 158ede7538548e4d6daba4fc08d543f434b3ec6d..f8426e3d2b19bc9742e46f66b7c7c9bd6af33a69 100644 (file)
@@ -297,7 +297,8 @@ static void dwc2_handle_session_req_intr(struct dwc2_hsotg *hsotg)
 
                        /* Exit gadget mode clock gating. */
                        if (hsotg->params.power_down ==
-                           DWC2_POWER_DOWN_PARAM_NONE && hsotg->bus_suspended)
+                           DWC2_POWER_DOWN_PARAM_NONE && hsotg->bus_suspended &&
+                           !hsotg->params.no_clock_gating)
                                dwc2_gadget_exit_clock_gating(hsotg, 0);
                }
 
@@ -408,7 +409,8 @@ static void dwc2_handle_wakeup_detected_intr(struct dwc2_hsotg *hsotg)
 
                        /* Exit gadget mode clock gating. */
                        if (hsotg->params.power_down ==
-                           DWC2_POWER_DOWN_PARAM_NONE && hsotg->bus_suspended)
+                           DWC2_POWER_DOWN_PARAM_NONE && hsotg->bus_suspended &&
+                           !hsotg->params.no_clock_gating)
                                dwc2_gadget_exit_clock_gating(hsotg, 0);
                } else {
                        /* Change to L0 state */
@@ -425,7 +427,8 @@ static void dwc2_handle_wakeup_detected_intr(struct dwc2_hsotg *hsotg)
                        }
 
                        if (hsotg->params.power_down ==
-                           DWC2_POWER_DOWN_PARAM_NONE && hsotg->bus_suspended)
+                           DWC2_POWER_DOWN_PARAM_NONE && hsotg->bus_suspended &&
+                           !hsotg->params.no_clock_gating)
                                dwc2_host_exit_clock_gating(hsotg, 1);
 
                        /*
index b517a7216de22ae420405ae7ceae2fd04f74f2b3..8d3d937c81f9edfa7b17a7c1b29003f5ecb07e25 100644 (file)
@@ -3727,6 +3727,12 @@ irq_retry:
                if (hsotg->in_ppd && hsotg->lx_state == DWC2_L2)
                        dwc2_exit_partial_power_down(hsotg, 0, true);
 
+               /* Exit gadget mode clock gating. */
+               if (hsotg->params.power_down ==
+                   DWC2_POWER_DOWN_PARAM_NONE && hsotg->bus_suspended &&
+                   !hsotg->params.no_clock_gating)
+                       dwc2_gadget_exit_clock_gating(hsotg, 0);
+
                hsotg->lx_state = DWC2_L0;
        }
 
index 70b389125f63560308dee3213f36e25e425f6f9e..dd5b1c5691e11efa8e9300a289a32839e9212300 100644 (file)
@@ -4657,7 +4657,7 @@ static int _dwc2_hcd_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
        }
 
        if (hsotg->params.power_down == DWC2_POWER_DOWN_PARAM_NONE &&
-           hsotg->bus_suspended) {
+           hsotg->bus_suspended && !hsotg->params.no_clock_gating) {
                if (dwc2_is_device_mode(hsotg))
                        dwc2_gadget_exit_clock_gating(hsotg, 0);
                else
index b1d48019e944f3ea4166aa748d2053a4ea4312dc..7b84416dfc2b11eca6e4c9699571bb6379cce150 100644 (file)
@@ -331,7 +331,7 @@ static void dwc2_driver_remove(struct platform_device *dev)
 
        /* Exit clock gating when driver is removed. */
        if (hsotg->params.power_down == DWC2_POWER_DOWN_PARAM_NONE &&
-           hsotg->bus_suspended) {
+           hsotg->bus_suspended && !hsotg->params.no_clock_gating) {
                if (dwc2_is_device_mode(hsotg))
                        dwc2_gadget_exit_clock_gating(hsotg, 0);
                else