@@ -491,12 +491,6 @@ static void dwc2_handle_usb_suspend_intr(struct dwc2_hsotg *hsotg)
hsotg->hw_params.power_optimized,
hsotg->hw_params.hibernation);
- /* Ignore suspend request before enumeration */
- if (!dwc2_is_device_connected(hsotg)) {
- dev_dbg(hsotg->dev,
- "ignore suspend request before enumeration\n");
- return;
- }
if (dsts & DSTS_SUSPSTS) {
switch (hsotg->params.power_down) {
case DWC2_POWER_DOWN_PARAM_PARTIAL:
@@ -733,21 +727,26 @@ static void dwc2_handle_gpwrdn_intr(struct dwc2_hsotg *hsotg)
}
}
}
+
if ((gpwrdn & GPWRDN_RST_DET) && (gpwrdn & GPWRDN_RST_DET_MSK)) {
dev_dbg(hsotg->dev, "%s: GPWRDN_RST_DET\n", __func__);
if (!linestate && (gpwrdn & GPWRDN_BSESSVLD))
dwc2_exit_hibernation(hsotg, 0, 1, 0);
}
+
if ((gpwrdn & GPWRDN_STS_CHGINT) &&
- (gpwrdn & GPWRDN_STS_CHGINT_MSK) && linestate) {
+ (gpwrdn & GPWRDN_STS_CHGINT_MSK)) {
dev_dbg(hsotg->dev, "%s: GPWRDN_STS_CHGINT\n", __func__);
if (hsotg->hw_params.hibernation &&
hsotg->hibernated) {
- if (gpwrdn & GPWRDN_IDSTS) {
+ if ((gpwrdn & GPWRDN_IDSTS) &
+ (hsotg->gr_backup.gpwrdn & GPWRDN_IDSTS) &&
+ linestate) {
dwc2_exit_hibernation(hsotg, 0, 0, 0);
call_gadget(hsotg, resume);
- } else {
- dwc2_exit_hibernation(hsotg, 1, 0, 1);
+ } else if (!(gpwrdn & GPWRDN_IDSTS) && !linestate) {
+ dwc2_exit_hibernation(hsotg, 1, 0, 0);
+ call_gadget(hsotg, resume);
}
}
}
@@ -5582,6 +5582,9 @@ int dwc2_host_enter_hibernation(struct dwc2_hsotg *hsotg)
gpwrdn |= GPWRDN_PWRDNSWTCH;
dwc2_writel(hsotg, gpwrdn, GPWRDN);
+ /* Save gpwrdn register for further usage if stschng interrupt */
+ hsotg->gr_backup.gpwrdn = dwc2_readl(hsotg, GPWRDN);
+
hsotg->hibernated = 1;
hsotg->bus_suspended = 1;
dev_dbg(hsotg->dev, "Host hibernation completed\n");