usb: cdns3: Enable TDL_CHK only for OUT ep
authorSanket Parmar <sparmar@cadence.com>
Mon, 17 May 2021 15:05:12 +0000 (17:05 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 25 Jul 2021 12:36:18 +0000 (14:36 +0200)
commit d6eef886903c4bb5af41b9a31d4ba11dc7a6f8e8 upstream.

ZLP gets stuck if TDL_CHK bit is set and TDL_FROM_TRB is used
as TDL source for IN endpoints. To fix it, TDL_CHK is only
enabled for OUT endpoints.

Fixes: 7733f6c32e36 ("usb: cdns3: Add Cadence USB3 DRD Driver")
Reported-by: Aswath Govindraju <a-govindraju@ti.com>
Signed-off-by: Sanket Parmar <sparmar@cadence.com>
Link: https://lore.kernel.org/r/1621263912-13175-1-git-send-email-sparmar@cadence.com
Signed-off-by: Peter Chen <peter.chen@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/cdns3/gadget.c

index c24c0e3..9d38f86 100644 (file)
@@ -2006,7 +2006,7 @@ static void cdns3_configure_dmult(struct cdns3_device *priv_dev,
                else
                        mask = BIT(priv_ep->num);
 
-               if (priv_ep->type != USB_ENDPOINT_XFER_ISOC) {
+               if (priv_ep->type != USB_ENDPOINT_XFER_ISOC  && !priv_ep->dir) {
                        cdns3_set_register_bit(&regs->tdl_from_trb, mask);
                        cdns3_set_register_bit(&regs->tdl_beh, mask);
                        cdns3_set_register_bit(&regs->tdl_beh2, mask);
@@ -2045,15 +2045,13 @@ int cdns3_ep_config(struct cdns3_endpoint *priv_ep, bool enable)
        case USB_ENDPOINT_XFER_INT:
                ep_cfg = EP_CFG_EPTYPE(USB_ENDPOINT_XFER_INT);
 
-               if ((priv_dev->dev_ver == DEV_VER_V2 && !priv_ep->dir) ||
-                   priv_dev->dev_ver > DEV_VER_V2)
+               if (priv_dev->dev_ver >= DEV_VER_V2 && !priv_ep->dir)
                        ep_cfg |= EP_CFG_TDL_CHK;
                break;
        case USB_ENDPOINT_XFER_BULK:
                ep_cfg = EP_CFG_EPTYPE(USB_ENDPOINT_XFER_BULK);
 
-               if ((priv_dev->dev_ver == DEV_VER_V2  && !priv_ep->dir) ||
-                   priv_dev->dev_ver > DEV_VER_V2)
+               if (priv_dev->dev_ver >= DEV_VER_V2 && !priv_ep->dir)
                        ep_cfg |= EP_CFG_TDL_CHK;
                break;
        default: