Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 71218b2d authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge changes I7caef189,I6bf9510c,Ic624a9d6 into msm-4.14

* changes:
  USB: gsi: Use dma_get_sgtable() to update USB TRB ring and data buffer
  usb: f_gsi: Use gadget->dev.parent->parent instead of gadget->dev.parent
  dwc3-msm: Map IPA channel doorbell address with USB device
parents 4b7a3433 42e87d6b
Loading
Loading
Loading
Loading
+23 −4
Original line number Diff line number Diff line
@@ -1050,6 +1050,8 @@ static int gsi_prepare_trbs(struct usb_ep *ep, struct usb_gsi_request *req)
	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,
				num_trbs * sizeof(struct dwc3_trb),
@@ -1062,6 +1064,19 @@ static int gsi_prepare_trbs(struct usb_ep *ep, struct usb_gsi_request *req)
	}

	dep->num_trbs = num_trbs;
	dma_get_sgtable(dwc->sysdev, &req->sgt_trb_xfer_ring, dep->trb_pool,
		dep->trb_pool_dma, num_trbs * sizeof(struct dwc3_trb));

	sgt = &req->sgt_trb_xfer_ring;
	dev_dbg(dwc->dev, "%s(): trb_pool:%pK trb_pool_dma:%lx\n",
		__func__, dep->trb_pool, (unsigned long)dep->trb_pool_dma);

	for_each_sg(sgt->sgl, sg, sgt->nents, i)
		dev_dbg(dwc->dev,
			"%i: page_link:%lx offset:%x length:%x address:%lx\n",
			i, sg->page_link, sg->offset, sg->length,
			(unsigned long)sg->dma_address);

	/* IN direction */
	if (dep->direction) {
		for (i = 0; i < num_trbs ; i++) {
@@ -1127,11 +1142,13 @@ static int gsi_prepare_trbs(struct usb_ep *ep, struct usb_gsi_request *req)
		}
	}

	pr_debug("%s: Initialized TRB Ring for %s\n", __func__, dep->name);
	dev_dbg(dwc->dev, "%s: Initialized TRB Ring for %s\n",
					__func__, dep->name);
	trb = &dep->trb_pool[0];
	if (trb) {
		for (i = 0; i < num_trbs; i++) {
			pr_debug("TRB(%d): ADDRESS:%lx bpl:%x bph:%x size:%x ctrl:%x\n",
			dev_dbg(dwc->dev,
				"TRB %d: ADDR:%lx bpl:%x bph:%x sz:%x ctl:%x\n",
				i, (unsigned long)dwc3_trb_dma_offset(dep,
				&dep->trb_pool[i]), trb->bpl, trb->bph,
				trb->size, trb->ctrl);
@@ -1148,7 +1165,7 @@ static int gsi_prepare_trbs(struct usb_ep *ep, struct usb_gsi_request *req)
 * @usb_ep - pointer to usb_ep instance.
 *
 */
static void gsi_free_trbs(struct usb_ep *ep)
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;
@@ -1165,6 +1182,7 @@ static void gsi_free_trbs(struct usb_ep *ep)
		dep->trb_pool = NULL;
		dep->trb_pool_dma = 0;
	}
	sg_free_table(&req->sgt_trb_xfer_ring);
}
/**
 * Configures GSI EPs. For GSI EPs we need to set interrupter numbers.
@@ -1354,7 +1372,8 @@ static int dwc3_msm_gsi_ep_op(struct usb_ep *ep,
		break;
	case GSI_EP_OP_FREE_TRBS:
		dev_dbg(mdwc->dev, "EP_OP_FREE_TRBS for %s\n", ep->name);
		gsi_free_trbs(ep);
		request = (struct usb_gsi_request *)op_data;
		gsi_free_trbs(ep, request);
		break;
	case GSI_EP_OP_CONFIG:
		request = (struct usb_gsi_request *)op_data;
+56 −47
Original line number Diff line number Diff line
/*
 * Copyright (c) 2015-2017, Linux Foundation. All rights reserved.
 * Copyright (c) 2015-2018, 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
@@ -314,6 +314,10 @@ static int ipa_connect_channels(struct gsi_data_port *d_port)
	in_params->data_buff_base_len = d_port->in_request.buf_len *
					d_port->in_request.num_bufs;
	in_params->data_buff_base_addr_iova = d_port->in_request.dma;
	in_params->sgt_xfer_rings = &d_port->in_request.sgt_trb_xfer_ring;
	in_params->sgt_data_buff = &d_port->in_request.sgt_data_buff;
	log_event_dbg("%s(): IN: sgt_xfer_rings:%pK sgt_data_buff:%pK\n",
		__func__, in_params->sgt_xfer_rings, in_params->sgt_data_buff);
	in_params->xfer_scratch.const_buffer_size =
		gsi_channel_info.const_buffer_size;
	in_params->xfer_scratch.depcmd_low_addr =
@@ -351,6 +355,13 @@ static int ipa_connect_channels(struct gsi_data_port *d_port)
			d_port->out_request.num_bufs;
		out_params->data_buff_base_addr_iova =
			d_port->out_request.dma;
		out_params->sgt_xfer_rings =
			&d_port->out_request.sgt_trb_xfer_ring;
		out_params->sgt_data_buff = &d_port->out_request.sgt_data_buff;
		log_event_dbg("%s(): OUT: sgt_xfer_rings:%pK sgt_data_buff:%pK\n",
			__func__, out_params->sgt_xfer_rings,
			out_params->sgt_data_buff);

		out_params->xfer_scratch.last_trb_addr_iova =
			gsi_channel_info.last_trb_addr;
		out_params->xfer_scratch.const_buffer_size =
@@ -410,17 +421,17 @@ static int ipa_connect_channels(struct gsi_data_port *d_port)
			ipa_out_channel_out_params.db_reg_phs_addr_lsb);

	d_port->in_channel_handle = ipa_in_channel_out_params.clnt_hdl;
	d_port->in_db_reg_phs_addr_lsb =
	d_port->in_request.db_reg_phs_addr_lsb =
		ipa_in_channel_out_params.db_reg_phs_addr_lsb;
	d_port->in_db_reg_phs_addr_msb =
	d_port->in_request.db_reg_phs_addr_msb =
		ipa_in_channel_out_params.db_reg_phs_addr_msb;

	if (gsi->prot_id != IPA_USB_DIAG) {
		d_port->out_channel_handle =
			ipa_out_channel_out_params.clnt_hdl;
		d_port->out_db_reg_phs_addr_lsb =
		d_port->out_request.db_reg_phs_addr_lsb =
			ipa_out_channel_out_params.db_reg_phs_addr_lsb;
		d_port->out_db_reg_phs_addr_msb =
		d_port->out_request.db_reg_phs_addr_msb =
			ipa_out_channel_out_params.db_reg_phs_addr_msb;
	}
	return ret;
@@ -429,22 +440,19 @@ static int ipa_connect_channels(struct gsi_data_port *d_port)
static void ipa_data_path_enable(struct gsi_data_port *d_port)
{
	struct f_gsi *gsi = d_port_to_gsi(d_port);
	struct usb_gsi_request req;
	u64 dbl_register_addr;
	bool block_db = false;


	log_event_dbg("in_db_reg_phs_addr_lsb = %x",
			gsi->d_port.in_db_reg_phs_addr_lsb);
	log_event_dbg("IN: db_reg_phs_addr_lsb = %x",
			gsi->d_port.in_request.db_reg_phs_addr_lsb);
	usb_gsi_ep_op(gsi->d_port.in_ep,
			(void *)&gsi->d_port.in_db_reg_phs_addr_lsb,
			&gsi->d_port.in_request,
			GSI_EP_OP_STORE_DBL_INFO);

	if (gsi->d_port.out_ep) {
		log_event_dbg("out_db_reg_phs_addr_lsb = %x",
				gsi->d_port.out_db_reg_phs_addr_lsb);
		log_event_dbg("OUT: db_reg_phs_addr_lsb = %x",
				gsi->d_port.out_request.db_reg_phs_addr_lsb);
		usb_gsi_ep_op(gsi->d_port.out_ep,
				(void *)&gsi->d_port.out_db_reg_phs_addr_lsb,
				&gsi->d_port.out_request,
				GSI_EP_OP_STORE_DBL_INFO);

		usb_gsi_ep_op(gsi->d_port.out_ep, &gsi->d_port.out_request,
@@ -455,29 +463,12 @@ static void ipa_data_path_enable(struct gsi_data_port *d_port)
	usb_gsi_ep_op(d_port->in_ep, (void *)&block_db,
				GSI_EP_OP_SET_CLR_BLOCK_DBL);

	/* GSI channel DBL address for USB IN endpoint */
	dbl_register_addr = gsi->d_port.in_db_reg_phs_addr_msb;
	dbl_register_addr = dbl_register_addr << 32;
	dbl_register_addr =
		dbl_register_addr | gsi->d_port.in_db_reg_phs_addr_lsb;

	/* use temp gsi request to pass 64 bit dbl reg addr and num_bufs */
	req.buf_base_addr = &dbl_register_addr;
	usb_gsi_ep_op(gsi->d_port.in_ep, &gsi->d_port.in_request,
						GSI_EP_OP_RING_DB);

	req.num_bufs = gsi->d_port.in_request.num_bufs;
	usb_gsi_ep_op(gsi->d_port.in_ep, &req, GSI_EP_OP_RING_DB);

	if (gsi->d_port.out_ep) {
		/* GSI channel DBL address for USB OUT endpoint */
		dbl_register_addr = gsi->d_port.out_db_reg_phs_addr_msb;
		dbl_register_addr = dbl_register_addr << 32;
		dbl_register_addr = dbl_register_addr |
					gsi->d_port.out_db_reg_phs_addr_lsb;
		/* use temp request to pass 64 bit dbl reg addr and num_bufs */
		req.buf_base_addr = &dbl_register_addr;
		req.num_bufs = gsi->d_port.out_request.num_bufs;
		usb_gsi_ep_op(gsi->d_port.out_ep, &req, GSI_EP_OP_RING_DB);
	}
	if (gsi->d_port.out_ep)
		usb_gsi_ep_op(gsi->d_port.out_ep, &gsi->d_port.out_request,
						GSI_EP_OP_RING_DB);
}

