From 47d3946ea220f2db43b3abc46c9e64287d625ac3 Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Tue, 31 Jan 2017 20:58:10 +0000 Subject: [PATCH] usb: dwc3: refactor gadget endpoint count calculation - DWC_USB3_NUM indicates the number of Device mode single directional endpoints, including OUT and IN endpoint 0. - DWC_USB3_NUM_IN_EPS indicates the maximum number of Device mode IN endpoints active at any time, including control endpoint 0. It's possible to configure RTL such that DWC_USB3_NUM_EPS is equal to DWC_USB3_NUM_IN_EPS. dwc3-core calculates the number of OUT endpoints as DWC_USB3_NUM minus DWC_USB3_NUM_IN_EPS. If RTL has been configured with DWC_USB3_NUM_IN_EPS equal to DWC_USB3_NUM then dwc3-core will calculate the number of OUT endpoints as zero. For example a from dwc3_core_num_eps() shows: [ 1.565000] /usb0@f01d0000: found 8 IN and 0 OUT endpoints This patch refactors the endpoint calculation down to one variable dwc->num_eps taking care to maintain the current mapping of endpoints for fixed FPGA configurations as described in Table 4-7 of version 2.60a of the DWC USB3 databook. The endpoint mapping will then be EP-OUT, EP-IN etc, up to DWC_USB3_NUM. If DWC_USB3_NUM is odd then OUT will take the extra endpoint. Suggested-by: Felipe Balbi Signed-off-by: Bryan O'Donoghue Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.c | 3 +-- drivers/usb/dwc3/core.h | 6 ++---- drivers/usb/dwc3/debugfs.c | 15 ++------------- drivers/usb/dwc3/gadget.c | 33 +++++++++------------------------ 4 files changed, 14 insertions(+), 43 deletions(-) diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 8173d0634d68..56f136784cd3 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -397,8 +397,7 @@ static void dwc3_core_num_eps(struct dwc3 *dwc) { struct dwc3_hwparams *parms = &dwc->hwparams; - dwc->num_in_eps = DWC3_NUM_IN_EPS(parms); - dwc->num_out_eps = DWC3_NUM_EPS(parms) - dwc->num_in_eps; + dwc->num_eps = DWC3_NUM_EPS(parms); } static void dwc3_cache_hwparams(struct dwc3 *dwc) diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 2fa768637f49..92045efefaab 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -800,8 +800,7 @@ struct dwc3_scratchpad_array { * @u2pel: parameter from Set SEL request. * @u1sel: parameter from Set SEL request. * @u1pel: parameter from Set SEL request. - * @num_out_eps: number of out endpoints - * @num_in_eps: number of in endpoints + * @num_eps: number of endpoints * @ep0_next_event: hold the next expected event * @ep0state: state of endpoint zero * @link_state: link state @@ -961,8 +960,7 @@ struct dwc3 { u8 speed; - u8 num_out_eps; - u8 num_in_eps; + u8 num_eps; struct dwc3_hwparams hwparams; struct dentry *root; diff --git a/drivers/usb/dwc3/debugfs.c b/drivers/usb/dwc3/debugfs.c index 31926dda43c9..7df45415ad70 100644 --- a/drivers/usb/dwc3/debugfs.c +++ b/drivers/usb/dwc3/debugfs.c @@ -822,19 +822,8 @@ static void dwc3_debugfs_create_endpoint_dirs(struct dwc3 *dwc, { int i; - for (i = 0; i < dwc->num_in_eps; i++) { - u8 epnum = (i << 1) | 1; - struct dwc3_ep *dep = dwc->eps[epnum]; - - if (!dep) - continue; - - dwc3_debugfs_create_endpoint_dir(dep, parent); - } - - for (i = 0; i < dwc->num_out_eps; i++) { - u8 epnum = (i << 1); - struct dwc3_ep *dep = dwc->eps[epnum]; + for (i = 0; i < dwc->num_eps; i++) { + struct dwc3_ep *dep = dwc->eps[i]; if (!dep) continue; diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 79e7a3480d51..fe4e0ac00f06 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -2006,14 +2006,13 @@ static const struct usb_gadget_ops dwc3_gadget_ops = { /* -------------------------------------------------------------------------- */ -static int dwc3_gadget_init_hw_endpoints(struct dwc3 *dwc, - u8 num, u32 direction) +static int dwc3_gadget_init_hw_endpoints(struct dwc3 *dwc, u8 num) { struct dwc3_ep *dep; - u8 i; + u8 epnum; - for (i = 0; i < num; i++) { - u8 epnum = (i << 1) | (direction ? 1 : 0); + for (epnum = 0; epnum < num; epnum++) { + bool direction = epnum & 1; dep = kzalloc(sizeof(*dep), GFP_KERNEL); if (!dep) @@ -2021,12 +2020,12 @@ static int dwc3_gadget_init_hw_endpoints(struct dwc3 *dwc, dep->dwc = dwc; dep->number = epnum; - dep->direction = !!direction; + dep->direction = direction; dep->regs = dwc->regs + DWC3_DEP_BASE(epnum); dwc->eps[epnum] = dep; snprintf(dep->name, sizeof(dep->name), "ep%d%s", epnum >> 1, - (epnum & 1) ? "in" : "out"); + direction ? "in" : "out"); dep->endpoint.name = dep->name; @@ -2053,7 +2052,7 @@ static int dwc3_gadget_init_hw_endpoints(struct dwc3 *dwc, /* MDWIDTH is represented in bits, we need it in bytes */ mdwidth /= 8; - size = dwc3_readl(dwc->regs, DWC3_GTXFIFOSIZ(i)); + size = dwc3_readl(dwc->regs, DWC3_GTXFIFOSIZ(epnum >> 1)); size = DWC3_GTXFIFOSIZ_TXFDEF(size); /* FIFO Depth is in MDWDITH bytes. Multiply */ @@ -2103,7 +2102,7 @@ static int dwc3_gadget_init_hw_endpoints(struct dwc3 *dwc, dep->endpoint.caps.type_int = true; } - dep->endpoint.caps.dir_in = !!direction; + dep->endpoint.caps.dir_in = direction; dep->endpoint.caps.dir_out = !direction; INIT_LIST_HEAD(&dep->pending_list); @@ -2115,23 +2114,9 @@ static int dwc3_gadget_init_hw_endpoints(struct dwc3 *dwc, static int dwc3_gadget_init_endpoints(struct dwc3 *dwc) { - int ret; - INIT_LIST_HEAD(&dwc->gadget.ep_list); - ret = dwc3_gadget_init_hw_endpoints(dwc, dwc->num_out_eps, 0); - if (ret < 0) { - dev_err(dwc->dev, "failed to initialize OUT endpoints\n"); - return ret; - } - - ret = dwc3_gadget_init_hw_endpoints(dwc, dwc->num_in_eps, 1); - if (ret < 0) { - dev_err(dwc->dev, "failed to initialize IN endpoints\n"); - return ret; - } - - return 0; + return dwc3_gadget_init_hw_endpoints(dwc, dwc->num_eps); } static void dwc3_gadget_free_endpoints(struct dwc3 *dwc)