aboutsummaryrefslogtreecommitdiff
path: root/drivers/usb/dwc3/ep0.c
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-03-02 15:56:33 -0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-03-02 15:56:33 -0800
commit3d71769014c55e05b2342b6d9c1464f7fb383322 (patch)
treeb85909f3f949e070bbba86976f81966f180a837c /drivers/usb/dwc3/ep0.c
parentcd70469d084fde198dc07c1a31b8463562228a5a (diff)
parentc2df85ca31645ed3c68c56bd30a3673e034224f1 (diff)
Merge tag 'dwc3-for-v3.4' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb into usb-next
usb: dwc3: changes for v3.4 merge window Here are the changes for v3.4 merge window. It includes a new glue layer for Samsung's Exynos platform, a simplification of memory management on DWC3 driver by using dev_xxx functions, a few optimizations to IRQ handling by dropping memcpy() and using bitshifts, a fix for TI's OMAP5430 TX Fifo Allocation, two fixes on USB2 test mode implementation (one on debugfs and one on ep0), and several minor changes such as whitespace cleanups, simplification of a few parts of the code, decreasing a long delay to something a bit saner, dropping a header which was included twice and so on. The highlight on this merge is the support for Samsung's Exynos platform, increasing the number of different users for this driver to three. Note that Samsung Exynos glue layer will only compile on platforms which provide implementation for the clk API for now. Once Samsung supports pm_runtime, that limitation can be dropped from the Makefile. Conflicts: drivers/usb/dwc3/gadget.c
Diffstat (limited to 'drivers/usb/dwc3/ep0.c')
-rw-r--r--drivers/usb/dwc3/ep0.c82
1 files changed, 41 insertions, 41 deletions
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
index d5c568e91874..25910e251c04 100644
--- a/drivers/usb/dwc3/ep0.c
+++ b/drivers/usb/dwc3/ep0.c
@@ -76,8 +76,7 @@ static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma,
u32 len, u32 type)
{
struct dwc3_gadget_ep_cmd_params params;
- struct dwc3_trb_hw *trb_hw;
- struct dwc3_trb trb;
+ struct dwc3_trb *trb;
struct dwc3_ep *dep;
int ret;
@@ -88,19 +87,17 @@ static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma,
return 0;
}
- trb_hw = dwc->ep0_trb;
- memset(&trb, 0, sizeof(trb));
+ trb = dwc->ep0_trb;
- trb.trbctl = type;
- trb.bplh = buf_dma;
- trb.length = len;
+ trb->bpl = lower_32_bits(buf_dma);
+ trb->bph = upper_32_bits(buf_dma);
+ trb->size = len;
+ trb->ctrl = type;
- trb.hwo = 1;
- trb.lst = 1;
- trb.ioc = 1;
- trb.isp_imi = 1;
-
- dwc3_trb_to_hw(&trb, trb_hw);
+ trb->ctrl |= (DWC3_TRB_CTRL_HWO
+ | DWC3_TRB_CTRL_LST
+ | DWC3_TRB_CTRL_IOC
+ | DWC3_TRB_CTRL_ISP_IMI);
memset(&params, 0, sizeof(params));
params.param0 = upper_32_bits(dwc->ep0_trb_addr);
@@ -315,9 +312,7 @@ static int dwc3_ep0_handle_feature(struct dwc3 *dwc,
u32 recip;
u32 wValue;
u32 wIndex;
- u32 reg;
int ret;
- u32 mode;
wValue = le16_to_cpu(ctrl->wValue);
wIndex = le16_to_cpu(ctrl->wIndex);
@@ -356,25 +351,8 @@ static int dwc3_ep0_handle_feature(struct dwc3 *dwc,
if (!set)
return -EINVAL;
- mode = wIndex >> 8;
- reg = dwc3_readl(dwc->regs, DWC3_DCTL);
- reg &= ~DWC3_DCTL_TSTCTRL_MASK;
-
- switch (mode) {
- case TEST_J:
- case TEST_K:
- case TEST_SE0_NAK:
- case TEST_PACKET:
- case TEST_FORCE_EN:
- reg |= mode << 1;
- break;
- default:
- return -EINVAL;
- }
- dwc3_writel(dwc->regs, DWC3_DCTL, reg);
- break;
- default:
- return -EINVAL;
+ dwc->test_mode_nr = wIndex >> 8;
+ dwc->test_mode = true;
}
break;
@@ -396,7 +374,7 @@ static int dwc3_ep0_handle_feature(struct dwc3 *dwc,
case USB_RECIP_ENDPOINT:
switch (wValue) {
case USB_ENDPOINT_HALT:
- dep = dwc3_wIndex_to_dep(dwc, wIndex);
+ dep = dwc3_wIndex_to_dep(dwc, wIndex);
if (!dep)
return -EINVAL;
ret = __dwc3_gadget_ep_set_halt(dep, set);
@@ -470,8 +448,11 @@ static int dwc3_ep0_set_config(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
case DWC3_ADDRESS_STATE:
ret = dwc3_ep0_delegate_req(dwc, ctrl);
/* if the cfg matches and the cfg is non zero */
- if (!ret && cfg)
+ if (cfg && (!ret || (ret == USB_GADGET_DELAYED_STATUS))) {
dwc->dev_state = DWC3_CONFIGURED_STATE;
+ dwc->resize_fifos = true;
+ dev_dbg(dwc->dev, "resize fifos flag SET\n");
+ }
break;
case DWC3_CONFIGURED_STATE:
@@ -560,9 +541,10 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc,
{
struct dwc3_request *r = NULL;
struct usb_request *ur;
- struct dwc3_trb trb;
+ struct dwc3_trb *trb;
struct dwc3_ep *ep0;
u32 transferred;
+ u32 length;
u8 epnum;
epnum = event->endpoint_number;
@@ -573,16 +555,16 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc,
r = next_request(&ep0->request_list);
ur = &r->request;
- dwc3_trb_to_nat(dwc->ep0_trb, &trb);
+ trb = dwc->ep0_trb;
+ length = trb->size & DWC3_TRB_SIZE_MASK;
if (dwc->ep0_bounced) {
-
transferred = min_t(u32, ur->length,
- ep0->endpoint.maxpacket - trb.length);
+ ep0->endpoint.maxpacket - length);
memcpy(ur->buf, dwc->ep0_bounce, transferred);
dwc->ep0_bounced = false;
} else {
- transferred = ur->length - trb.length;
+ transferred = ur->length - length;
ur->actual += transferred;
}
@@ -614,6 +596,17 @@ static void dwc3_ep0_complete_req(struct dwc3 *dwc,
dwc3_gadget_giveback(dep, r, 0);
}
+ if (dwc->test_mode) {
+ int ret;
+
+ ret = dwc3_gadget_set_test_mode(dwc, dwc->test_mode_nr);
+ if (ret < 0) {
+ dev_dbg(dwc->dev, "Invalid Test #%d\n",
+ dwc->test_mode_nr);
+ dwc3_ep0_stall_and_restart(dwc);
+ }
+ }
+
dwc->ep0state = EP0_SETUP_PHASE;
dwc3_ep0_out_start(dwc);
}
@@ -624,6 +617,7 @@ static void dwc3_ep0_xfer_complete(struct dwc3 *dwc,
struct dwc3_ep *dep = dwc->eps[event->endpoint_number];
dep->flags &= ~DWC3_EP_BUSY;
+ dep->res_trans_idx = 0;
dwc->setup_packet_pending = false;
switch (dwc->ep0state) {
@@ -730,6 +724,12 @@ static void dwc3_ep0_do_control_status(struct dwc3 *dwc, u32 epnum)
{
struct dwc3_ep *dep = dwc->eps[epnum];
+ if (dwc->resize_fifos) {
+ dev_dbg(dwc->dev, "starting to resize fifos\n");
+ dwc3_gadget_resize_tx_fifos(dwc);
+ dwc->resize_fifos = 0;
+ }
+
WARN_ON(dwc3_ep0_start_control_status(dep));
}