musb_writel(base, USBC_REG_o_ISCR, reg_val);
 }
 
+static void USBC_ForceVbusValidToLow(__iomem void *base)
+{
+       u32 reg_val;
+
+       reg_val = musb_readl(base, USBC_REG_o_ISCR);
+       reg_val &= ~(0x03 << USBC_BP_ISCR_FORCE_VBUS_VALID);
+       reg_val |= (0x02 << USBC_BP_ISCR_FORCE_VBUS_VALID);
+       reg_val = USBC_WakeUp_ClearChangeDetect(reg_val);
+       musb_writel(base, USBC_REG_o_ISCR, reg_val);
+}
+
 static void USBC_ForceVbusValidToHigh(__iomem void *base)
 {
        u32 reg_val;
        return retval;
 }
 
+/* musb_core does not call enable / disable in a balanced manner <sigh> */
+static bool enabled = false;
+
 static void sunxi_musb_enable(struct musb *musb)
 {
        pr_debug("%s():\n", __func__);
 
+       if (enabled)
+               return;
+
        /* select PIO mode */
        musb_writeb(musb->mregs, USBC_REG_o_VEND0, 0);
 
-       if (is_host_enabled(musb)) {
-               /* port power on */
-               sunxi_usb_phy_power_on(0);
-       }
+       if (is_host_enabled(musb))
+               sunxi_usb_phy_power_on(0); /* port power on */
+
+       USBC_ForceVbusValidToHigh(musb->mregs);
+
+       enabled = true;
 }
 
 static void sunxi_musb_disable(struct musb *musb)
 {
-       struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
-
        pr_debug("%s():\n", __func__);
 
-       /* Put the controller back in a pristane state for "usb reset" */
-       if (musb->is_active) {
-               sunxi_usb_phy_exit(0);
-#ifdef CONFIG_SUNXI_GEN_SUN6I
-               clrbits_le32(&ccm->ahb_reset0_cfg, 1 << AHB_GATE_OFFSET_USB0);
-#endif
-               clrbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_USB0);
+       if (!enabled)
+               return;
 
-               mdelay(10);
+       if (is_host_enabled(musb))
+               sunxi_usb_phy_power_off(0); /* port power off */
 
-               setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_USB0);
-#ifdef CONFIG_SUNXI_GEN_SUN6I
-               setbits_le32(&ccm->ahb_reset0_cfg, 1 << AHB_GATE_OFFSET_USB0);
-#endif
-               sunxi_usb_phy_init(0);
-               musb->is_active = 0;
-       }
+       USBC_ForceVbusValidToLow(musb->mregs);
+       mdelay(200); /* Wait for the current session to timeout */
+
+       enabled = false;
 }
 
 static int sunxi_musb_init(struct musb *musb)