Merge "USB: dwc3-msm: Perform DBM config/unconfig under spinlock protection"
This commit is contained in:
commit
9660a520b9
7 changed files with 41 additions and 23 deletions
|
@ -654,6 +654,14 @@ static int dwc3_msm_ep_queue(struct usb_ep *ep,
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!mdwc->original_ep_ops[dep->number]) {
|
||||||
|
dev_err(mdwc->dev,
|
||||||
|
"ep [%s,%d] was unconfigured as msm endpoint\n",
|
||||||
|
ep->name, dep->number);
|
||||||
|
spin_unlock_irqrestore(&dwc->lock, flags);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
if (!request) {
|
if (!request) {
|
||||||
dev_err(mdwc->dev, "%s: request is NULL\n", __func__);
|
dev_err(mdwc->dev, "%s: request is NULL\n", __func__);
|
||||||
spin_unlock_irqrestore(&dwc->lock, flags);
|
spin_unlock_irqrestore(&dwc->lock, flags);
|
||||||
|
@ -661,14 +669,11 @@ static int dwc3_msm_ep_queue(struct usb_ep *ep,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(request->udc_priv & MSM_SPS_MODE)) {
|
if (!(request->udc_priv & MSM_SPS_MODE)) {
|
||||||
/* Not SPS mode, call original queue */
|
dev_err(mdwc->dev, "%s: sps mode is not set\n",
|
||||||
dev_vdbg(mdwc->dev, "%s: not sps mode, use regular queue\n",
|
|
||||||
__func__);
|
__func__);
|
||||||
|
|
||||||
spin_unlock_irqrestore(&dwc->lock, flags);
|
spin_unlock_irqrestore(&dwc->lock, flags);
|
||||||
return (mdwc->original_ep_ops[dep->number])->queue(ep,
|
return -EINVAL;
|
||||||
request,
|
|
||||||
gfp_flags);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* HW restriction regarding TRB size (8KB) */
|
/* HW restriction regarding TRB size (8KB) */
|
||||||
|
@ -1345,8 +1350,7 @@ 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, struct usb_request *request,
|
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;
|
||||||
|
@ -1358,23 +1362,27 @@ int msm_ep_config(struct usb_ep *ep, struct usb_request *request,
|
||||||
bool disable_wb;
|
bool disable_wb;
|
||||||
bool internal_mem;
|
bool internal_mem;
|
||||||
bool ioc;
|
bool ioc;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
|
||||||
|
spin_lock_irqsave(&dwc->lock, flags);
|
||||||
/* Save original ep ops for future restore*/
|
/* Save original ep ops for future restore*/
|
||||||
if (mdwc->original_ep_ops[dep->number]) {
|
if (mdwc->original_ep_ops[dep->number]) {
|
||||||
dev_err(mdwc->dev,
|
dev_err(mdwc->dev,
|
||||||
"ep [%s,%d] already configured as msm endpoint\n",
|
"ep [%s,%d] already configured as msm endpoint\n",
|
||||||
ep->name, dep->number);
|
ep->name, dep->number);
|
||||||
|
spin_unlock_irqrestore(&dwc->lock, flags);
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
}
|
}
|
||||||
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_flags);
|
new_ep_ops = kzalloc(sizeof(struct usb_ep_ops), GFP_ATOMIC);
|
||||||
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",
|
||||||
__func__);
|
__func__);
|
||||||
|
spin_unlock_irqrestore(&dwc->lock, flags);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
(*new_ep_ops) = (*ep->ops);
|
(*new_ep_ops) = (*ep->ops);
|
||||||
|
@ -1382,8 +1390,10 @@ int msm_ep_config(struct usb_ep *ep, struct usb_request *request,
|
||||||
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))
|
if (!mdwc->dbm || !request || (dep->endpoint.ep_type == EP_TYPE_GSI)) {
|
||||||
|
spin_unlock_irqrestore(&dwc->lock, flags);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Configure the DBM endpoint if required.
|
* Configure the DBM endpoint if required.
|
||||||
|
@ -1399,9 +1409,12 @@ int msm_ep_config(struct usb_ep *ep, struct usb_request *request,
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
dev_err(mdwc->dev,
|
dev_err(mdwc->dev,
|
||||||
"error %d after calling dbm_ep_config\n", ret);
|
"error %d after calling dbm_ep_config\n", ret);
|
||||||
|
spin_unlock_irqrestore(&dwc->lock, flags);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&dwc->lock, flags);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(msm_ep_config);
|
EXPORT_SYMBOL(msm_ep_config);
|
||||||
|
@ -1421,12 +1434,15 @@ int msm_ep_unconfig(struct usb_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 *old_ep_ops;
|
struct usb_ep_ops *old_ep_ops;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&dwc->lock, flags);
|
||||||
/* Restore original ep ops */
|
/* Restore original ep ops */
|
||||||
if (!mdwc->original_ep_ops[dep->number]) {
|
if (!mdwc->original_ep_ops[dep->number]) {
|
||||||
dev_err(mdwc->dev,
|
dev_err(mdwc->dev,
|
||||||
"ep [%s,%d] was not configured as msm endpoint\n",
|
"ep [%s,%d] was not configured as msm endpoint\n",
|
||||||
ep->name, dep->number);
|
ep->name, dep->number);
|
||||||
|
spin_unlock_irqrestore(&dwc->lock, flags);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
old_ep_ops = (struct usb_ep_ops *)ep->ops;
|
old_ep_ops = (struct usb_ep_ops *)ep->ops;
|
||||||
|
@ -1438,8 +1454,10 @@ int msm_ep_unconfig(struct usb_ep *ep)
|
||||||
* Do HERE more usb endpoint un-configurations
|
* Do HERE more usb endpoint un-configurations
|
||||||
* which are specific to MSM.
|
* which are specific to MSM.
|
||||||
*/
|
*/
|
||||||
if (!mdwc->dbm || (dep->endpoint.ep_type == EP_TYPE_GSI))
|
if (!mdwc->dbm || (dep->endpoint.ep_type == EP_TYPE_GSI)) {
|
||||||
|
spin_unlock_irqrestore(&dwc->lock, flags);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (dep->busy_slot == dep->free_slot && list_empty(&dep->request_list)
|
if (dep->busy_slot == dep->free_slot && list_empty(&dep->request_list)
|
||||||
&& list_empty(&dep->req_queued)) {
|
&& list_empty(&dep->req_queued)) {
|
||||||
|
@ -1460,6 +1478,8 @@ int msm_ep_unconfig(struct usb_ep *ep)
|
||||||
dbm_event_buffer_config(mdwc->dbm, 0, 0, 0);
|
dbm_event_buffer_config(mdwc->dbm, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&dwc->lock, flags);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(msm_ep_unconfig);
|
EXPORT_SYMBOL(msm_ep_unconfig);
|
||||||
|
|
|
@ -2253,7 +2253,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, NULL, GFP_KERNEL);
|
msm_ep_config(gsi->d_port.in_ep, NULL);
|
||||||
ep->driver_data = cdev; /* claim */
|
ep->driver_data = cdev; /* claim */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2263,7 +2263,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, NULL, GFP_KERNEL);
|
msm_ep_config(gsi->d_port.out_ep, NULL);
|
||||||
ep->driver_data = cdev; /* claim */
|
ep->driver_data = cdev; /* claim */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1395,7 +1395,7 @@ static void gbam2bam_connect_work(struct work_struct *w)
|
||||||
d->src_pipe_idx;
|
d->src_pipe_idx;
|
||||||
d->rx_req->length = 32*1024;
|
d->rx_req->length = 32*1024;
|
||||||
d->rx_req->udc_priv = sps_params;
|
d->rx_req->udc_priv = sps_params;
|
||||||
msm_ep_config(port->port_usb->out, d->rx_req, GFP_ATOMIC);
|
msm_ep_config(port->port_usb->out, d->rx_req);
|
||||||
|
|
||||||
/* Configure for TX */
|
/* Configure for TX */
|
||||||
configure_data_fifo(d->usb_bam_type, d->dst_connection_idx,
|
configure_data_fifo(d->usb_bam_type, d->dst_connection_idx,
|
||||||
|
@ -1403,7 +1403,7 @@ static void gbam2bam_connect_work(struct work_struct *w)
|
||||||
sps_params = MSM_SPS_MODE | MSM_DISABLE_WB | d->dst_pipe_idx;
|
sps_params = MSM_SPS_MODE | MSM_DISABLE_WB | d->dst_pipe_idx;
|
||||||
d->tx_req->length = 32*1024;
|
d->tx_req->length = 32*1024;
|
||||||
d->tx_req->udc_priv = sps_params;
|
d->tx_req->udc_priv = sps_params;
|
||||||
msm_ep_config(port->port_usb->in, d->tx_req, GFP_ATOMIC);
|
msm_ep_config(port->port_usb->in, d->tx_req);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
/* Configure for RX */
|
/* Configure for RX */
|
||||||
|
|
|
@ -935,7 +935,7 @@ static void bam2bam_data_connect_work(struct work_struct *w)
|
||||||
| MSM_PRODUCER | d->src_pipe_idx;
|
| MSM_PRODUCER | d->src_pipe_idx;
|
||||||
d->rx_req->length = 32*1024;
|
d->rx_req->length = 32*1024;
|
||||||
d->rx_req->udc_priv = sps_params;
|
d->rx_req->udc_priv = sps_params;
|
||||||
msm_ep_config(port->port_usb->out, d->rx_req, GFP_ATOMIC);
|
msm_ep_config(port->port_usb->out, d->rx_req);
|
||||||
|
|
||||||
/* Configure TX */
|
/* Configure TX */
|
||||||
configure_usb_data_fifo(d->usb_bam_type,
|
configure_usb_data_fifo(d->usb_bam_type,
|
||||||
|
@ -945,7 +945,7 @@ static void bam2bam_data_connect_work(struct work_struct *w)
|
||||||
| d->dst_pipe_idx;
|
| d->dst_pipe_idx;
|
||||||
d->tx_req->length = 32*1024;
|
d->tx_req->length = 32*1024;
|
||||||
d->tx_req->udc_priv = sps_params;
|
d->tx_req->udc_priv = sps_params;
|
||||||
msm_ep_config(port->port_usb->in, d->tx_req, GFP_ATOMIC);
|
msm_ep_config(port->port_usb->in, d->tx_req);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
/* Configure RX */
|
/* Configure RX */
|
||||||
|
|
|
@ -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, port->rx_req, GFP_ATOMIC);
|
ret = msm_ep_config(gport->out, port->rx_req);
|
||||||
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, port->tx_req, GFP_ATOMIC);
|
ret = msm_ep_config(gport->in, port->tx_req);
|
||||||
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;
|
||||||
|
|
|
@ -99,7 +99,7 @@ static int init_data(struct usb_ep *ep)
|
||||||
|
|
||||||
pr_debug("init_data\n");
|
pr_debug("init_data\n");
|
||||||
|
|
||||||
res = msm_ep_config(ep, qdss->endless_req, GFP_ATOMIC);
|
res = msm_ep_config(ep, qdss->endless_req);
|
||||||
if (res)
|
if (res)
|
||||||
pr_err("msm_ep_config failed\n");
|
pr_err("msm_ep_config failed\n");
|
||||||
|
|
||||||
|
|
|
@ -296,8 +296,7 @@ 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, struct usb_request *request,
|
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,
|
||||||
|
@ -312,8 +311,7 @@ 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, struct usb_request *request,
|
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