From: Li Jun Date: Thu, 15 Jan 2015 12:49:36 +0000 (+0800) Subject: MLK-10102-5 usb: chipidea: udc: support resume udc from power lost X-Git-Tag: C0P2-H0.0--20200415~4720 X-Git-Url: https://git.somdevices.com/?a=commitdiff_plain;h=70776369238c49f7736a703a59d505842aa05453;p=linux.git MLK-10102-5 usb: chipidea: udc: support resume udc from power lost This patch implements the suspend and resume routine for udc resume from power lost. Acked-by: Peter Chen Signed-off-by: Li Jun (cherry picked from commit a1389afb0c70d4024e07ff9634f10eba559af374) (cherry picked from commit 733d0547c2cc90299b35b1b0d34073838ffcf6d9) --- diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index caf2a733a335..959fa196040f 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -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);