diff options
author | Sebastian Andrzej Siewior <bigeasy@linutronix.de> | 2013-10-15 12:29:22 -0400 |
---|---|---|
committer | Felipe Balbi <balbi@ti.com> | 2013-10-17 10:55:03 -0400 |
commit | ae44df2e21b50f9fff28ac75c57e399c04df812c (patch) | |
tree | d87431c6159128a25ef4f405b597d4eeafb1841e | |
parent | 811f33033f9e6a00756e38990d82214c8c619f4c (diff) |
usb: musb: call musb_start() only once in OTG mode
In commit 001dd84 ("usb: musb: start musb on the udc side, too") it was
ensured that the state engine is started also in OTG mode after a
removal / insertion of the gadget.
Unfortunately this change also introduced a bug: If the device is
configured as OTG and it connected with a remote host _without_ loading
a gadget then we bug() later (because musb->otg->gadget is not
initialized).
Initially I assumed it might be nice to have the host part of musb in
OTG mode working without having a gadget loaded. This bug and fact that
it wasn't working like this before the host/gadget split made me realize
that this was a silly idea.
This patch now introduces back the old behavior where in OTG mode the
host mode is only working after the gadget has been loaded.
Cc: stable@vger.kernel.org # v3.11
Cc: Daniel Mack <zonque@gmail.com>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Felipe Balbi <balbi@ti.com>
-rw-r--r-- | drivers/usb/musb/musb_virthub.c | 19 |
1 files changed, 18 insertions, 1 deletions
diff --git a/drivers/usb/musb/musb_virthub.c b/drivers/usb/musb/musb_virthub.c index a523950c2b32..d8bbdb366beb 100644 --- a/drivers/usb/musb/musb_virthub.c +++ b/drivers/usb/musb/musb_virthub.c | |||
@@ -266,6 +266,23 @@ int musb_hub_status_data(struct usb_hcd *hcd, char *buf) | |||
266 | return retval; | 266 | return retval; |
267 | } | 267 | } |
268 | 268 | ||
269 | static int musb_has_gadget(struct musb *musb) | ||
270 | { | ||
271 | /* | ||
272 | * In host-only mode we start a connection right away. In OTG mode | ||
273 | * we have to wait until we loaded a gadget. We don't really need a | ||
274 | * gadget if we operate as a host but we should not start a session | ||
275 | * as a device without a gadget or else we explode. | ||
276 | */ | ||
277 | #ifdef CONFIG_USB_MUSB_HOST | ||
278 | return 1; | ||
279 | #else | ||
280 | if (musb->port_mode == MUSB_PORT_MODE_HOST) | ||
281 | return 1; | ||
282 | return musb->g.dev.driver != NULL; | ||
283 | #endif | ||
284 | } | ||
285 | |||
269 | int musb_hub_control( | 286 | int musb_hub_control( |
270 | struct usb_hcd *hcd, | 287 | struct usb_hcd *hcd, |
271 | u16 typeReq, | 288 | u16 typeReq, |
@@ -408,7 +425,7 @@ int musb_hub_control( | |||
408 | * initialization logic, e.g. for OTG, or change any | 425 | * initialization logic, e.g. for OTG, or change any |
409 | * logic relating to VBUS power-up. | 426 | * logic relating to VBUS power-up. |
410 | */ | 427 | */ |
411 | if (!hcd->self.is_b_host) | 428 | if (!hcd->self.is_b_host && musb_has_gadget(musb)) |
412 | musb_start(musb); | 429 | musb_start(musb); |
413 | break; | 430 | break; |
414 | case USB_PORT_FEAT_RESET: | 431 | case USB_PORT_FEAT_RESET: |