Loading drivers/usb/dwc3/dwc3-msm.c +59 −9 Original line number Diff line number Diff line Loading @@ -338,6 +338,7 @@ struct dwc3_msm { enum usb_device_speed override_usb_speed; u32 *gsi_reg; int gsi_reg_offset_cnt; bool gsi_io_coherency_disabled; struct notifier_block dpdm_nb; struct regulator *dpdm_reg; Loading Loading @@ -1110,7 +1111,7 @@ static void gsi_endxfer_for_ep(struct usb_ep *ep) } /** * Allocates and configures TRBs for GSI EPs. * Allocates Buffers and TRBs. Configures TRBs for GSI EPs. * * @usb_ep - pointer to usb_ep instance. * @request - pointer to GSI request. Loading @@ -1120,23 +1121,49 @@ static void gsi_endxfer_for_ep(struct usb_ep *ep) static int gsi_prepare_trbs(struct usb_ep *ep, struct usb_gsi_request *req) { int i = 0; dma_addr_t buffer_addr = req->dma; size_t len; unsigned long dma_attr; dma_addr_t buffer_addr; struct dwc3_ep *dep = to_dwc3_ep(ep); struct dwc3 *dwc = dep->dwc; struct dwc3_msm *mdwc = dev_get_drvdata(dwc->dev->parent); struct dwc3_trb *trb; int num_trbs = (dep->direction) ? (2 * (req->num_bufs) + 2) : (req->num_bufs + 2); struct scatterlist *sg; struct sg_table *sgt; dep->trb_pool = dma_zalloc_coherent(dwc->sysdev, if (mdwc->gsi_io_coherency_disabled) dma_attr = DMA_ATTR_FORCE_NON_COHERENT; else dma_attr = DMA_ATTR_FORCE_COHERENT; /* Allocate TRB buffers */ len = req->buf_len * req->num_bufs; req->buf_base_addr = dma_alloc_attrs(dwc->sysdev, len, &req->dma, GFP_KERNEL, dma_attr); if (!req->buf_base_addr) { dev_err(dwc->dev, "%s: buf_base_addr allocate failed %s\n", dep->name); return -ENOMEM; } dma_get_sgtable(dwc->sysdev, &req->sgt_data_buff, req->buf_base_addr, req->dma, len); buffer_addr = req->dma; /* Allocate and configgure TRBs */ dep->trb_pool = dma_alloc_attrs(dwc->sysdev, num_trbs * sizeof(struct dwc3_trb), &dep->trb_pool_dma, GFP_KERNEL); &dep->trb_pool_dma, GFP_KERNEL, dma_attr); if (!dep->trb_pool) { dev_err(dep->dwc->dev, "failed to alloc trb dma pool for %s\n", dep->name); return -ENOMEM; goto free_trb_buffer; } dep->num_trbs = num_trbs; Loading Loading @@ -1233,10 +1260,17 @@ static int gsi_prepare_trbs(struct usb_ep *ep, struct usb_gsi_request *req) } return 0; free_trb_buffer: dma_free_attrs(dwc->sysdev, len, req->buf_base_addr, req->dma, dma_attr); req->buf_base_addr = NULL; sg_free_table(&req->sgt_data_buff); return -ENOMEM; } /** * Frees TRBs for GSI EPs. * Frees TRBs and buffers for GSI EPs. * * @usb_ep - pointer to usb_ep instance. * Loading @@ -1245,20 +1279,32 @@ static void gsi_free_trbs(struct usb_ep *ep, struct usb_gsi_request *req) { struct dwc3_ep *dep = to_dwc3_ep(ep); struct dwc3 *dwc = dep->dwc; struct dwc3_msm *mdwc = dev_get_drvdata(dwc->dev->parent); unsigned long dma_attr; if (dep->endpoint.ep_type == EP_TYPE_NORMAL) return; if (mdwc->gsi_io_coherency_disabled) dma_attr = DMA_ATTR_FORCE_NON_COHERENT; else dma_attr = DMA_ATTR_FORCE_COHERENT; /* Free TRBs and TRB pool for EP */ if (dep->trb_pool_dma) { dma_free_coherent(dwc->sysdev, dma_free_attrs(dwc->sysdev, dep->num_trbs * sizeof(struct dwc3_trb), dep->trb_pool, dep->trb_pool_dma); dep->trb_pool, dep->trb_pool_dma, dma_attr); dep->trb_pool = NULL; dep->trb_pool_dma = 0; } sg_free_table(&req->sgt_trb_xfer_ring); /* free TRB buffers */ dma_free_attrs(dwc->sysdev, req->buf_len * req->num_bufs, req->buf_base_addr, req->dma, dma_attr); req->buf_base_addr = NULL; sg_free_table(&req->sgt_data_buff); } /** * Configures GSI EPs. For GSI EPs we need to set interrupter numbers. Loading Loading @@ -3585,6 +3631,10 @@ static int dwc3_msm_probe(struct platform_device *pdev) mdwc->use_pdc_interrupts = of_property_read_bool(node, "qcom,use-pdc-interrupts"); mdwc->gsi_io_coherency_disabled = of_property_read_bool(node, "qcom,gsi-disable-io-coherency"); dwc3_set_notifier(&dwc3_msm_notify_event); if (dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64))) { Loading drivers/usb/gadget/function/f_gsi.c +6 −121 Original line number Diff line number Diff line Loading @@ -34,8 +34,6 @@ static DEFINE_IDA(gsi_ida); static void gsi_inst_clean(struct gsi_opts *opts); static void gsi_rndis_ipa_reset_trigger(struct gsi_data_port *d_port); static int gsi_ctrl_send_notification(struct f_gsi *gsi); static int gsi_alloc_trb_buffer(struct f_gsi *gsi); static void gsi_free_trb_buffer(struct f_gsi *gsi); static struct gsi_ctrl_pkt *gsi_ctrl_pkt_alloc(unsigned int len, gfp_t flags); static void gsi_ctrl_pkt_free(struct gsi_ctrl_pkt *pkt); Loading Loading @@ -486,7 +484,9 @@ static int ipa_connect_channels(struct gsi_data_port *d_port) struct ipa_req_chan_out_params ipa_in_channel_out_params; struct ipa_req_chan_out_params ipa_out_channel_out_params; log_event_dbg("%s: USB GSI IN OPS", __func__); log_event_dbg("IN: num_bufs:=%zu, buf_len=%zu\n", d_port->in_request.num_bufs, d_port->in_request.buf_len); usb_gsi_ep_op(d_port->in_ep, &d_port->in_request, GSI_EP_OP_PREPARE_TRBS); usb_gsi_ep_op(d_port->in_ep, &d_port->in_request, Loading Loading @@ -530,7 +530,9 @@ static int ipa_connect_channels(struct gsi_data_port *d_port) gsi_channel_info.depcmd_hi_addr; if (d_port->out_ep) { log_event_dbg("%s: USB GSI OUT OPS", __func__); log_event_dbg("OUT: num_bufs:=%zu, buf_len=%zu\n", d_port->out_request.num_bufs, d_port->out_request.buf_len); usb_gsi_ep_op(d_port->out_ep, &d_port->out_request, GSI_EP_OP_PREPARE_TRBS); usb_gsi_ep_op(d_port->out_ep, &d_port->out_request, Loading Loading @@ -721,9 +723,6 @@ static void ipa_disconnect_channel(struct gsi_data_port *d_port) if (gsi->d_port.out_ep) usb_gsi_ep_op(gsi->d_port.out_ep, &gsi->d_port.out_request, GSI_EP_OP_FREE_TRBS); /* free buffers allocated with each TRB */ gsi_free_trb_buffer(gsi); } static int ipa_suspend_work_handler(struct gsi_data_port *d_port) Loading Loading @@ -883,13 +882,6 @@ static void ipa_work_handler(struct work_struct *w) break; } /* allocate buffers used with each TRB */ ret = gsi_alloc_trb_buffer(gsi); if (ret) { log_event_err("%s: gsi_alloc_trb_failed\n", __func__); break; } ipa_connect_channels(d_port); d_port->sm_state = STATE_WAIT_FOR_IPA_RDY; log_event_dbg("%s: ST_INIT_EVT_SET_ALT", Loading Loading @@ -1028,13 +1020,6 @@ static void ipa_work_handler(struct work_struct *w) usb_gadget_autopm_get(d_port->gadget); log_event_dbg("%s: get = %d", __func__, atomic_read(&gad_dev->power.usage_count)); /* allocate buffers used with each TRB */ ret = gsi_alloc_trb_buffer(gsi); if (ret) { log_event_err("%s: gsi_alloc_trb_failed\n", __func__); break; } ipa_connect_channels(d_port); ipa_data_path_enable(d_port); Loading Loading @@ -2260,106 +2245,6 @@ static int gsi_get_alt(struct usb_function *f, unsigned int intf) return -EINVAL; } static int gsi_alloc_trb_buffer(struct f_gsi *gsi) { u32 len_in = 0, len_out = 0; int ret = 0; struct device *dev; log_event_dbg("allocate trb's buffer\n"); dev = gsi->d_port.gadget->dev.parent; if (gsi->d_port.in_ep && !gsi->d_port.in_request.buf_base_addr) { log_event_dbg("IN: num_bufs:=%zu, buf_len=%zu\n", gsi->d_port.in_request.num_bufs, gsi->d_port.in_request.buf_len); len_in = gsi->d_port.in_request.buf_len * gsi->d_port.in_request.num_bufs; gsi->d_port.in_request.buf_base_addr = dma_zalloc_coherent(dev->parent, len_in, &gsi->d_port.in_request.dma, GFP_KERNEL); if (!gsi->d_port.in_request.buf_base_addr) { dev_err(&gsi->d_port.gadget->dev, "IN buf_base_addr allocate failed %s\n", gsi->function.name); ret = -ENOMEM; goto fail1; } dma_get_sgtable(dev->parent, &gsi->d_port.in_request.sgt_data_buff, gsi->d_port.in_request.buf_base_addr, gsi->d_port.in_request.dma, len_in); } if (gsi->d_port.out_ep && !gsi->d_port.out_request.buf_base_addr) { log_event_dbg("OUT: num_bufs:=%zu, buf_len=%zu\n", gsi->d_port.out_request.num_bufs, gsi->d_port.out_request.buf_len); len_out = gsi->d_port.out_request.buf_len * gsi->d_port.out_request.num_bufs; gsi->d_port.out_request.buf_base_addr = dma_zalloc_coherent(dev->parent, len_out, &gsi->d_port.out_request.dma, GFP_KERNEL); if (!gsi->d_port.out_request.buf_base_addr) { dev_err(&gsi->d_port.gadget->dev, "OUT buf_base_addr allocate failed %s\n", gsi->function.name); ret = -ENOMEM; goto fail; } dma_get_sgtable(dev->parent, &gsi->d_port.out_request.sgt_data_buff, gsi->d_port.out_request.buf_base_addr, gsi->d_port.out_request.dma, len_out); } log_event_dbg("finished allocating trb's buffer\n"); return ret; fail: if (len_in && gsi->d_port.in_request.buf_base_addr) { dma_free_coherent(dev->parent, len_in, gsi->d_port.in_request.buf_base_addr, gsi->d_port.in_request.dma); gsi->d_port.in_request.buf_base_addr = NULL; } fail1: return ret; } static void gsi_free_trb_buffer(struct f_gsi *gsi) { u32 len; log_event_dbg("freeing trb's buffer\n"); if (gsi->d_port.out_ep && gsi->d_port.out_request.buf_base_addr) { len = gsi->d_port.out_request.buf_len * gsi->d_port.out_request.num_bufs; dma_free_coherent(gsi->d_port.gadget->dev.parent->parent, len, gsi->d_port.out_request.buf_base_addr, gsi->d_port.out_request.dma); gsi->d_port.out_request.buf_base_addr = NULL; sg_free_table(&gsi->d_port.out_request.sgt_data_buff); } if (gsi->d_port.in_ep && gsi->d_port.in_request.buf_base_addr) { len = gsi->d_port.in_request.buf_len * gsi->d_port.in_request.num_bufs; dma_free_coherent(gsi->d_port.gadget->dev.parent->parent, len, gsi->d_port.in_request.buf_base_addr, gsi->d_port.in_request.dma); gsi->d_port.in_request.buf_base_addr = NULL; sg_free_table(&gsi->d_port.in_request.sgt_data_buff); } } static int gsi_set_alt(struct usb_function *f, unsigned int intf, unsigned int alt) { Loading Loading
drivers/usb/dwc3/dwc3-msm.c +59 −9 Original line number Diff line number Diff line Loading @@ -338,6 +338,7 @@ struct dwc3_msm { enum usb_device_speed override_usb_speed; u32 *gsi_reg; int gsi_reg_offset_cnt; bool gsi_io_coherency_disabled; struct notifier_block dpdm_nb; struct regulator *dpdm_reg; Loading Loading @@ -1110,7 +1111,7 @@ static void gsi_endxfer_for_ep(struct usb_ep *ep) } /** * Allocates and configures TRBs for GSI EPs. * Allocates Buffers and TRBs. Configures TRBs for GSI EPs. * * @usb_ep - pointer to usb_ep instance. * @request - pointer to GSI request. Loading @@ -1120,23 +1121,49 @@ static void gsi_endxfer_for_ep(struct usb_ep *ep) static int gsi_prepare_trbs(struct usb_ep *ep, struct usb_gsi_request *req) { int i = 0; dma_addr_t buffer_addr = req->dma; size_t len; unsigned long dma_attr; dma_addr_t buffer_addr; struct dwc3_ep *dep = to_dwc3_ep(ep); struct dwc3 *dwc = dep->dwc; struct dwc3_msm *mdwc = dev_get_drvdata(dwc->dev->parent); struct dwc3_trb *trb; int num_trbs = (dep->direction) ? (2 * (req->num_bufs) + 2) : (req->num_bufs + 2); struct scatterlist *sg; struct sg_table *sgt; dep->trb_pool = dma_zalloc_coherent(dwc->sysdev, if (mdwc->gsi_io_coherency_disabled) dma_attr = DMA_ATTR_FORCE_NON_COHERENT; else dma_attr = DMA_ATTR_FORCE_COHERENT; /* Allocate TRB buffers */ len = req->buf_len * req->num_bufs; req->buf_base_addr = dma_alloc_attrs(dwc->sysdev, len, &req->dma, GFP_KERNEL, dma_attr); if (!req->buf_base_addr) { dev_err(dwc->dev, "%s: buf_base_addr allocate failed %s\n", dep->name); return -ENOMEM; } dma_get_sgtable(dwc->sysdev, &req->sgt_data_buff, req->buf_base_addr, req->dma, len); buffer_addr = req->dma; /* Allocate and configgure TRBs */ dep->trb_pool = dma_alloc_attrs(dwc->sysdev, num_trbs * sizeof(struct dwc3_trb), &dep->trb_pool_dma, GFP_KERNEL); &dep->trb_pool_dma, GFP_KERNEL, dma_attr); if (!dep->trb_pool) { dev_err(dep->dwc->dev, "failed to alloc trb dma pool for %s\n", dep->name); return -ENOMEM; goto free_trb_buffer; } dep->num_trbs = num_trbs; Loading Loading @@ -1233,10 +1260,17 @@ static int gsi_prepare_trbs(struct usb_ep *ep, struct usb_gsi_request *req) } return 0; free_trb_buffer: dma_free_attrs(dwc->sysdev, len, req->buf_base_addr, req->dma, dma_attr); req->buf_base_addr = NULL; sg_free_table(&req->sgt_data_buff); return -ENOMEM; } /** * Frees TRBs for GSI EPs. * Frees TRBs and buffers for GSI EPs. * * @usb_ep - pointer to usb_ep instance. * Loading @@ -1245,20 +1279,32 @@ static void gsi_free_trbs(struct usb_ep *ep, struct usb_gsi_request *req) { struct dwc3_ep *dep = to_dwc3_ep(ep); struct dwc3 *dwc = dep->dwc; struct dwc3_msm *mdwc = dev_get_drvdata(dwc->dev->parent); unsigned long dma_attr; if (dep->endpoint.ep_type == EP_TYPE_NORMAL) return; if (mdwc->gsi_io_coherency_disabled) dma_attr = DMA_ATTR_FORCE_NON_COHERENT; else dma_attr = DMA_ATTR_FORCE_COHERENT; /* Free TRBs and TRB pool for EP */ if (dep->trb_pool_dma) { dma_free_coherent(dwc->sysdev, dma_free_attrs(dwc->sysdev, dep->num_trbs * sizeof(struct dwc3_trb), dep->trb_pool, dep->trb_pool_dma); dep->trb_pool, dep->trb_pool_dma, dma_attr); dep->trb_pool = NULL; dep->trb_pool_dma = 0; } sg_free_table(&req->sgt_trb_xfer_ring); /* free TRB buffers */ dma_free_attrs(dwc->sysdev, req->buf_len * req->num_bufs, req->buf_base_addr, req->dma, dma_attr); req->buf_base_addr = NULL; sg_free_table(&req->sgt_data_buff); } /** * Configures GSI EPs. For GSI EPs we need to set interrupter numbers. Loading Loading @@ -3585,6 +3631,10 @@ static int dwc3_msm_probe(struct platform_device *pdev) mdwc->use_pdc_interrupts = of_property_read_bool(node, "qcom,use-pdc-interrupts"); mdwc->gsi_io_coherency_disabled = of_property_read_bool(node, "qcom,gsi-disable-io-coherency"); dwc3_set_notifier(&dwc3_msm_notify_event); if (dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64))) { Loading
drivers/usb/gadget/function/f_gsi.c +6 −121 Original line number Diff line number Diff line Loading @@ -34,8 +34,6 @@ static DEFINE_IDA(gsi_ida); static void gsi_inst_clean(struct gsi_opts *opts); static void gsi_rndis_ipa_reset_trigger(struct gsi_data_port *d_port); static int gsi_ctrl_send_notification(struct f_gsi *gsi); static int gsi_alloc_trb_buffer(struct f_gsi *gsi); static void gsi_free_trb_buffer(struct f_gsi *gsi); static struct gsi_ctrl_pkt *gsi_ctrl_pkt_alloc(unsigned int len, gfp_t flags); static void gsi_ctrl_pkt_free(struct gsi_ctrl_pkt *pkt); Loading Loading @@ -486,7 +484,9 @@ static int ipa_connect_channels(struct gsi_data_port *d_port) struct ipa_req_chan_out_params ipa_in_channel_out_params; struct ipa_req_chan_out_params ipa_out_channel_out_params; log_event_dbg("%s: USB GSI IN OPS", __func__); log_event_dbg("IN: num_bufs:=%zu, buf_len=%zu\n", d_port->in_request.num_bufs, d_port->in_request.buf_len); usb_gsi_ep_op(d_port->in_ep, &d_port->in_request, GSI_EP_OP_PREPARE_TRBS); usb_gsi_ep_op(d_port->in_ep, &d_port->in_request, Loading Loading @@ -530,7 +530,9 @@ static int ipa_connect_channels(struct gsi_data_port *d_port) gsi_channel_info.depcmd_hi_addr; if (d_port->out_ep) { log_event_dbg("%s: USB GSI OUT OPS", __func__); log_event_dbg("OUT: num_bufs:=%zu, buf_len=%zu\n", d_port->out_request.num_bufs, d_port->out_request.buf_len); usb_gsi_ep_op(d_port->out_ep, &d_port->out_request, GSI_EP_OP_PREPARE_TRBS); usb_gsi_ep_op(d_port->out_ep, &d_port->out_request, Loading Loading @@ -721,9 +723,6 @@ static void ipa_disconnect_channel(struct gsi_data_port *d_port) if (gsi->d_port.out_ep) usb_gsi_ep_op(gsi->d_port.out_ep, &gsi->d_port.out_request, GSI_EP_OP_FREE_TRBS); /* free buffers allocated with each TRB */ gsi_free_trb_buffer(gsi); } static int ipa_suspend_work_handler(struct gsi_data_port *d_port) Loading Loading @@ -883,13 +882,6 @@ static void ipa_work_handler(struct work_struct *w) break; } /* allocate buffers used with each TRB */ ret = gsi_alloc_trb_buffer(gsi); if (ret) { log_event_err("%s: gsi_alloc_trb_failed\n", __func__); break; } ipa_connect_channels(d_port); d_port->sm_state = STATE_WAIT_FOR_IPA_RDY; log_event_dbg("%s: ST_INIT_EVT_SET_ALT", Loading Loading @@ -1028,13 +1020,6 @@ static void ipa_work_handler(struct work_struct *w) usb_gadget_autopm_get(d_port->gadget); log_event_dbg("%s: get = %d", __func__, atomic_read(&gad_dev->power.usage_count)); /* allocate buffers used with each TRB */ ret = gsi_alloc_trb_buffer(gsi); if (ret) { log_event_err("%s: gsi_alloc_trb_failed\n", __func__); break; } ipa_connect_channels(d_port); ipa_data_path_enable(d_port); Loading Loading @@ -2260,106 +2245,6 @@ static int gsi_get_alt(struct usb_function *f, unsigned int intf) return -EINVAL; } static int gsi_alloc_trb_buffer(struct f_gsi *gsi) { u32 len_in = 0, len_out = 0; int ret = 0; struct device *dev; log_event_dbg("allocate trb's buffer\n"); dev = gsi->d_port.gadget->dev.parent; if (gsi->d_port.in_ep && !gsi->d_port.in_request.buf_base_addr) { log_event_dbg("IN: num_bufs:=%zu, buf_len=%zu\n", gsi->d_port.in_request.num_bufs, gsi->d_port.in_request.buf_len); len_in = gsi->d_port.in_request.buf_len * gsi->d_port.in_request.num_bufs; gsi->d_port.in_request.buf_base_addr = dma_zalloc_coherent(dev->parent, len_in, &gsi->d_port.in_request.dma, GFP_KERNEL); if (!gsi->d_port.in_request.buf_base_addr) { dev_err(&gsi->d_port.gadget->dev, "IN buf_base_addr allocate failed %s\n", gsi->function.name); ret = -ENOMEM; goto fail1; } dma_get_sgtable(dev->parent, &gsi->d_port.in_request.sgt_data_buff, gsi->d_port.in_request.buf_base_addr, gsi->d_port.in_request.dma, len_in); } if (gsi->d_port.out_ep && !gsi->d_port.out_request.buf_base_addr) { log_event_dbg("OUT: num_bufs:=%zu, buf_len=%zu\n", gsi->d_port.out_request.num_bufs, gsi->d_port.out_request.buf_len); len_out = gsi->d_port.out_request.buf_len * gsi->d_port.out_request.num_bufs; gsi->d_port.out_request.buf_base_addr = dma_zalloc_coherent(dev->parent, len_out, &gsi->d_port.out_request.dma, GFP_KERNEL); if (!gsi->d_port.out_request.buf_base_addr) { dev_err(&gsi->d_port.gadget->dev, "OUT buf_base_addr allocate failed %s\n", gsi->function.name); ret = -ENOMEM; goto fail; } dma_get_sgtable(dev->parent, &gsi->d_port.out_request.sgt_data_buff, gsi->d_port.out_request.buf_base_addr, gsi->d_port.out_request.dma, len_out); } log_event_dbg("finished allocating trb's buffer\n"); return ret; fail: if (len_in && gsi->d_port.in_request.buf_base_addr) { dma_free_coherent(dev->parent, len_in, gsi->d_port.in_request.buf_base_addr, gsi->d_port.in_request.dma); gsi->d_port.in_request.buf_base_addr = NULL; } fail1: return ret; } static void gsi_free_trb_buffer(struct f_gsi *gsi) { u32 len; log_event_dbg("freeing trb's buffer\n"); if (gsi->d_port.out_ep && gsi->d_port.out_request.buf_base_addr) { len = gsi->d_port.out_request.buf_len * gsi->d_port.out_request.num_bufs; dma_free_coherent(gsi->d_port.gadget->dev.parent->parent, len, gsi->d_port.out_request.buf_base_addr, gsi->d_port.out_request.dma); gsi->d_port.out_request.buf_base_addr = NULL; sg_free_table(&gsi->d_port.out_request.sgt_data_buff); } if (gsi->d_port.in_ep && gsi->d_port.in_request.buf_base_addr) { len = gsi->d_port.in_request.buf_len * gsi->d_port.in_request.num_bufs; dma_free_coherent(gsi->d_port.gadget->dev.parent->parent, len, gsi->d_port.in_request.buf_base_addr, gsi->d_port.in_request.dma); gsi->d_port.in_request.buf_base_addr = NULL; sg_free_table(&gsi->d_port.in_request.sgt_data_buff); } } static int gsi_set_alt(struct usb_function *f, unsigned int intf, unsigned int alt) { Loading