static void ipa_disconnect_handler(struct gsi_data_port *d_port)
@@ -494,11 +485,13 @@ static void ipa_disconnect_handler(struct gsi_data_port *d_port)
		 */
		usb_gsi_ep_op(d_port->in_ep, (void *)&block_db,
				GSI_EP_OP_SET_CLR_BLOCK_DBL);
		usb_gsi_ep_op(gsi->d_port.in_ep, NULL, GSI_EP_OP_DISABLE);
		usb_gsi_ep_op(gsi->d_port.in_ep,
				&gsi->d_port.in_request, GSI_EP_OP_DISABLE);
	}

	if (gsi->d_port.out_ep)
		usb_gsi_ep_op(gsi->d_port.out_ep, NULL, GSI_EP_OP_DISABLE);
		usb_gsi_ep_op(gsi->d_port.out_ep,
				&gsi->d_port.out_request, GSI_EP_OP_DISABLE);

	gsi->d_port.net_ready_trigger = false;
}
@@ -522,10 +515,12 @@ static void ipa_disconnect_work_handler(struct gsi_data_port *d_port)
	gsi->d_port.in_channel_handle = -EINVAL;
	gsi->d_port.out_channel_handle = -EINVAL;

	usb_gsi_ep_op(gsi->d_port.in_ep, NULL, GSI_EP_OP_FREE_TRBS);
	usb_gsi_ep_op(gsi->d_port.in_ep, &gsi->d_port.in_request,
							GSI_EP_OP_FREE_TRBS);

	if (gsi->d_port.out_ep)
		usb_gsi_ep_op(gsi->d_port.out_ep, NULL, GSI_EP_OP_FREE_TRBS);
		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);
