Skip to content

Commit

Permalink
drivers/usb: Add dcache flush(VIC7100 ONLY)
Browse files Browse the repository at this point in the history
drivers/usb/cdns3/
drivers/usb/core/
drivers/usb/host/
include/linux/usb.h

Geert: Rebase to v5.13-rc1
Stafford: Don't flush NULL values

Signed-off-by: Stafford Horne <[email protected]>
  • Loading branch information
Tom authored and esmil committed Jun 13, 2021
1 parent 7a144b2 commit 6bdd39b
Show file tree
Hide file tree
Showing 17 changed files with 1,209 additions and 50 deletions.
3 changes: 3 additions & 0 deletions drivers/usb/cdns3/cdns3-debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,9 @@ static inline char *cdns3_dbg_ring(struct cdns3_endpoint *priv_ep,
le32_to_cpu(trb->buffer),
le32_to_cpu(trb->length),
le32_to_cpu(trb->control));
#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
cdns_virt_flush_dcache(trb, sizeof(struct cdns3_trb));
#endif
addr += sizeof(*trb);
}

Expand Down
129 changes: 117 additions & 12 deletions drivers/usb/cdns3/cdns3-ep0.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ static void cdns3_ep0_run_transfer(struct cdns3_device *priv_dev,
priv_ep->trb_pool[1].control = 0;
}

#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
cdns_flush_dcache(EP_TRADDR_TRADDR(priv_ep->trb_pool_dma),
2 * TRB_SIZE);
#endif

trace_cdns3_prepare_trb(priv_ep, priv_ep->trb_pool);

