diff options
author | Roger Quadros <rogerq@ti.com> | 2019-10-30 08:16:07 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2019-10-30 09:39:07 -0400 |
commit | 94e259f81a714c96f381d362228fc4743db49742 (patch) | |
tree | 2a27651ca7664ffcb558861629b69df3a0ccf49b | |
parent | f5c8d290634a470600e1ce61733ec54d05a897e8 (diff) |
usb: cdns3: gadget: Fix g_audio use case when connected to Super-Speed host
Take into account gadget driver's speed limit when programming
controller speed.
Fixes: 7733f6c32e36 ("usb: cdns3: Add Cadence USB3 DRD Driver")
Signed-off-by: Roger Quadros <rogerq@ti.com>
Acked-by: Peter Chen <peter.chen@nxp.com>
Link: https://lore.kernel.org/r/20191030121607.21739-1-rogerq@ti.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/usb/cdns3/gadget.c | 31 |
1 files changed, 26 insertions, 5 deletions
diff --git a/drivers/usb/cdns3/gadget.c b/drivers/usb/cdns3/gadget.c index 8421fc028c40..4c1e75509303 100644 --- a/drivers/usb/cdns3/gadget.c +++ b/drivers/usb/cdns3/gadget.c | |||
@@ -2343,9 +2343,35 @@ static int cdns3_gadget_udc_start(struct usb_gadget *gadget, | |||
2343 | { | 2343 | { |
2344 | struct cdns3_device *priv_dev = gadget_to_cdns3_device(gadget); | 2344 | struct cdns3_device *priv_dev = gadget_to_cdns3_device(gadget); |
2345 | unsigned long flags; | 2345 | unsigned long flags; |
2346 | enum usb_device_speed max_speed = driver->max_speed; | ||
2346 | 2347 | ||
2347 | spin_lock_irqsave(&priv_dev->lock, flags); | 2348 | spin_lock_irqsave(&priv_dev->lock, flags); |
2348 | priv_dev->gadget_driver = driver; | 2349 | priv_dev->gadget_driver = driver; |
2350 | |||
2351 | /* limit speed if necessary */ | ||
2352 | max_speed = min(driver->max_speed, gadget->max_speed); | ||
2353 | |||
2354 | switch (max_speed) { | ||
2355 | case USB_SPEED_FULL: | ||
2356 | writel(USB_CONF_SFORCE_FS, &priv_dev->regs->usb_conf); | ||
2357 | writel(USB_CONF_USB3DIS, &priv_dev->regs->usb_conf); | ||
2358 | break; | ||
2359 | case USB_SPEED_HIGH: | ||
2360 | writel(USB_CONF_USB3DIS, &priv_dev->regs->usb_conf); | ||
2361 | break; | ||
2362 | case USB_SPEED_SUPER: | ||
2363 | break; | ||
2364 | default: | ||
2365 | dev_err(priv_dev->dev, | ||
2366 | "invalid maximum_speed parameter %d\n", | ||
2367 | max_speed); | ||
2368 | /* fall through */ | ||
2369 | case USB_SPEED_UNKNOWN: | ||
2370 | /* default to superspeed */ | ||
2371 | max_speed = USB_SPEED_SUPER; | ||
2372 | break; | ||
2373 | } | ||
2374 | |||
2349 | cdns3_gadget_config(priv_dev); | 2375 | cdns3_gadget_config(priv_dev); |
2350 | spin_unlock_irqrestore(&priv_dev->lock, flags); | 2376 | spin_unlock_irqrestore(&priv_dev->lock, flags); |
2351 | return 0; | 2377 | return 0; |
@@ -2575,12 +2601,7 @@ static int cdns3_gadget_start(struct cdns3 *cdns) | |||
2575 | /* Check the maximum_speed parameter */ | 2601 | /* Check the maximum_speed parameter */ |
2576 | switch (max_speed) { | 2602 | switch (max_speed) { |
2577 | case USB_SPEED_FULL: | 2603 | case USB_SPEED_FULL: |
2578 | writel(USB_CONF_SFORCE_FS, &priv_dev->regs->usb_conf); | ||
2579 | writel(USB_CONF_USB3DIS, &priv_dev->regs->usb_conf); | ||
2580 | break; | ||
2581 | case USB_SPEED_HIGH: | 2604 | case USB_SPEED_HIGH: |
2582 | writel(USB_CONF_USB3DIS, &priv_dev->regs->usb_conf); | ||
2583 | break; | ||
2584 | case USB_SPEED_SUPER: | 2605 | case USB_SPEED_SUPER: |
2585 | break; | 2606 | break; |
2586 | default: | 2607 | default: |