@@ -1962,9 +1957,11 @@ 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,
@@ -1973,7 +1970,7 @@ static int gsi_alloc_trb_buffer(struct f_gsi *gsi)
		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(gsi->d_port.gadget->dev.parent,
			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,
@@ -1982,6 +1979,11 @@ static int gsi_alloc_trb_buffer(struct f_gsi *gsi)
			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) {
@@ -1992,7 +1994,7 @@ static int gsi_alloc_trb_buffer(struct f_gsi *gsi)
		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(gsi->d_port.gadget->dev.parent,
			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,
@@ -2001,6 +2003,11 @@ static int gsi_alloc_trb_buffer(struct f_gsi *gsi)
			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");
@@ -2008,7 +2015,7 @@ static int gsi_alloc_trb_buffer(struct f_gsi *gsi)

fail:
	if (len_in && gsi->d_port.in_request.buf_base_addr) {
		dma_free_coherent(gsi->d_port.gadget->dev.parent, len_in,
		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;
@@ -2027,20 +2034,22 @@ static void gsi_free_trb_buffer(struct f_gsi *gsi)
			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, len,
		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, len,
		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);
	}
}

@@ -3010,7 +3019,7 @@ static ssize_t gsi_info_show(struct config_item *item, char *page)
				gsi->d_port.in_channel_handle);
		len += scnprintf(buf + len, PAGE_SIZE - len,
		"%25s %10x\n", "IN Chnl Dbl Addr: ",
				gsi->d_port.in_db_reg_phs_addr_lsb);
				gsi->d_port.in_request.db_reg_phs_addr_lsb);
		len += scnprintf(buf + len, PAGE_SIZE - len,
		"%25s %10u\n", "IN TRB Ring Len: ",
				ipa_chnl_params->xfer_ring_len);
