summaryrefslogtreecommitdiffstats
path: root/drivers/usb/dwc2/platform.c
diff options
context:
space:
mode:
authorMarek Szyprowski <m.szyprowski@samsung.com>2015-03-10 13:41:10 +0100
committerFelipe Balbi <balbi@ti.com>2015-03-12 12:18:49 -0500
commite39af88f18dfe9a7938765c97ce9ed448915e6d5 (patch)
tree88205ee3959d9fdaeda0d2e0f5824dd82516ae72 /drivers/usb/dwc2/platform.c
parent9024c495f35be735a917571406fab30a789c27d1 (diff)
downloadlinux-e39af88f18dfe9a7938765c97ce9ed448915e6d5.tar.bz2
usb: dwc2: rework initialization of host and gadget in dual-role mode
If device is configured to work only in HOST or DEVICE mode, there is no point in initializing both subdrivers. This patch also fixes resource leakage if host subdriver fails to initialize. Acked-by: John Youn <johnyoun@synopsys.com> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/dwc2/platform.c')
-rw-r--r--drivers/usb/dwc2/platform.c29
1 files changed, 21 insertions, 8 deletions
diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c
index ae095f009b4f..185663e0b5f4 100644
--- a/drivers/usb/dwc2/platform.c
+++ b/drivers/usb/dwc2/platform.c
@@ -121,8 +121,10 @@ static int dwc2_driver_remove(struct platform_device *dev)
{
struct dwc2_hsotg *hsotg = platform_get_drvdata(dev);
- dwc2_hcd_remove(hsotg);
- s3c_hsotg_remove(hsotg);
+ if (hsotg->hcd_enabled)
+ dwc2_hcd_remove(hsotg);
+ if (hsotg->gadget_enabled)
+ s3c_hsotg_remove(hsotg);
return 0;
}
@@ -234,12 +236,23 @@ static int dwc2_driver_probe(struct platform_device *dev)
spin_lock_init(&hsotg->lock);
mutex_init(&hsotg->init_mutex);
- retval = dwc2_gadget_init(hsotg, irq);
- if (retval)
- return retval;
- retval = dwc2_hcd_init(hsotg, irq, params);
- if (retval)
- return retval;
+
+ if (hsotg->dr_mode != USB_DR_MODE_HOST) {
+ retval = dwc2_gadget_init(hsotg, irq);
+ if (retval)
+ return retval;
+ hsotg->gadget_enabled = 1;
+ }
+
+ if (hsotg->dr_mode != USB_DR_MODE_PERIPHERAL) {
+ retval = dwc2_hcd_init(hsotg, irq, params);
+ if (retval) {
+ if (hsotg->gadget_enabled)
+ s3c_hsotg_remove(hsotg);
+ return retval;
+ }
+ hsotg->hcd_enabled = 1;
+ }
platform_set_drvdata(dev, hsotg);