summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNick Hudson2013-12-06 23:01:44 +0100
committerGreg Kroah-Hartman2013-12-09 02:25:14 +0100
commit9f8144c6ed8f04984ee372a060ad75d228d2b9f0 (patch)
treee8670a5824dd2e024cc964a0c92fa0f555e31636
parentimx-drm: Add mx6 hdmi transmitter support (diff)
downloadkernel-qcow2-linux-9f8144c6ed8f04984ee372a060ad75d228d2b9f0.tar.gz
kernel-qcow2-linux-9f8144c6ed8f04984ee372a060ad75d228d2b9f0.tar.xz
kernel-qcow2-linux-9f8144c6ed8f04984ee372a060ad75d228d2b9f0.zip
staging: dwc2: don't issue traffic to LS devices in FS mode
I fell over the problem reported in https://github.com/raspberrypi/linux/pull/390: "Issuing low-speed packets when the root port is in full-speed mode causes the root port to stop responding. Explicitly fail when enqueuing URBs to a LS endpoint on a FS bus." with my dwc2 testing in NetBSD, so I adapted the change to dwc2. Signed-off-by: Nick Hudson <skrll@netbsd.org> [paulz: fixed up the patch to compile under Linux, and tested it] Signed-off-by: Paul Zimmerman <paulz@synopsys.com> Tested-by: Stephen Warren <swarren@wwwdotorg.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/staging/dwc2/hcd.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/drivers/staging/dwc2/hcd.c b/drivers/staging/dwc2/hcd.c
index 24b57d7952c5..07dfe855dc20 100644
--- a/drivers/staging/dwc2/hcd.c
+++ b/drivers/staging/dwc2/hcd.c
@@ -355,6 +355,7 @@ static int dwc2_hcd_urb_enqueue(struct dwc2_hsotg *hsotg,
unsigned long flags;
u32 intr_mask;
int retval;
+ int dev_speed;
if (!hsotg->flags.b.port_connect_status) {
/* No longer connected */
@@ -362,6 +363,19 @@ static int dwc2_hcd_urb_enqueue(struct dwc2_hsotg *hsotg,
return -ENODEV;
}
+ dev_speed = dwc2_host_get_speed(hsotg, urb->priv);
+
+ /* Some configurations cannot support LS traffic on a FS root port */
+ if ((dev_speed == USB_SPEED_LOW) &&
+ (hsotg->hw_params.fs_phy_type == GHWCFG2_FS_PHY_TYPE_DEDICATED) &&
+ (hsotg->hw_params.hs_phy_type == GHWCFG2_HS_PHY_TYPE_UTMI)) {
+ u32 hprt0 = readl(hsotg->regs + HPRT0);
+ u32 prtspd = (hprt0 & HPRT0_SPD_MASK) >> HPRT0_SPD_SHIFT;
+
+ if (prtspd == HPRT0_SPD_FULL_SPEED)
+ return -ENODEV;
+ }
+
qtd = kzalloc(sizeof(*qtd), mem_flags);
if (!qtd)
return -ENOMEM;