MLK-10102-5 usb: chipidea: udc: support resume udc from power lost
authorLi Jun <jun.li@freescale.com>
Thu, 15 Jan 2015 12:49:36 +0000 (20:49 +0800)
committerNitin Garg <nitin.garg@nxp.com>
Mon, 19 Mar 2018 19:46:58 +0000 (14:46 -0500)
This patch implements the suspend and resume routine for udc resume
from power lost.

Acked-by: Peter Chen <peter.chen@freescale.com>
Signed-off-by: Li Jun <b47624@freescale.com>
(cherry picked from commit a1389afb0c70d4024e07ff9634f10eba559af374)
(cherry picked from commit 733d0547c2cc90299b35b1b0d34073838ffcf6d9)

drivers/usb/chipidea/udc.c

index caf2a73..959fa19 100644 (file)
@@ -2027,6 +2027,40 @@ static void udc_id_switch_for_host(struct ci_hdrc *ci)
                hw_write_otgsc(ci, OTGSC_BSVIE | OTGSC_BSVIS, OTGSC_BSVIS);
 }
 
+static void udc_suspend_for_power_lost(struct ci_hdrc *ci)
+{
+       /*
+        * Set OP_ENDPTLISTADDR to be non-zero for
+        * checking if controller resume from power lost
+        * in non-host mode.
+        */
+       if (hw_read(ci, OP_ENDPTLISTADDR, ~0) == 0)
+               hw_write(ci, OP_ENDPTLISTADDR, ~0, ~0);
+}
+
+/* Power lost with device mode */
+static void udc_resume_from_power_lost(struct ci_hdrc *ci)
+{
+       /* Force disconnect if power lost with vbus on */
+       if (!ci_otg_is_fsm_mode(ci) && ci->vbus_active)
+               usb_gadget_vbus_disconnect(&ci->gadget);
+
+       if (ci->is_otg)
+               hw_write_otgsc(ci, OTGSC_BSVIS | OTGSC_BSVIE,
+                                       OTGSC_BSVIS | OTGSC_BSVIE);
+}
+
+static void udc_suspend(struct ci_hdrc *ci)
+{
+       udc_suspend_for_power_lost(ci);
+}
+
+static void udc_resume(struct ci_hdrc *ci, bool power_lost)
+{
+       if (power_lost)
+               udc_resume_from_power_lost(ci);
+}
+
 /**
  * ci_hdrc_gadget_init - initialize device related bits
  * ci: the controller
@@ -2048,6 +2082,8 @@ int ci_hdrc_gadget_init(struct ci_hdrc *ci)
        rdrv->start     = udc_id_switch_for_device;
        rdrv->stop      = udc_id_switch_for_host;
        rdrv->irq       = udc_irq;
+       rdrv->suspend   = udc_suspend;
+       rdrv->resume    = udc_resume;
        rdrv->name      = "gadget";
 
        ret = udc_start(ci);