Merge tag 'usb-for-v4.13' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb into usb-testing
Felipe writes: usb: changes for v4.13 merge window This time around we have a total of 57 non-merge commits. A list of most important changes follows: - Improvements to dwc3 tracing interface - Initial dual-role support for dwc3 - Improvements to how we handle DMA resources in dwc3 - A new f_uac1 implementation which much more flexible - Removal of AVR32 bits - Improvements to f_mass_storage driver
Šī revīzija ir iekļauta:
@@ -1,4 +1,4 @@
|
||||
/**
|
||||
/*
|
||||
* gadget.c - DesignWare USB3 DRD Controller Gadget Framework Link
|
||||
*
|
||||
* Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com
|
||||
@@ -36,13 +36,12 @@
|
||||
#include "io.h"
|
||||
|
||||
/**
|
||||
* dwc3_gadget_set_test_mode - Enables USB2 Test Modes
|
||||
* dwc3_gadget_set_test_mode - enables usb2 test modes
|
||||
* @dwc: pointer to our context structure
|
||||
* @mode: the mode to set (J, K SE0 NAK, Force Enable)
|
||||
*
|
||||
* Caller should take care of locking. This function will
|
||||
* return 0 on success or -EINVAL if wrong Test Selector
|
||||
* is passed
|
||||
* Caller should take care of locking. This function will return 0 on
|
||||
* success or -EINVAL if wrong Test Selector is passed.
|
||||
*/
|
||||
int dwc3_gadget_set_test_mode(struct dwc3 *dwc, int mode)
|
||||
{
|
||||
@@ -69,7 +68,7 @@ int dwc3_gadget_set_test_mode(struct dwc3 *dwc, int mode)
|
||||
}
|
||||
|
||||
/**
|
||||
* dwc3_gadget_get_link_state - Gets current state of USB Link
|
||||
* dwc3_gadget_get_link_state - gets current state of usb link
|
||||
* @dwc: pointer to our context structure
|
||||
*
|
||||
* Caller should take care of locking. This function will
|
||||
@@ -85,7 +84,7 @@ int dwc3_gadget_get_link_state(struct dwc3 *dwc)
|
||||
}
|
||||
|
||||
/**
|
||||
* dwc3_gadget_set_link_state - Sets USB Link to a particular State
|
||||
* dwc3_gadget_set_link_state - sets usb link to a particular state
|
||||
* @dwc: pointer to our context structure
|
||||
* @state: the state to put link into
|
||||
*
|
||||
@@ -143,8 +142,8 @@ int dwc3_gadget_set_link_state(struct dwc3 *dwc, enum dwc3_link_state state)
|
||||
}
|
||||
|
||||
/**
|
||||
* dwc3_ep_inc_trb() - Increment a TRB index.
|
||||
* @index - Pointer to the TRB index to increment.
|
||||
* dwc3_ep_inc_trb - increment a trb index.
|
||||
* @index: Pointer to the TRB index to increment.
|
||||
*
|
||||
* The index should never point to the link TRB. After incrementing,
|
||||
* if it is point to the link TRB, wrap around to the beginning. The
|
||||
@@ -157,16 +156,34 @@ static void dwc3_ep_inc_trb(u8 *index)
|
||||
*index = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* dwc3_ep_inc_enq - increment endpoint's enqueue pointer
|
||||
* @dep: The endpoint whose enqueue pointer we're incrementing
|
||||
*/
|
||||
static void dwc3_ep_inc_enq(struct dwc3_ep *dep)
|
||||
{
|
||||
dwc3_ep_inc_trb(&dep->trb_enqueue);
|
||||
}
|
||||
|
||||
/**
|
||||
* dwc3_ep_inc_deq - increment endpoint's dequeue pointer
|
||||
* @dep: The endpoint whose enqueue pointer we're incrementing
|
||||
*/
|
||||
static void dwc3_ep_inc_deq(struct dwc3_ep *dep)
|
||||
{
|
||||
dwc3_ep_inc_trb(&dep->trb_dequeue);
|
||||
}
|
||||
|
||||
/**
|
||||
* dwc3_gadget_giveback - call struct usb_request's ->complete callback
|
||||
* @dep: The endpoint to whom the request belongs to
|
||||
* @req: The request we're giving back
|
||||
* @status: completion code for the request
|
||||
*
|
||||
* Must be called with controller's lock held and interrupts disabled. This
|
||||
* function will unmap @req and call its ->complete() callback to notify upper
|
||||
* layers that it has completed.
|
||||
*/
|
||||
void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
|
||||
int status)
|
||||
{
|
||||
@@ -193,6 +210,15 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
|
||||
pm_runtime_put(dwc->dev);
|
||||
}
|
||||
|
||||
/**
|
||||
* dwc3_send_gadget_generic_command - issue a generic command for the controller
|
||||
* @dwc: pointer to the controller context
|
||||
* @cmd: the command to be issued
|
||||
* @param: command parameter
|
||||
*
|
||||
* Caller should take care of locking. Issue @cmd with a given @param to @dwc
|
||||
* and wait for its completion.
|
||||
*/
|
||||
int dwc3_send_gadget_generic_command(struct dwc3 *dwc, unsigned cmd, u32 param)
|
||||
{
|
||||
u32 timeout = 500;
|
||||
@@ -225,6 +251,15 @@ int dwc3_send_gadget_generic_command(struct dwc3 *dwc, unsigned cmd, u32 param)
|
||||
|
||||
static int __dwc3_gadget_wakeup(struct dwc3 *dwc);
|
||||
|
||||
/**
|
||||
* dwc3_send_gadget_ep_cmd - issue an endpoint command
|
||||
* @dep: the endpoint to which the command is going to be issued
|
||||
* @cmd: the command to be issued
|
||||
* @params: parameters to the command
|
||||
*
|
||||
* Caller should handle locking. This function will issue @cmd with given
|
||||
* @params to @dep and wait for its completion.
|
||||
*/
|
||||
int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned cmd,
|
||||
struct dwc3_gadget_ep_cmd_params *params)
|
||||
{
|
||||
@@ -422,36 +457,38 @@ static void dwc3_free_trb_pool(struct dwc3_ep *dep)
|
||||
static int dwc3_gadget_set_xfer_resource(struct dwc3 *dwc, struct dwc3_ep *dep);
|
||||
|
||||
/**
|
||||
* dwc3_gadget_start_config - Configure EP resources
|
||||
* dwc3_gadget_start_config - configure ep resources
|
||||
* @dwc: pointer to our controller context structure
|
||||
* @dep: endpoint that is being enabled
|
||||
*
|
||||
* The assignment of transfer resources cannot perfectly follow the
|
||||
* data book due to the fact that the controller driver does not have
|
||||
* all knowledge of the configuration in advance. It is given this
|
||||
* information piecemeal by the composite gadget framework after every
|
||||
* SET_CONFIGURATION and SET_INTERFACE. Trying to follow the databook
|
||||
* programming model in this scenario can cause errors. For two
|
||||
* reasons:
|
||||
* Issue a %DWC3_DEPCMD_DEPSTARTCFG command to @dep. After the command's
|
||||
* completion, it will set Transfer Resource for all available endpoints.
|
||||
*
|
||||
* 1) The databook says to do DEPSTARTCFG for every SET_CONFIGURATION
|
||||
* and SET_INTERFACE (8.1.5). This is incorrect in the scenario of
|
||||
* multiple interfaces.
|
||||
* The assignment of transfer resources cannot perfectly follow the data book
|
||||
* due to the fact that the controller driver does not have all knowledge of the
|
||||
* configuration in advance. It is given this information piecemeal by the
|
||||
* composite gadget framework after every SET_CONFIGURATION and
|
||||
* SET_INTERFACE. Trying to follow the databook programming model in this
|
||||
* scenario can cause errors. For two reasons:
|
||||
*
|
||||
* 2) The databook does not mention doing more DEPXFERCFG for new
|
||||
* 1) The databook says to do %DWC3_DEPCMD_DEPSTARTCFG for every
|
||||
* %USB_REQ_SET_CONFIGURATION and %USB_REQ_SET_INTERFACE (8.1.5). This is
|
||||
* incorrect in the scenario of multiple interfaces.
|
||||
*
|
||||
* 2) The databook does not mention doing more %DWC3_DEPCMD_DEPXFERCFG for new
|
||||
* endpoint on alt setting (8.1.6).
|
||||
*
|
||||
* The following simplified method is used instead:
|
||||
*
|
||||
* All hardware endpoints can be assigned a transfer resource and this
|
||||
* setting will stay persistent until either a core reset or
|
||||
* hibernation. So whenever we do a DEPSTARTCFG(0) we can go ahead and
|
||||
* do DEPXFERCFG for every hardware endpoint as well. We are
|
||||
* All hardware endpoints can be assigned a transfer resource and this setting
|
||||
* will stay persistent until either a core reset or hibernation. So whenever we
|
||||
* do a %DWC3_DEPCMD_DEPSTARTCFG(0) we can go ahead and do
|
||||
* %DWC3_DEPCMD_DEPXFERCFG for every hardware endpoint as well. We are
|
||||
* guaranteed that there are as many transfer resources as endpoints.
|
||||
*
|
||||
* This function is called for each endpoint when it is being enabled
|
||||
* but is triggered only when called for EP0-out, which always happens
|
||||
* first, and which should only happen in one of the above conditions.
|
||||
* This function is called for each endpoint when it is being enabled but is
|
||||
* triggered only when called for EP0-out, which always happens first, and which
|
||||
* should only happen in one of the above conditions.
|
||||
*/
|
||||
static int dwc3_gadget_start_config(struct dwc3 *dwc, struct dwc3_ep *dep)
|
||||
{
|
||||
@@ -569,11 +606,13 @@ static int dwc3_gadget_set_xfer_resource(struct dwc3 *dwc, struct dwc3_ep *dep)
|
||||
}
|
||||
|
||||
/**
|
||||
* __dwc3_gadget_ep_enable - Initializes a HW endpoint
|
||||
* __dwc3_gadget_ep_enable - initializes a hw endpoint
|
||||
* @dep: endpoint to be initialized
|
||||
* @desc: USB Endpoint Descriptor
|
||||
* @modify: if true, modify existing endpoint configuration
|
||||
* @restore: if true, restore endpoint configuration from scratch buffer
|
||||
*
|
||||
* Caller should take care of locking
|
||||
* Caller should take care of locking. Execute all necessary commands to
|
||||
* initialize a HW endpoint so it can be used by a gadget driver.
|
||||
*/
|
||||
static int __dwc3_gadget_ep_enable(struct dwc3_ep *dep,
|
||||
bool modify, bool restore)
|
||||
@@ -685,11 +724,13 @@ static void dwc3_remove_requests(struct dwc3 *dwc, struct dwc3_ep *dep)
|
||||
}
|
||||
|
||||
/**
|
||||
* __dwc3_gadget_ep_disable - Disables a HW endpoint
|
||||
* __dwc3_gadget_ep_disable - disables a hw endpoint
|
||||
* @dep: the endpoint to disable
|
||||
*
|
||||
* This function also removes requests which are currently processed ny the
|
||||
* hardware and those which are not yet scheduled.
|
||||
* This function undoes what __dwc3_gadget_ep_enable did and also removes
|
||||
* requests which are currently being processed by the hardware and those which
|
||||
* are not yet scheduled.
|
||||
*
|
||||
* Caller should take care of locking.
|
||||
*/
|
||||
static int __dwc3_gadget_ep_disable(struct dwc3_ep *dep)
|
||||
@@ -932,7 +973,7 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep,
|
||||
}
|
||||
|
||||
/**
|
||||
* dwc3_ep_prev_trb() - Returns the previous TRB in the ring
|
||||
* dwc3_ep_prev_trb - returns the previous TRB in the ring
|
||||
* @dep: The endpoint with the TRB ring
|
||||
* @index: The index of the current TRB in the ring
|
||||
*
|
||||
@@ -953,7 +994,6 @@ static struct dwc3_trb *dwc3_ep_prev_trb(struct dwc3_ep *dep, u8 index)
|
||||
static u32 dwc3_calc_trbs_left(struct dwc3_ep *dep)
|
||||
{
|
||||
struct dwc3_trb *tmp;
|
||||
struct dwc3 *dwc = dep->dwc;
|
||||
u8 trbs_left;
|
||||
|
||||
/*
|
||||
@@ -965,8 +1005,7 @@ static u32 dwc3_calc_trbs_left(struct dwc3_ep *dep)
|
||||
*/
|
||||
if (dep->trb_enqueue == dep->trb_dequeue) {
|
||||
tmp = dwc3_ep_prev_trb(dep, dep->trb_enqueue);
|
||||
if (dev_WARN_ONCE(dwc->dev, tmp->ctrl & DWC3_TRB_CTRL_HWO,
|
||||
"%s No TRBS left\n", dep->name))
|
||||
if (tmp->ctrl & DWC3_TRB_CTRL_HWO)
|
||||
return 0;
|
||||
|
||||
return DWC3_TRB_NUM - 1;
|
||||
@@ -1101,6 +1140,17 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep)
|
||||
}
|
||||
|
||||
list_for_each_entry_safe(req, n, &dep->pending_list, list) {
|
||||
struct dwc3 *dwc = dep->dwc;
|
||||
int ret;
|
||||
|
||||
ret = usb_gadget_map_request_by_dev(dwc->sysdev, &req->request,
|
||||
dep->direction);
|
||||
if (ret)
|
||||
return;
|
||||
|
||||
req->sg = req->request.sg;
|
||||
req->num_pending_sgs = req->request.num_mapped_sgs;
|
||||
|
||||
if (req->num_pending_sgs > 0)
|
||||
dwc3_prepare_one_trb_sg(dep, req);
|
||||
else
|
||||
@@ -1207,7 +1257,7 @@ static void dwc3_gadget_start_isoc(struct dwc3 *dwc,
|
||||
static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)
|
||||
{
|
||||
struct dwc3 *dwc = dep->dwc;
|
||||
int ret;
|
||||
int ret = 0;
|
||||
|
||||
if (!dep->endpoint.desc) {
|
||||
dev_err(dwc->dev, "%s: can't queue to disabled endpoint\n",
|
||||
@@ -1215,12 +1265,9 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)
|
||||
return -ESHUTDOWN;
|
||||
}
|
||||
|
||||
if (WARN(req->dep != dep, "request %p belongs to '%s'\n",
|
||||
&req->request, req->dep->name)) {
|
||||
dev_err(dwc->dev, "%s: request %p belongs to '%s'\n",
|
||||
dep->name, &req->request, req->dep->name);
|
||||
if (WARN(req->dep != dep, "request %pK belongs to '%s'\n",
|
||||
&req->request, req->dep->name))
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pm_runtime_get(dwc->dev);
|
||||
|
||||
@@ -1231,14 +1278,6 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)
|
||||
|
||||
trace_dwc3_ep_queue(req);
|
||||
|
||||
ret = usb_gadget_map_request_by_dev(dwc->sysdev, &req->request,
|
||||
dep->direction);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
req->sg = req->request.sg;
|
||||
req->num_pending_sgs = req->request.num_mapped_sgs;
|
||||
|
||||
list_add_tail(&req->list, &dep->pending_list);
|
||||
|
||||
/*
|
||||
@@ -1396,7 +1435,7 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep,
|
||||
}
|
||||
goto out1;
|
||||
}
|
||||
dev_err(dwc->dev, "request %p was not queued to %s\n",
|
||||
dev_err(dwc->dev, "request %pK was not queued to %s\n",
|
||||
request, ep->name);
|
||||
ret = -EINVAL;
|
||||
goto out0;
|
||||
@@ -1741,8 +1780,8 @@ static irqreturn_t dwc3_interrupt(int irq, void *_dwc);
|
||||
static irqreturn_t dwc3_thread_interrupt(int irq, void *_dwc);
|
||||
|
||||
/**
|
||||
* dwc3_gadget_setup_nump - Calculate and initialize NUMP field of DCFG
|
||||
* dwc: pointer to our context structure
|
||||
* dwc3_gadget_setup_nump - calculate and initialize NUMP field of %DWC3_DCFG
|
||||
* @dwc: pointer to our context structure
|
||||
*
|
||||
* The following looks like complex but it's actually very simple. In order to
|
||||
* calculate the number of packets we can burst at once on OUT transfers, we're
|
||||
@@ -1798,49 +1837,6 @@ static int __dwc3_gadget_start(struct dwc3 *dwc)
|
||||
dwc3_writel(dwc->regs, DWC3_DEV_IMOD(0), 0);
|
||||
}
|
||||
|
||||
reg = dwc3_readl(dwc->regs, DWC3_DCFG);
|
||||
reg &= ~(DWC3_DCFG_SPEED_MASK);
|
||||
|
||||
/**
|
||||
* WORKAROUND: DWC3 revision < 2.20a have an issue
|
||||
* which would cause metastability state on Run/Stop
|
||||
* bit if we try to force the IP to USB2-only mode.
|
||||
*
|
||||
* Because of that, we cannot configure the IP to any
|
||||
* speed other than the SuperSpeed
|
||||
*
|
||||
* Refers to:
|
||||
*
|
||||
* STAR#9000525659: Clock Domain Crossing on DCTL in
|
||||
* USB 2.0 Mode
|
||||
*/
|
||||
if (dwc->revision < DWC3_REVISION_220A) {
|
||||
reg |= DWC3_DCFG_SUPERSPEED;
|
||||
} else {
|
||||
switch (dwc->maximum_speed) {
|
||||
case USB_SPEED_LOW:
|
||||
reg |= DWC3_DCFG_LOWSPEED;
|
||||
break;
|
||||
case USB_SPEED_FULL:
|
||||
reg |= DWC3_DCFG_FULLSPEED;
|
||||
break;
|
||||
case USB_SPEED_HIGH:
|
||||
reg |= DWC3_DCFG_HIGHSPEED;
|
||||
break;
|
||||
case USB_SPEED_SUPER_PLUS:
|
||||
reg |= DWC3_DCFG_SUPERSPEED_PLUS;
|
||||
break;
|
||||
default:
|
||||
dev_err(dwc->dev, "invalid dwc->maximum_speed (%d)\n",
|
||||
dwc->maximum_speed);
|
||||
/* fall through */
|
||||
case USB_SPEED_SUPER:
|
||||
reg |= DWC3_DCFG_SUPERSPEED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
dwc3_writel(dwc->regs, DWC3_DCFG, reg);
|
||||
|
||||
/*
|
||||
* We are telling dwc3 that we want to use DCFG.NUMP as ACK TP's NUMP
|
||||
* field instead of letting dwc3 itself calculate that automatically.
|
||||
@@ -1972,6 +1968,63 @@ out:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dwc3_gadget_set_speed(struct usb_gadget *g,
|
||||
enum usb_device_speed speed)
|
||||
{
|
||||
struct dwc3 *dwc = gadget_to_dwc(g);
|
||||
unsigned long flags;
|
||||
u32 reg;
|
||||
|
||||
spin_lock_irqsave(&dwc->lock, flags);
|
||||
reg = dwc3_readl(dwc->regs, DWC3_DCFG);
|
||||
reg &= ~(DWC3_DCFG_SPEED_MASK);
|
||||
|
||||
/*
|
||||
* WORKAROUND: DWC3 revision < 2.20a have an issue
|
||||
* which would cause metastability state on Run/Stop
|
||||
* bit if we try to force the IP to USB2-only mode.
|
||||
*
|
||||
* Because of that, we cannot configure the IP to any
|
||||
* speed other than the SuperSpeed
|
||||
*
|
||||
* Refers to:
|
||||
*
|
||||
* STAR#9000525659: Clock Domain Crossing on DCTL in
|
||||
* USB 2.0 Mode
|
||||
*/
|
||||
if (dwc->revision < DWC3_REVISION_220A) {
|
||||
reg |= DWC3_DCFG_SUPERSPEED;
|
||||
} else {
|
||||
switch (speed) {
|
||||
case USB_SPEED_LOW:
|
||||
reg |= DWC3_DCFG_LOWSPEED;
|
||||
break;
|
||||
case USB_SPEED_FULL:
|
||||
reg |= DWC3_DCFG_FULLSPEED;
|
||||
break;
|
||||
case USB_SPEED_HIGH:
|
||||
reg |= DWC3_DCFG_HIGHSPEED;
|
||||
break;
|
||||
case USB_SPEED_SUPER:
|
||||
reg |= DWC3_DCFG_SUPERSPEED;
|
||||
break;
|
||||
case USB_SPEED_SUPER_PLUS:
|
||||
reg |= DWC3_DCFG_SUPERSPEED_PLUS;
|
||||
break;
|
||||
default:
|
||||
dev_err(dwc->dev, "invalid speed (%d)\n", speed);
|
||||
|
||||
if (dwc->revision & DWC3_REVISION_IS_DWC31)
|
||||
reg |= DWC3_DCFG_SUPERSPEED_PLUS;
|
||||
else
|
||||
reg |= DWC3_DCFG_SUPERSPEED;
|
||||
}
|
||||
}
|
||||
dwc3_writel(dwc->regs, DWC3_DCFG, reg);
|
||||
|
||||
spin_unlock_irqrestore(&dwc->lock, flags);
|
||||
}
|
||||
|
||||
static const struct usb_gadget_ops dwc3_gadget_ops = {
|
||||
.get_frame = dwc3_gadget_get_frame,
|
||||
.wakeup = dwc3_gadget_wakeup,
|
||||
@@ -1979,19 +2032,21 @@ static const struct usb_gadget_ops dwc3_gadget_ops = {
|
||||
.pullup = dwc3_gadget_pullup,
|
||||
.udc_start = dwc3_gadget_start,
|
||||
.udc_stop = dwc3_gadget_stop,
|
||||
.udc_set_speed = dwc3_gadget_set_speed,
|
||||
};
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
static int dwc3_gadget_init_endpoints(struct dwc3 *dwc, u8 num)
|
||||
static int dwc3_gadget_init_endpoints(struct dwc3 *dwc, u8 total)
|
||||
{
|
||||
struct dwc3_ep *dep;
|
||||
u8 epnum;
|
||||
|
||||
INIT_LIST_HEAD(&dwc->gadget.ep_list);
|
||||
|
||||
for (epnum = 0; epnum < num; epnum++) {
|
||||
for (epnum = 0; epnum < total; epnum++) {
|
||||
bool direction = epnum & 1;
|
||||
u8 num = epnum >> 1;
|
||||
|
||||
dep = kzalloc(sizeof(*dep), GFP_KERNEL);
|
||||
if (!dep)
|
||||
@@ -2003,7 +2058,7 @@ static int dwc3_gadget_init_endpoints(struct dwc3 *dwc, u8 num)
|
||||
dep->regs = dwc->regs + DWC3_DEP_BASE(epnum);
|
||||
dwc->eps[epnum] = dep;
|
||||
|
||||
snprintf(dep->name, sizeof(dep->name), "ep%d%s", epnum >> 1,
|
||||
snprintf(dep->name, sizeof(dep->name), "ep%u%s", num,
|
||||
direction ? "in" : "out");
|
||||
|
||||
dep->endpoint.name = dep->name;
|
||||
@@ -2015,39 +2070,39 @@ static int dwc3_gadget_init_endpoints(struct dwc3 *dwc, u8 num)
|
||||
|
||||
spin_lock_init(&dep->lock);
|
||||
|
||||
if (epnum == 0 || epnum == 1) {
|
||||
if (num == 0) {
|
||||
usb_ep_set_maxpacket_limit(&dep->endpoint, 512);
|
||||
dep->endpoint.maxburst = 1;
|
||||
dep->endpoint.ops = &dwc3_gadget_ep0_ops;
|
||||
if (!epnum)
|
||||
if (!direction)
|
||||
dwc->gadget.ep0 = &dep->endpoint;
|
||||
} else if (direction) {
|
||||
int mdwidth;
|
||||
int kbytes;
|
||||
int size;
|
||||
int ret;
|
||||
int num;
|
||||
|
||||
mdwidth = DWC3_MDWIDTH(dwc->hwparams.hwparams0);
|
||||
/* MDWIDTH is represented in bits, we need it in bytes */
|
||||
mdwidth /= 8;
|
||||
|
||||
size = dwc3_readl(dwc->regs, DWC3_GTXFIFOSIZ(epnum >> 1));
|
||||
size = dwc3_readl(dwc->regs, DWC3_GTXFIFOSIZ(num));
|
||||
size = DWC3_GTXFIFOSIZ_TXFDEF(size);
|
||||
|
||||
/* FIFO Depth is in MDWDITH bytes. Multiply */
|
||||
size *= mdwidth;
|
||||
|
||||
num = size / 1024;
|
||||
if (num == 0)
|
||||
num = 1;
|
||||
kbytes = size / 1024;
|
||||
if (kbytes == 0)
|
||||
kbytes = 1;
|
||||
|
||||
/*
|
||||
* FIFO sizes account an extra MDWIDTH * (num + 1) bytes for
|
||||
* FIFO sizes account an extra MDWIDTH * (kbytes + 1) bytes for
|
||||
* internal overhead. We don't really know how these are used,
|
||||
* but documentation say it exists.
|
||||
*/
|
||||
size -= mdwidth * (num + 1);
|
||||
size /= num;
|
||||
size -= mdwidth * (kbytes + 1);
|
||||
size /= kbytes;
|
||||
|
||||
usb_ep_set_maxpacket_limit(&dep->endpoint, size);
|
||||
|
||||
@@ -2073,7 +2128,7 @@ static int dwc3_gadget_init_endpoints(struct dwc3 *dwc, u8 num)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (epnum == 0 || epnum == 1) {
|
||||
if (num == 0) {
|
||||
dep->endpoint.caps.type_control = true;
|
||||
} else {
|
||||
dep->endpoint.caps.type_iso = true;
|
||||
@@ -2871,7 +2926,7 @@ static void dwc3_gadget_hibernation_interrupt(struct dwc3 *dwc,
|
||||
{
|
||||
unsigned int is_ss = evtinfo & BIT(4);
|
||||
|
||||
/**
|
||||
/*
|
||||
* WORKAROUND: DWC3 revison 2.20a with hibernation support
|
||||
* have a known issue which can cause USB CV TD.9.23 to fail
|
||||
* randomly.
|
||||
@@ -2943,20 +2998,12 @@ static void dwc3_process_event_entry(struct dwc3 *dwc,
|
||||
{
|
||||
trace_dwc3_event(event->raw, dwc);
|
||||
|
||||
/* Endpoint IRQ, handle it and return early */
|
||||
if (event->type.is_devspec == 0) {
|
||||
/* depevt */
|
||||
return dwc3_endpoint_interrupt(dwc, &event->depevt);
|
||||
}
|
||||
|
||||
switch (event->type.type) {
|
||||
case DWC3_EVENT_TYPE_DEV:
|
||||
if (!event->type.is_devspec)
|
||||
dwc3_endpoint_interrupt(dwc, &event->depevt);
|
||||
else if (event->type.type == DWC3_EVENT_TYPE_DEV)
|
||||
dwc3_gadget_interrupt(dwc, &event->devt);
|
||||
break;
|
||||
/* REVISIT what to do with Carkit and I2C events ? */
|
||||
default:
|
||||
else
|
||||
dev_err(dwc->dev, "UNKNOWN IRQ type %d\n", event->raw);
|
||||
}
|
||||
}
|
||||
|
||||
static irqreturn_t dwc3_process_event_buf(struct dwc3_event_buffer *evt)
|
||||
@@ -3110,7 +3157,7 @@ out:
|
||||
}
|
||||
|
||||
/**
|
||||
* dwc3_gadget_init - Initializes gadget related registers
|
||||
* dwc3_gadget_init - initializes gadget related registers
|
||||
* @dwc: pointer to our controller context structure
|
||||
*
|
||||
* Returns 0 on success otherwise negative errno.
|
||||
|
Atsaukties uz šo jaunā problēmā
Block a user