diff options
Diffstat (limited to 'drivers/usb/dwc2/platform.c')
| -rw-r--r-- | drivers/usb/dwc2/platform.c | 36 | 
1 files changed, 35 insertions, 1 deletions
| diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index 5f18acac7406..3024785d84cb 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -316,6 +316,39 @@ static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg)  static int dwc2_driver_remove(struct platform_device *dev)  {  	struct dwc2_hsotg *hsotg = platform_get_drvdata(dev); +	struct dwc2_gregs_backup *gr; +	int ret = 0; + +	gr = &hsotg->gr_backup; + +	/* Exit Hibernation when driver is removed. */ +	if (hsotg->hibernated) { +		if (gr->gotgctl & GOTGCTL_CURMODE_HOST) +			ret = dwc2_exit_hibernation(hsotg, 0, 0, 1); +		else +			ret = dwc2_exit_hibernation(hsotg, 0, 0, 0); + +		if (ret) +			dev_err(hsotg->dev, +				"exit hibernation failed.\n"); +	} + +	/* Exit Partial Power Down when driver is removed. */ +	if (hsotg->in_ppd) { +		ret = dwc2_exit_partial_power_down(hsotg, 0, true); +		if (ret) +			dev_err(hsotg->dev, +				"exit partial_power_down failed\n"); +	} + +	/* Exit clock gating when driver is removed. */ +	if (hsotg->params.power_down == DWC2_POWER_DOWN_PARAM_NONE && +	    hsotg->bus_suspended) { +		if (dwc2_is_device_mode(hsotg)) +			dwc2_gadget_exit_clock_gating(hsotg, 0); +		else +			dwc2_host_exit_clock_gating(hsotg, 0); +	}  	dwc2_debugfs_exit(hsotg);  	if (hsotg->hcd_enabled) @@ -334,7 +367,7 @@ static int dwc2_driver_remove(struct platform_device *dev)  	reset_control_assert(hsotg->reset);  	reset_control_assert(hsotg->reset_ecc); -	return 0; +	return ret;  }  /** @@ -734,6 +767,7 @@ static struct platform_driver dwc2_platform_driver = {  	.driver = {  		.name = dwc2_driver_name,  		.of_match_table = dwc2_of_match_table, +		.acpi_match_table = ACPI_PTR(dwc2_acpi_match),  		.pm = &dwc2_dev_pm_ops,  	},  	.probe = dwc2_driver_probe, | 
