diff options
Diffstat (limited to 'drivers/usb/chipidea/udc.c')
| -rw-r--r-- | drivers/usb/chipidea/udc.c | 32 | 
1 files changed, 32 insertions, 0 deletions
diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index 8c3e3a635ac2..54c09245ad05 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -2181,6 +2181,34 @@ static void udc_id_switch_for_host(struct ci_hdrc *ci)  				     ci->platdata->pins_default);  } +#ifdef CONFIG_PM_SLEEP +static void udc_suspend(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); +} + +static void udc_resume(struct ci_hdrc *ci, bool power_lost) +{ +	if (power_lost) { +		if (ci->is_otg) +			hw_write_otgsc(ci, OTGSC_BSVIS | OTGSC_BSVIE, +					OTGSC_BSVIS | OTGSC_BSVIE); +		if (ci->vbus_active) +			usb_gadget_vbus_disconnect(&ci->gadget); +	} + +	/* Restore value 0 if it was set for power lost check */ +	if (hw_read(ci, OP_ENDPTLISTADDR, ~0) == 0xFFFFFFFF) +		hw_write(ci, OP_ENDPTLISTADDR, ~0, 0); +} +#endif +  /**   * ci_hdrc_gadget_init - initialize device related bits   * @ci: the controller @@ -2201,6 +2229,10 @@ int ci_hdrc_gadget_init(struct ci_hdrc *ci)  	rdrv->start	= udc_id_switch_for_device;  	rdrv->stop	= udc_id_switch_for_host; +#ifdef CONFIG_PM_SLEEP +	rdrv->suspend	= udc_suspend; +	rdrv->resume	= udc_resume; +#endif  	rdrv->irq	= udc_irq;  	rdrv->name	= "gadget";  |