summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVijayavardhan Vennapusa <vvreddy@codeaurora.org>2016-02-03 19:22:23 +0530
committerChandana Kishori Chiluveru <cchiluve@codeaurora.org>2016-12-12 15:16:52 +0530
commit58c91d96b2fca7590fc6b89f1a9bbe1247f818ab (patch)
tree5fe7f636f3139134e01e2b01ae719fdd02758a5d
parenta80e267a8c0d61790c3d1d5f7181ebd1be39c438 (diff)
USB: dwc3-msm: Initialize DBM ep before BAM pipe reset
On new platforms, endpoint clock gating is added for dbm endpoints with Synopsys USB3.0 controller. This hardware feature requires initialization of DBM endpoint before BAM pipe reset for bam2bam mode data transfers working. Hence change sequence such that do DBM endpoint initialization first followed by BAM pipe reset and do start transfer as last operation. CRs-Fixed: 965207 Change-Id: Ib5bfd1a7d258fe336a4c9924850fc9223c1c81f6 Signed-off-by: Vijayavardhan Vennapusa <vvreddy@codeaurora.org> Signed-off-by: Chandana Kishori Chiluveru <cchiluve@codeaurora.org>
-rw-r--r--drivers/usb/dwc3/dbm.c22
-rw-r--r--drivers/usb/dwc3/dwc3-msm.c52
-rw-r--r--drivers/usb/gadget/function/f_gsi.c4
-rw-r--r--drivers/usb/gadget/function/u_data_ipa.c4
-rw-r--r--drivers/usb/gadget/function/u_qdss.c3
-rw-r--r--include/linux/usb/msm_hsusb.h6
6 files changed, 39 insertions, 52 deletions
diff --git a/drivers/usb/dwc3/dbm.c b/drivers/usb/dwc3/dbm.c
index 285cd5a47d82..34a1b6259d1b 100644
--- a/drivers/usb/dwc3/dbm.c
+++ b/drivers/usb/dwc3/dbm.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -312,9 +312,6 @@ int dbm_ep_config(struct dbm *dbm, u8 usb_ep, u8 bam_pipe, bool producer,
return -ENODEV;
}
- /* First, reset the dbm endpoint */
- ep_soft_reset(dbm, dbm_ep, 0);
-
/* Set ioc bit for dbm_ep if needed */
msm_dbm_write_reg_field(dbm, DBM_DBG_CNFG,
DBM_ENABLE_IOC_MASK & 1 << dbm_ep, ioc ? 1 : 0);
@@ -391,23 +388,10 @@ int dbm_ep_unconfig(struct dbm *dbm, u8 usb_ep)
data &= (~0x1);
msm_dbm_write_ep_reg(dbm, DBM_EP_CFG, dbm_ep, data);
- /* Reset the dbm endpoint */
- ep_soft_reset(dbm, dbm_ep, true);
/*
- * The necessary delay between asserting and deasserting the dbm ep
- * reset is based on the number of active endpoints. If there is more
- * than one endpoint, a 1 msec delay is required. Otherwise, a shorter
- * delay will suffice.
- *
- * As this function can be called in atomic context, sleeping variants
- * for delay are not possible - albeit a 1ms delay.
+ * ep_soft_reset is not required during disconnect as pipe reset on
+ * next connect will take care of the same.
*/
- if (dbm_get_num_of_eps_configured(dbm) > 1)
- udelay(1000);
- else
- udelay(10);
- ep_soft_reset(dbm, dbm_ep, false);
-
return 0;
}
diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c
index bb6afb6a7d6d..91c3aa314b23 100644
--- a/drivers/usb/dwc3/dwc3-msm.c
+++ b/drivers/usb/dwc3/dwc3-msm.c
@@ -622,11 +622,6 @@ static int dwc3_msm_ep_queue(struct usb_ep *ep,
struct dwc3_msm_req_complete *req_complete;
unsigned long flags;
int ret = 0, size;
- u8 bam_pipe;
- bool producer;
- bool disable_wb;
- bool internal_mem;
- bool ioc;
bool superspeed;
if (!(request->udc_priv & MSM_SPS_MODE)) {
@@ -659,23 +654,6 @@ static int dwc3_msm_ep_queue(struct usb_ep *ep,
list_add_tail(&req_complete->list_item, &mdwc->req_complete_list);
request->complete = dwc3_msm_req_complete_func;
- /*
- * Configure the DBM endpoint
- */
- bam_pipe = request->udc_priv & MSM_PIPE_ID_MASK;
- producer = ((request->udc_priv & MSM_PRODUCER) ? true : false);
- disable_wb = ((request->udc_priv & MSM_DISABLE_WB) ? true : false);
- internal_mem = ((request->udc_priv & MSM_INTERNAL_MEM) ? true : false);
- ioc = ((request->udc_priv & MSM_ETD_IOC) ? true : false);
-
- ret = dbm_ep_config(mdwc->dbm, dep->number, bam_pipe, producer,
- disable_wb, internal_mem, ioc);
- if (ret < 0) {
- dev_err(mdwc->dev,
- "error %d after calling dbm_ep_config\n", ret);
- return ret;
- }
-
dev_vdbg(dwc->dev, "%s: queing request %p to ep %s length %d\n",
__func__, request, ep->name, request->length);
size = dwc3_msm_read_reg(mdwc->base, DWC3_GEVNTSIZ(0));
@@ -1346,12 +1324,19 @@ static int dwc3_msm_gsi_ep_op(struct usb_ep *ep,
*
* @return int - 0 on success, negetive on error.
*/
-int msm_ep_config(struct usb_ep *ep)
+int msm_ep_config(struct usb_ep *ep, struct usb_request *request,
+ gfp_t gfp_flags)
{
struct dwc3_ep *dep = to_dwc3_ep(ep);
struct dwc3 *dwc = dep->dwc;
struct dwc3_msm *mdwc = dev_get_drvdata(dwc->dev->parent);
struct usb_ep_ops *new_ep_ops;
+ int ret = 0;
+ u8 bam_pipe;
+ bool producer;
+ bool disable_wb;
+ bool internal_mem;
+ bool ioc;
/* Save original ep ops for future restore*/
@@ -1364,7 +1349,7 @@ int msm_ep_config(struct usb_ep *ep)
mdwc->original_ep_ops[dep->number] = ep->ops;
/* Set new usb ops as we like */
- new_ep_ops = kzalloc(sizeof(struct usb_ep_ops), GFP_ATOMIC);
+ new_ep_ops = kzalloc(sizeof(struct usb_ep_ops), gfp_flags);
if (!new_ep_ops) {
dev_err(mdwc->dev,
"%s: unable to allocate mem for new usb ep ops\n",
@@ -1376,10 +1361,25 @@ int msm_ep_config(struct usb_ep *ep)
new_ep_ops->gsi_ep_op = dwc3_msm_gsi_ep_op;
ep->ops = new_ep_ops;
+ if (!mdwc->dbm || !request || (dep->endpoint.ep_type == EP_TYPE_GSI))
+ return 0;
+
/*
- * Do HERE more usb endpoint configurations
- * which are specific to MSM.
+ * Configure the DBM endpoint if required.
*/
+ bam_pipe = request->udc_priv & MSM_PIPE_ID_MASK;
+ producer = ((request->udc_priv & MSM_PRODUCER) ? true : false);
+ disable_wb = ((request->udc_priv & MSM_DISABLE_WB) ? true : false);
+ internal_mem = ((request->udc_priv & MSM_INTERNAL_MEM) ? true : false);
+ ioc = ((request->udc_priv & MSM_ETD_IOC) ? true : false);
+
+ ret = dbm_ep_config(mdwc->dbm, dep->number, bam_pipe, producer,
+ disable_wb, internal_mem, ioc);
+ if (ret < 0) {
+ dev_err(mdwc->dev,
+ "error %d after calling dbm_ep_config\n", ret);
+ return ret;
+ }
return 0;
}
diff --git a/drivers/usb/gadget/function/f_gsi.c b/drivers/usb/gadget/function/f_gsi.c
index af20033b621f..84b60ec771a4 100644
--- a/drivers/usb/gadget/function/f_gsi.c
+++ b/drivers/usb/gadget/function/f_gsi.c
@@ -2245,7 +2245,7 @@ skip_string_id_alloc:
if (!ep)
goto fail;
gsi->d_port.in_ep = ep;
- msm_ep_config(gsi->d_port.in_ep);
+ msm_ep_config(gsi->d_port.in_ep, NULL, GFP_KERNEL);
ep->driver_data = cdev; /* claim */
}
@@ -2255,7 +2255,7 @@ skip_string_id_alloc:
if (!ep)
goto fail;
gsi->d_port.out_ep = ep;
- msm_ep_config(gsi->d_port.out_ep);
+ msm_ep_config(gsi->d_port.out_ep, NULL, GFP_KERNEL);
ep->driver_data = cdev; /* claim */
}
diff --git a/drivers/usb/gadget/function/u_data_ipa.c b/drivers/usb/gadget/function/u_data_ipa.c
index 2da0c59fdfc2..1850aa6ea19d 100644
--- a/drivers/usb/gadget/function/u_data_ipa.c
+++ b/drivers/usb/gadget/function/u_data_ipa.c
@@ -457,7 +457,7 @@ static void ipa_data_connect_work(struct work_struct *w)
configure_fifo(port->usb_bam_type,
port->src_connection_idx,
port->port_usb->out);
- ret = msm_ep_config(gport->out);
+ ret = msm_ep_config(gport->out, port->rx_req, GFP_ATOMIC);
if (ret) {
pr_err("msm_ep_config() failed for OUT EP\n");
usb_bam_free_fifos(port->usb_bam_type,
@@ -475,7 +475,7 @@ static void ipa_data_connect_work(struct work_struct *w)
port->tx_req->udc_priv = sps_params;
configure_fifo(port->usb_bam_type,
port->dst_connection_idx, gport->in);
- ret = msm_ep_config(gport->in);
+ ret = msm_ep_config(gport->in, port->tx_req, GFP_ATOMIC);
if (ret) {
pr_err("msm_ep_config() failed for IN EP\n");
goto unconfig_msm_ep_out;
diff --git a/drivers/usb/gadget/function/u_qdss.c b/drivers/usb/gadget/function/u_qdss.c
index 8f5fcc16eb15..e26f0977b9b7 100644
--- a/drivers/usb/gadget/function/u_qdss.c
+++ b/drivers/usb/gadget/function/u_qdss.c
@@ -94,11 +94,12 @@ int set_qdss_data_connection(struct usb_gadget *gadget,
static int init_data(struct usb_ep *ep)
{
+ struct f_qdss *qdss = ep->driver_data;
int res = 0;
pr_debug("init_data\n");
- res = msm_ep_config(ep);
+ res = msm_ep_config(ep, qdss->endless_req, GFP_ATOMIC);
if (res)
pr_err("msm_ep_config failed\n");
diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h
index 44b6222db9a3..1eb442f8dc6c 100644
--- a/include/linux/usb/msm_hsusb.h
+++ b/include/linux/usb/msm_hsusb.h
@@ -296,7 +296,8 @@ static inline void msm_usb_irq_disable(bool disable)
#endif
#ifdef CONFIG_USB_DWC3_QCOM
-int msm_ep_config(struct usb_ep *ep);
+int msm_ep_config(struct usb_ep *ep, struct usb_request *request,
+ gfp_t gfp_flags);
int msm_ep_unconfig(struct usb_ep *ep);
void dwc3_tx_fifo_resize_request(struct usb_ep *ep, bool qdss_enable);
int msm_data_fifo_config(struct usb_ep *ep, phys_addr_t addr, u32 size,
@@ -311,7 +312,8 @@ static inline int msm_data_fifo_config(struct usb_ep *ep, phys_addr_t addr,
return -ENODEV;
}
-static inline int msm_ep_config(struct usb_ep *ep)
+static inline int msm_ep_config(struct usb_ep *ep, struct usb_request *request,
+ gfp_t gfp_flags)
{
return -ENODEV;
}