@@ -3044,7 +3053,7 @@ static ssize_t gsi_info_show(struct config_item *item, char *page)
			gsi->d_port.out_channel_handle);
		len += scnprintf(buf + len, PAGE_SIZE - len,
		"%25s %10x\n", "OUT Channel Dbl Addr: ",
			gsi->d_port.out_db_reg_phs_addr_lsb);
			gsi->d_port.out_request.db_reg_phs_addr_lsb);
		len += scnprintf(buf + len, PAGE_SIZE - len,
		"%25s %10u\n", "OUT TRB Ring Len: ",
			ipa_chnl_params->xfer_ring_len);
+1 −5
Original line number Diff line number Diff line
/*
 * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
 * Copyright (c) 2015-2018, 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
@@ -218,10 +218,6 @@ struct gsi_data_port {
	struct ipa_usb_teth_params ipa_init_params;
	int in_channel_handle;
	int out_channel_handle;
	u32 in_db_reg_phs_addr_lsb;
	u32 in_db_reg_phs_addr_msb;
	u32 out_db_reg_phs_addr_lsb;
	u32 out_db_reg_phs_addr_msb;
	u32 in_xfer_rsc_index;
	u32 out_xfer_rsc_index;
	u16 in_last_trb_addr;
+4 −0
Original line number Diff line number Diff line
@@ -83,6 +83,8 @@ enum gsi_ep_op {
 * @db_reg_phs_addr_lsb: IPA channel doorbell register's physical address LSB
 * @mapped_db_reg_phs_addr_lsb: doorbell LSB IOVA address mapped with IOMMU
 * @db_reg_phs_addr_msb: IPA channel doorbell register's physical address MSB
 * @sgt_trb_xfer_ring: USB TRB ring related sgtable entries
 * @sgt_data_buff: Data buffer related sgtable entries
 */
struct usb_gsi_request {
	void *buf_base_addr;
@@ -92,6 +94,8 @@ struct usb_gsi_request {
	u32 db_reg_phs_addr_lsb;
	dma_addr_t mapped_db_reg_phs_addr_lsb;
	u32 db_reg_phs_addr_msb;
	struct sg_table sgt_trb_xfer_ring;
	struct sg_table sgt_data_buff;
};

/*