unsigned long flags;
        int ret = 0;
        u32 hprt0;
+       u32 pcgctl;
 
        spin_lock_irqsave(&hsotg->lock, flags);
 
        if (hsotg->op_state == OTG_STATE_B_PERIPHERAL)
                goto unlock;
 
-       if (hsotg->params.power_down != DWC2_POWER_DOWN_PARAM_PARTIAL)
+       if (hsotg->params.power_down > DWC2_POWER_DOWN_PARAM_PARTIAL)
                goto skip_power_saving;
 
        /*
         */
        if (!hsotg->bus_suspended) {
                hprt0 = dwc2_read_hprt0(hsotg);
-               hprt0 |= HPRT0_SUSP;
-               hprt0 &= ~HPRT0_PWR;
-               dwc2_writel(hsotg, hprt0, HPRT0);
-               spin_unlock_irqrestore(&hsotg->lock, flags);
-               dwc2_vbus_supply_exit(hsotg);
-               spin_lock_irqsave(&hsotg->lock, flags);
+               if (hprt0 & HPRT0_CONNSTS) {
+                       hprt0 |= HPRT0_SUSP;
+                       if (hsotg->params.power_down == DWC2_POWER_DOWN_PARAM_PARTIAL)
+                               hprt0 &= ~HPRT0_PWR;
+                       dwc2_writel(hsotg, hprt0, HPRT0);
+               }
+               if (hsotg->params.power_down == DWC2_POWER_DOWN_PARAM_PARTIAL) {
+                       spin_unlock_irqrestore(&hsotg->lock, flags);
+                       dwc2_vbus_supply_exit(hsotg);
+                       spin_lock_irqsave(&hsotg->lock, flags);
+               } else {
+                       pcgctl = readl(hsotg->regs + PCGCTL);
+                       pcgctl |= PCGCTL_STOPPCLK;
+                       writel(pcgctl, hsotg->regs + PCGCTL);
+               }
        }
 
-       /* Enter partial_power_down */
-       ret = dwc2_enter_partial_power_down(hsotg);
-       if (ret) {
-               if (ret != -ENOTSUPP)
-                       dev_err(hsotg->dev,
-                               "enter partial_power_down failed\n");
-               goto skip_power_saving;
+       if (hsotg->params.power_down == DWC2_POWER_DOWN_PARAM_PARTIAL) {
+               /* Enter partial_power_down */
+               ret = dwc2_enter_partial_power_down(hsotg);
+               if (ret) {
+                       if (ret != -ENOTSUPP)
+                               dev_err(hsotg->dev,
+                                       "enter partial_power_down failed\n");
+                       goto skip_power_saving;
+               }
+
+               /* After entering partial_power_down, hardware is no more accessible */
+               clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
        }
 
        /* Ask phy to be suspended */
                spin_lock_irqsave(&hsotg->lock, flags);
        }
 
-       /* After entering partial_power_down, hardware is no more accessible */
-       clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
-
 skip_power_saving:
        hsotg->lx_state = DWC2_L2;
 unlock:
 {
        struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd);
        unsigned long flags;
+       u32 pcgctl;
        int ret = 0;
 
        spin_lock_irqsave(&hsotg->lock, flags);
        if (hsotg->lx_state != DWC2_L2)
                goto unlock;
 
-       if (hsotg->params.power_down != DWC2_POWER_DOWN_PARAM_PARTIAL) {
+       if (hsotg->params.power_down > DWC2_POWER_DOWN_PARAM_PARTIAL) {
                hsotg->lx_state = DWC2_L0;
                goto unlock;
        }
 
-       /*
-        * Set HW accessible bit before powering on the controller
-        * since an interrupt may rise.
-        */
-       set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
-
        /*
         * Enable power if not already done.
         * This must not be spinlocked since duration
                spin_lock_irqsave(&hsotg->lock, flags);
        }
 
-       /* Exit partial_power_down */
-       ret = dwc2_exit_partial_power_down(hsotg, true);
-       if (ret && (ret != -ENOTSUPP))
-               dev_err(hsotg->dev, "exit partial_power_down failed\n");
+       if (hsotg->params.power_down == DWC2_POWER_DOWN_PARAM_PARTIAL) {
+               /*
+                * Set HW accessible bit before powering on the controller
+                * since an interrupt may rise.
+                */
+               set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
+
+
+               /* Exit partial_power_down */
+               ret = dwc2_exit_partial_power_down(hsotg, true);
+               if (ret && (ret != -ENOTSUPP))
+                       dev_err(hsotg->dev, "exit partial_power_down failed\n");
+       } else {
+               pcgctl = readl(hsotg->regs + PCGCTL);
+               pcgctl &= ~PCGCTL_STOPPCLK;
+               writel(pcgctl, hsotg->regs + PCGCTL);
+       }
 
        hsotg->lx_state = DWC2_L0;
 
                spin_unlock_irqrestore(&hsotg->lock, flags);
                dwc2_port_resume(hsotg);
        } else {
-               dwc2_vbus_supply_init(hsotg);
+               if (hsotg->params.power_down == DWC2_POWER_DOWN_PARAM_PARTIAL) {
+                       dwc2_vbus_supply_init(hsotg);
 
-               /* Wait for controller to correctly update D+/D- level */
-               usleep_range(3000, 5000);
+                       /* Wait for controller to correctly update D+/D- level */
+                       usleep_range(3000, 5000);
+               }
 
                /*
                 * Clear Port Enable and Port Status changes.