Merge "USB: dwc3-msm: Initialize DBM ep before BAM pipe reset"
This commit is contained in:
commit
b574f42cd7
6 changed files with 39 additions and 52 deletions
|
@ -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
|
* 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
|
* 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;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* First, reset the dbm endpoint */
|
|
||||||
ep_soft_reset(dbm, dbm_ep, 0);
|
|
||||||
|
|
||||||
/* Set ioc bit for dbm_ep if needed */
|
/* Set ioc bit for dbm_ep if needed */
|
||||||
msm_dbm_write_reg_field(dbm, DBM_DBG_CNFG,
|
msm_dbm_write_reg_field(dbm, DBM_DBG_CNFG,
|
||||||
DBM_ENABLE_IOC_MASK & 1 << dbm_ep, ioc ? 1 : 0);
|
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);
|
data &= (~0x1);
|
||||||
msm_dbm_write_ep_reg(dbm, DBM_EP_CFG, dbm_ep, data);
|
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
|
* ep_soft_reset is not required during disconnect as pipe reset on
|
||||||
* reset is based on the number of active endpoints. If there is more
|
* next connect will take care of the same.
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
if (dbm_get_num_of_eps_configured(dbm) > 1)
|
|
||||||
udelay(1000);
|
|
||||||
else
|
|
||||||
udelay(10);
|
|
||||||
ep_soft_reset(dbm, dbm_ep, false);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -624,11 +624,6 @@ static int dwc3_msm_ep_queue(struct usb_ep *ep,
|
||||||
struct dwc3_msm_req_complete *req_complete;
|
struct dwc3_msm_req_complete *req_complete;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
int ret = 0, size;
|
int ret = 0, size;
|
||||||
u8 bam_pipe;
|
|
||||||
bool producer;
|
|
||||||
bool disable_wb;
|
|
||||||
bool internal_mem;
|
|
||||||
bool ioc;
|
|
||||||
bool superspeed;
|
bool superspeed;
|
||||||
|
|
||||||
if (!(request->udc_priv & MSM_SPS_MODE)) {
|
if (!(request->udc_priv & MSM_SPS_MODE)) {
|
||||||
|
@ -661,23 +656,6 @@ static int dwc3_msm_ep_queue(struct usb_ep *ep,
|
||||||
list_add_tail(&req_complete->list_item, &mdwc->req_complete_list);
|
list_add_tail(&req_complete->list_item, &mdwc->req_complete_list);
|
||||||
request->complete = dwc3_msm_req_complete_func;
|
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",
|
dev_vdbg(dwc->dev, "%s: queing request %p to ep %s length %d\n",
|
||||||
__func__, request, ep->name, request->length);
|
__func__, request, ep->name, request->length);
|
||||||
size = dwc3_msm_read_reg(mdwc->base, DWC3_GEVNTSIZ(0));
|
size = dwc3_msm_read_reg(mdwc->base, DWC3_GEVNTSIZ(0));
|
||||||
|
@ -1348,12 +1326,19 @@ static int dwc3_msm_gsi_ep_op(struct usb_ep *ep,
|
||||||
*
|
*
|
||||||
* @return int - 0 on success, negetive on error.
|
* @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_ep *dep = to_dwc3_ep(ep);
|
||||||
struct dwc3 *dwc = dep->dwc;
|
struct dwc3 *dwc = dep->dwc;
|
||||||
struct dwc3_msm *mdwc = dev_get_drvdata(dwc->dev->parent);
|
struct dwc3_msm *mdwc = dev_get_drvdata(dwc->dev->parent);
|
||||||
struct usb_ep_ops *new_ep_ops;
|
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*/
|
/* Save original ep ops for future restore*/
|
||||||
|
@ -1366,7 +1351,7 @@ int msm_ep_config(struct usb_ep *ep)
|
||||||
mdwc->original_ep_ops[dep->number] = ep->ops;
|
mdwc->original_ep_ops[dep->number] = ep->ops;
|
||||||
|
|
||||||
/* Set new usb ops as we like */
|
/* 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) {
|
if (!new_ep_ops) {
|
||||||
dev_err(mdwc->dev,
|
dev_err(mdwc->dev,
|
||||||
"%s: unable to allocate mem for new usb ep ops\n",
|
"%s: unable to allocate mem for new usb ep ops\n",
|
||||||
|
@ -1378,10 +1363,25 @@ int msm_ep_config(struct usb_ep *ep)
|
||||||
new_ep_ops->gsi_ep_op = dwc3_msm_gsi_ep_op;
|
new_ep_ops->gsi_ep_op = dwc3_msm_gsi_ep_op;
|
||||||
ep->ops = new_ep_ops;
|
ep->ops = new_ep_ops;
|
||||||
|
|
||||||
|
if (!mdwc->dbm || !request || (dep->endpoint.ep_type == EP_TYPE_GSI))
|
||||||
|
return 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Do HERE more usb endpoint configurations
|
* Configure the DBM endpoint if required.
|
||||||
* which are specific to MSM.
|
|
||||||
*/
|
*/
|
||||||
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2245,7 +2245,7 @@ skip_string_id_alloc:
|
||||||
if (!ep)
|
if (!ep)
|
||||||
goto fail;
|
goto fail;
|
||||||
gsi->d_port.in_ep = ep;
|
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 */
|
ep->driver_data = cdev; /* claim */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2255,7 +2255,7 @@ skip_string_id_alloc:
|
||||||
if (!ep)
|
if (!ep)
|
||||||
goto fail;
|
goto fail;
|
||||||
gsi->d_port.out_ep = ep;
|
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 */
|
ep->driver_data = cdev; /* claim */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -457,7 +457,7 @@ static void ipa_data_connect_work(struct work_struct *w)
|
||||||
configure_fifo(port->usb_bam_type,
|
configure_fifo(port->usb_bam_type,
|
||||||
port->src_connection_idx,
|
port->src_connection_idx,
|
||||||
port->port_usb->out);
|
port->port_usb->out);
|
||||||
ret = msm_ep_config(gport->out);
|
ret = msm_ep_config(gport->out, port->rx_req, GFP_ATOMIC);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
pr_err("msm_ep_config() failed for OUT EP\n");
|
pr_err("msm_ep_config() failed for OUT EP\n");
|
||||||
usb_bam_free_fifos(port->usb_bam_type,
|
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;
|
port->tx_req->udc_priv = sps_params;
|
||||||
configure_fifo(port->usb_bam_type,
|
configure_fifo(port->usb_bam_type,
|
||||||
port->dst_connection_idx, gport->in);
|
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) {
|
if (ret) {
|
||||||
pr_err("msm_ep_config() failed for IN EP\n");
|
pr_err("msm_ep_config() failed for IN EP\n");
|
||||||
goto unconfig_msm_ep_out;
|
goto unconfig_msm_ep_out;
|
||||||
|
|
|
@ -94,11 +94,12 @@ int set_qdss_data_connection(struct usb_gadget *gadget,
|
||||||
|
|
||||||
static int init_data(struct usb_ep *ep)
|
static int init_data(struct usb_ep *ep)
|
||||||
{
|
{
|
||||||
|
struct f_qdss *qdss = ep->driver_data;
|
||||||
int res = 0;
|
int res = 0;
|
||||||
|
|
||||||
pr_debug("init_data\n");
|
pr_debug("init_data\n");
|
||||||
|
|
||||||
res = msm_ep_config(ep);
|
res = msm_ep_config(ep, qdss->endless_req, GFP_ATOMIC);
|
||||||
if (res)
|
if (res)
|
||||||
pr_err("msm_ep_config failed\n");
|
pr_err("msm_ep_config failed\n");
|
||||||
|
|
||||||
|
|
|
@ -296,7 +296,8 @@ static inline void msm_usb_irq_disable(bool disable)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_USB_DWC3_QCOM
|
#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);
|
int msm_ep_unconfig(struct usb_ep *ep);
|
||||||
void dwc3_tx_fifo_resize_request(struct usb_ep *ep, bool qdss_enable);
|
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,
|
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;
|
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;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue