aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarek Szyprowski <m.szyprowski@samsung.com>2015-03-10 08:41:10 -0400
committerFelipe Balbi <balbi@ti.com>2015-03-12 13:18:49 -0400
commite39af88f18dfe9a7938765c97ce9ed448915e6d5 (patch)
tree88205ee3959d9fdaeda0d2e0f5824dd82516ae72
parent9024c495f35be735a917571406fab30a789c27d1 (diff)
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>
-rw-r--r--drivers/usb/dwc2/core.h2
-rw-r--r--drivers/usb/dwc2/platform.c29
2 files changed, 23 insertions, 8 deletions
diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h
index f74304b12652..836c012c7707 100644
--- a/drivers/usb/dwc2/core.h
+++ b/drivers/usb/dwc2/core.h
@@ -593,6 +593,8 @@ struct dwc2_hsotg {
593 struct dwc2_core_params *core_params; 593 struct dwc2_core_params *core_params;
594 enum usb_otg_state op_state; 594 enum usb_otg_state op_state;
595 enum usb_dr_mode dr_mode; 595 enum usb_dr_mode dr_mode;
596 unsigned int hcd_enabled:1;
597 unsigned int gadget_enabled:1;
596 598
597 struct phy *phy; 599 struct phy *phy;
598 struct usb_phy *uphy; 600 struct usb_phy *uphy;
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)
121{ 121{
122 struct dwc2_hsotg *hsotg = platform_get_drvdata(dev); 122 struct dwc2_hsotg *hsotg = platform_get_drvdata(dev);
123 123
124 dwc2_hcd_remove(hsotg); 124 if (hsotg->hcd_enabled)
125 s3c_hsotg_remove(hsotg); 125 dwc2_hcd_remove(hsotg);
126 if (hsotg->gadget_enabled)
127 s3c_hsotg_remove(hsotg);
126 128
127 return 0; 129 return 0;
128} 130}
@@ -234,12 +236,23 @@ static int dwc2_driver_probe(struct platform_device *dev)
234 236
235 spin_lock_init(&hsotg->lock); 237 spin_lock_init(&hsotg->lock);
236 mutex_init(&hsotg->init_mutex); 238 mutex_init(&hsotg->init_mutex);
237 retval = dwc2_gadget_init(hsotg, irq); 239
238 if (retval) 240 if (hsotg->dr_mode != USB_DR_MODE_HOST) {
239 return retval; 241 retval = dwc2_gadget_init(hsotg, irq);
240 retval = dwc2_hcd_init(hsotg, irq, params); 242 if (retval)
241 if (retval) 243 return retval;
242 return retval; 244 hsotg->gadget_enabled = 1;
245 }
246
247 if (hsotg->dr_mode != USB_DR_MODE_PERIPHERAL) {
248 retval = dwc2_hcd_init(hsotg, irq, params);
249 if (retval) {
250 if (hsotg->gadget_enabled)
251 s3c_hsotg_remove(hsotg);
252 return retval;
253 }
254 hsotg->hcd_enabled = 1;
255 }
243 256
244 platform_set_drvdata(dev, hsotg); 257 platform_set_drvdata(dev, hsotg);
245 258