cdns3_select_ep(priv_dev, priv_dev->ep0_data_dir);
Expand Down Expand Up @@ -88,6 +93,9 @@ static int cdns3_ep0_delegate_req(struct cdns3_device *priv_dev,
spin_unlock(&priv_dev->lock);
priv_dev->setup_pending = 1;
ret = priv_dev->gadget_driver->setup(&priv_dev->gadget, ctrl_req);
#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
cdns_virt_flush_dcache(ctrl_req, sizeof(struct usb_ctrlrequest));
#endif
priv_dev->setup_pending = 0;
spin_lock(&priv_dev->lock);
return ret;
Expand All @@ -97,6 +105,12 @@ static void cdns3_prepare_setup_packet(struct cdns3_device *priv_dev)
{
priv_dev->ep0_data_dir = 0;
priv_dev->ep0_stage = CDNS3_SETUP_STAGE;

#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
gadget_flush_dcache(priv_dev->setup_dma,
sizeof(struct usb_ctrlrequest));
#endif

cdns3_ep0_run_transfer(priv_dev, priv_dev->setup_dma,
sizeof(struct usb_ctrlrequest), 0, 0);
}
Expand Down Expand Up @@ -140,6 +154,9 @@ static int cdns3_req_ep0_set_configuration(struct cdns3_device *priv_dev,
u32 config = le16_to_cpu(ctrl_req->wValue);
int result = 0;

#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
cdns_virt_flush_dcache(ctrl_req, sizeof(struct usb_ctrlrequest));
#endif
switch (device_state) {
case USB_STATE_ADDRESS:
result = cdns3_ep0_delegate_req(priv_dev, ctrl_req);
Expand Down Expand Up @@ -185,7 +202,9 @@ static int cdns3_req_ep0_set_address(struct cdns3_device *priv_dev,
u32 addr;

addr = le16_to_cpu(ctrl_req->wValue);

#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
cdns_virt_flush_dcache(ctrl_req, sizeof(struct usb_ctrlrequest));
#endif
if (addr > USB_DEVICE_MAX_ADDRESS) {
dev_err(priv_dev->dev,
"Device address (%d) cannot be greater than %d\n",
Expand Down Expand Up @@ -225,9 +244,14 @@ static int cdns3_req_ep0_get_status(struct cdns3_device *priv_dev,
u16 usb_status = 0;
u32 recip;
u8 index;
#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
u32 tmp_ind;
#endif

recip = ctrl->bRequestType & USB_RECIP_MASK;

#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
cdns_virt_flush_dcache(ctrl, sizeof(struct usb_ctrlrequest));
#endif
switch (recip) {
case USB_RECIP_DEVICE:
/* self powered */
Expand All @@ -253,8 +277,17 @@ static int cdns3_req_ep0_get_status(struct cdns3_device *priv_dev,
index = cdns3_ep_addr_to_index(le16_to_cpu(ctrl->wIndex));
priv_ep = priv_dev->eps[index];

#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
tmp_ind = ctrl->wIndex;
cdns_virt_flush_dcache(ctrl, sizeof(struct usb_ctrlrequest));

/* check if endpoint is stalled or stall is pending */
cdns3_select_ep(priv_dev, tmp_ind);
#else

/* check if endpoint is stalled or stall is pending */
cdns3_select_ep(priv_dev, le16_to_cpu(ctrl->wIndex));
#endif
if (EP_STS_STALL(readl(&priv_dev->regs->ep_sts)) ||
(priv_ep->flags & EP_STALL_PENDING))
usb_status = BIT(USB_ENDPOINT_HALT);
Expand All @@ -266,6 +299,10 @@ static int cdns3_req_ep0_get_status(struct cdns3_device *priv_dev,
response_pkt = (__le16 *)priv_dev->setup_buf;
*response_pkt = cpu_to_le16(usb_status);

#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
cdns_flush_dcache(priv_dev->setup_dma, sizeof(*response_pkt));
#endif

cdns3_ep0_run_transfer(priv_dev, priv_dev->setup_dma,
sizeof(*response_pkt), 1, 0);
return 0;
Expand All @@ -282,6 +319,9 @@ static int cdns3_ep0_feature_handle_device(struct cdns3_device *priv_dev,
u16 tmode;

wValue = le16_to_cpu(ctrl->wValue);
#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
cdns_virt_flush_dcache(ctrl, sizeof(struct usb_ctrlrequest));
#endif
state = priv_dev->gadget.state;
speed = priv_dev->gadget.speed;

Expand Down Expand Up @@ -309,7 +349,9 @@ static int cdns3_ep0_feature_handle_device(struct cdns3_device *priv_dev,
return -EINVAL;

tmode = le16_to_cpu(ctrl->wIndex);

#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
cdns_virt_flush_dcache(ctrl, sizeof(struct usb_ctrlrequest));
#endif
if (!set || (tmode & 0xff) != 0)
return -EINVAL;

Expand Down Expand Up @@ -342,7 +384,9 @@ static int cdns3_ep0_feature_handle_intf(struct cdns3_device *priv_dev,
int ret = 0;

wValue = le16_to_cpu(ctrl->wValue);

#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
cdns_virt_flush_dcache(ctrl, sizeof(struct usb_ctrlrequest));
#endif
switch (wValue) {
case USB_INTRF_FUNC_SUSPEND:
break;
Expand All @@ -360,17 +404,38 @@ static int cdns3_ep0_feature_handle_endpoint(struct cdns3_device *priv_dev,
struct cdns3_endpoint *priv_ep;
int ret = 0;
u8 index;

if (le16_to_cpu(ctrl->wValue) != USB_ENDPOINT_HALT)
#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
u32 tmp_ind;
#endif

if (le16_to_cpu(ctrl->wValue) != USB_ENDPOINT_HALT) {
#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
cdns_virt_flush_dcache(ctrl, sizeof(struct usb_ctrlrequest));
#endif
return -EINVAL;
}

if (!(le16_to_cpu(ctrl->wIndex) & ~USB_DIR_IN))
if (!(le16_to_cpu(ctrl->wIndex) & ~USB_DIR_IN)) {
#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
cdns_virt_flush_dcache(ctrl, sizeof(struct usb_ctrlrequest));
#endif
return 0;
}

#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
cdns_virt_flush_dcache(ctrl, sizeof(struct usb_ctrlrequest));
#endif

index = cdns3_ep_addr_to_index(le16_to_cpu(ctrl->wIndex));
priv_ep = priv_dev->eps[index];

#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
tmp_ind = ctrl->wIndex;
cdns_virt_flush_dcache(ctrl, sizeof(struct usb_ctrlrequest));
cdns3_select_ep(priv_dev, tmp_ind);
#else
cdns3_select_ep(priv_dev, le16_to_cpu(ctrl->wIndex));
#endif

if (set)
__cdns3_gadget_ep_set_halt(priv_ep);
Expand Down Expand Up @@ -400,7 +465,9 @@ static int cdns3_req_ep0_handle_feature(struct cdns3_device *priv_dev,
u32 recip;

recip = ctrl->bRequestType & USB_RECIP_MASK;

#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
cdns_virt_flush_dcache(ctrl, sizeof(struct usb_ctrlrequest));
#endif
switch (recip) {
case USB_RECIP_DEVICE:
ret = cdns3_ep0_feature_handle_device(priv_dev, ctrl, set);
Expand Down Expand Up @@ -434,9 +501,17 @@ static int cdns3_req_ep0_set_sel(struct cdns3_device *priv_dev,
if (le16_to_cpu(ctrl_req->wLength) != 6) {
dev_err(priv_dev->dev, "Set SEL should be 6 bytes, got %d\n",
ctrl_req->wLength);
#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
cdns_virt_flush_dcache(ctrl_req, sizeof(struct usb_ctrlrequest));
#endif
return -EINVAL;
}

#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
cdns_virt_flush_dcache(ctrl_req, sizeof(struct usb_ctrlrequest));
cdns_flush_dcache(priv_dev->setup_dma, 6);
#endif

cdns3_ep0_run_transfer(priv_dev, priv_dev->setup_dma, 6, 1, 0);
return 0;
}
Expand All @@ -452,11 +527,19 @@ static int cdns3_req_ep0_set_sel(struct cdns3_device *priv_dev,
static int cdns3_req_ep0_set_isoch_delay(struct cdns3_device *priv_dev,
struct usb_ctrlrequest *ctrl_req)
{
if (ctrl_req->wIndex || ctrl_req->wLength)
if (ctrl_req->wIndex || ctrl_req->wLength) {
#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
cdns_virt_flush_dcache(ctrl_req, sizeof(struct usb_ctrlrequest));
#endif
return -EINVAL;
}

priv_dev->isoch_delay = le16_to_cpu(ctrl_req->wValue);

#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
cdns_virt_flush_dcache(ctrl_req, sizeof(struct usb_ctrlrequest));
#endif

return 0;
}

Expand All @@ -472,7 +555,13 @@ static int cdns3_ep0_standard_request(struct cdns3_device *priv_dev,
{
int ret;

#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
u8 bReq = ctrl_req->bRequest;
cdns_virt_flush_dcache(ctrl_req, sizeof(struct usb_ctrlrequest));
switch (bReq) {
#else
switch (ctrl_req->bRequest) {
#endif
case USB_REQ_SET_ADDRESS:
ret = cdns3_req_ep0_set_address(priv_dev, ctrl_req);
break;
Expand Down Expand Up @@ -535,7 +624,9 @@ static void cdns3_ep0_setup_phase(struct cdns3_device *priv_dev)
int result;

priv_dev->ep0_data_dir = ctrl->bRequestType & USB_DIR_IN;

#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
cdns_virt_flush_dcache(ctrl, sizeof(struct usb_ctrlrequest));
#endif
trace_cdns3_ctrl_req(ctrl);

if (!list_empty(&priv_ep->pending_req_list)) {
Expand All @@ -552,10 +643,17 @@ static void cdns3_ep0_setup_phase(struct cdns3_device *priv_dev)
else
priv_dev->ep0_stage = CDNS3_STATUS_STAGE;

if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD)
if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) {
#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
cdns_virt_flush_dcache(ctrl, sizeof(struct usb_ctrlrequest));
#endif
result = cdns3_ep0_standard_request(priv_dev, ctrl);
else
} else {
#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
cdns_virt_flush_dcache(ctrl, sizeof(struct usb_ctrlrequest));
#endif
result = cdns3_ep0_delegate_req(priv_dev, ctrl);
}

if (result == USB_GADGET_DELAYED_STATUS)
return;
Expand All @@ -579,6 +677,10 @@ static void cdns3_transfer_completed(struct cdns3_device *priv_dev)
request->actual =
TRB_LEN(le32_to_cpu(priv_ep->trb_pool->length));

#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
cdns_flush_dcache(EP_TRADDR_TRADDR(priv_ep->trb_pool_dma),
sizeof(struct cdns3_trb));
#endif
priv_ep->dir = priv_dev->ep0_data_dir;
cdns3_gadget_giveback(priv_ep, to_cdns3_request(request), 0);
}
Expand Down Expand Up @@ -764,6 +866,9 @@ static int cdns3_gadget_ep0_queue(struct usb_ep *ep,
(request->length % ep->maxpacket == 0))
zlp = 1;

#ifdef CONFIG_USB_CDNS3_HOST_FLUSH_DMA
gadget_flush_dcache(request->dma, request->length);
#endif
cdns3_ep0_run_transfer(priv_dev, request->dma, request->length, 1, zlp);

spin_unlock_irqrestore(&priv_dev->lock, flags);
Expand Down
Loading

0 comments on commit 6bdd39b

Please sign in to comment.