aboutsummaryrefslogtreecommitdiff
path: root/drivers/usb/cdns3
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/cdns3')
-rw-r--r--drivers/usb/cdns3/core.c29
-rw-r--r--drivers/usb/cdns3/gadget.c27
2 files changed, 31 insertions, 25 deletions
diff --git a/drivers/usb/cdns3/core.c b/drivers/usb/cdns3/core.c
index a0f73d4711ae..039ab5d2435e 100644
--- a/drivers/usb/cdns3/core.c
+++ b/drivers/usb/cdns3/core.c
@@ -427,7 +427,6 @@ static irqreturn_t cdns3_wakeup_irq(int irq, void *data)
*/
static int cdns3_probe(struct platform_device *pdev)
{
- struct usb_role_switch_desc sw_desc = { };
struct device *dev = &pdev->dev;
struct resource *res;
struct cdns3 *cdns;
@@ -529,18 +528,21 @@ static int cdns3_probe(struct platform_device *pdev)
if (ret)
goto err2;
- sw_desc.set = cdns3_role_set;
- sw_desc.get = cdns3_role_get;
- sw_desc.allow_userspace_control = true;
- sw_desc.driver_data = cdns;
- if (device_property_read_bool(dev, "usb-role-switch"))
+ if (device_property_read_bool(dev, "usb-role-switch")) {
+ struct usb_role_switch_desc sw_desc = { };
+
+ sw_desc.set = cdns3_role_set;
+ sw_desc.get = cdns3_role_get;
+ sw_desc.allow_userspace_control = true;
+ sw_desc.driver_data = cdns;
sw_desc.fwnode = dev->fwnode;
- cdns->role_sw = usb_role_switch_register(dev, &sw_desc);
- if (IS_ERR(cdns->role_sw)) {
- ret = PTR_ERR(cdns->role_sw);
- dev_warn(dev, "Unable to register Role Switch\n");
- goto err3;
+ cdns->role_sw = usb_role_switch_register(dev, &sw_desc);
+ if (IS_ERR(cdns->role_sw)) {
+ ret = PTR_ERR(cdns->role_sw);
+ dev_warn(dev, "Unable to register Role Switch\n");
+ goto err3;
+ }
}
if (cdns->wakeup_irq) {
@@ -551,7 +553,7 @@ static int cdns3_probe(struct platform_device *pdev)
if (ret) {
dev_err(cdns->dev, "couldn't register wakeup irq handler\n");
- goto err3;
+ goto err4;
}
}
@@ -582,7 +584,8 @@ static int cdns3_probe(struct platform_device *pdev)
return 0;
err4:
cdns3_drd_exit(cdns);
- usb_role_switch_unregister(cdns->role_sw);
+ if (cdns->role_sw)
+ usb_role_switch_unregister(cdns->role_sw);
err3:
set_phy_power_off(cdns);
err2:
diff --git a/drivers/usb/cdns3/gadget.c b/drivers/usb/cdns3/gadget.c
index 66c1e6723eb1..0aa85cc07ff1 100644
--- a/drivers/usb/cdns3/gadget.c
+++ b/drivers/usb/cdns3/gadget.c
@@ -1114,7 +1114,7 @@ static int cdns3_ep_run_transfer(struct cdns3_endpoint *priv_ep,
struct cdns3_device *priv_dev = priv_ep->cdns3_dev;
struct cdns3_request *priv_req;
struct cdns3_trb *trb;
- struct cdns3_trb *link_trb;
+ struct cdns3_trb *link_trb = NULL;
dma_addr_t trb_dma;
u32 togle_pcs = 1;
int sg_iter = 0;
@@ -1193,10 +1193,20 @@ static int cdns3_ep_run_transfer(struct cdns3_endpoint *priv_ep,
/* set incorrect Cycle Bit for first trb*/
control = priv_ep->pcs ? 0 : TRB_CYCLE;
+ trb->length = 0;
+ if (priv_dev->dev_ver >= DEV_VER_V2) {
+ u16 td_size;
+
+ td_size = DIV_ROUND_UP(request->length,
+ priv_ep->endpoint.maxpacket);
+ if (priv_dev->gadget.speed == USB_SPEED_SUPER)
+ trb->length = TRB_TDL_SS_SIZE(td_size);
+ else
+ control |= TRB_TDL_HS_SIZE(td_size);
+ }
do {
u32 length;
- u16 td_size = 0;
/* fill TRB */
control |= TRB_TYPE(TRB_NORMAL);
@@ -1208,20 +1218,12 @@ static int cdns3_ep_run_transfer(struct cdns3_endpoint *priv_ep,
length = request->length;
}
- if (likely(priv_dev->dev_ver >= DEV_VER_V2))
- td_size = DIV_ROUND_UP(length,
- priv_ep->endpoint.maxpacket);
- else if (priv_ep->flags & EP_TDLCHK_EN)
+ if (priv_ep->flags & EP_TDLCHK_EN)
total_tdl += DIV_ROUND_UP(length,
priv_ep->endpoint.maxpacket);
- trb->length = cpu_to_le32(TRB_BURST_LEN(priv_ep->trb_burst_size) |
+ trb->length |= cpu_to_le32(TRB_BURST_LEN(priv_ep->trb_burst_size) |
TRB_LEN(length));
- if (priv_dev->gadget.speed == USB_SPEED_SUPER)
- trb->length |= cpu_to_le32(TRB_TDL_SS_SIZE(td_size));
- else
- control |= TRB_TDL_HS_SIZE(td_size);
-
pcs = priv_ep->pcs ? TRB_CYCLE : 0;
/*
@@ -1258,6 +1260,7 @@ static int cdns3_ep_run_transfer(struct cdns3_endpoint *priv_ep,
priv_req->end_trb = priv_ep->enqueue;
cdns3_ep_inc_enq(priv_ep);
trb = priv_ep->trb_pool + priv_ep->enqueue;
+ trb->length = 0;
} while (sg_iter < num_trb);
trb = priv_req->trb;