summaryrefslogtreecommitdiff
path: root/drivers/usb/dwc2
diff options
context:
space:
mode:
authorMarek Szyprowski <m.szyprowski@samsung.com>2015-03-10 12:41:10 (GMT)
committerFelipe Balbi <balbi@ti.com>2015-03-12 17:18:49 (GMT)
commite39af88f18dfe9a7938765c97ce9ed448915e6d5 (patch)
tree88205ee3959d9fdaeda0d2e0f5824dd82516ae72 /drivers/usb/dwc2
parent9024c495f35be735a917571406fab30a789c27d1 (diff)
downloadlinux-e39af88f18dfe9a7938765c97ce9ed448915e6d5.tar.xz
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')
-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 f74304b..836c012 100644
--- a/drivers/usb/dwc2/core.h
+++ b/drivers/usb/dwc2/core.h
@@ -593,6 +593,8 @@ struct dwc2_hsotg {
struct dwc2_core_params *core_params;
enum usb_otg_state op_state;
enum usb_dr_mode dr_mode;
+ unsigned int hcd_enabled:1;
+ unsigned int gadget_enabled:1;
struct phy *phy;
struct usb_phy *uphy;
diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c
index ae095f0..185663e 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);