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

Commit 123e80c4 authored by Vamsi Krishna's avatar Vamsi Krishna
Browse files

dwc3: gadget: Add support for no interrupt flag for sg reqs



Currently controller driver does not honor the no interrupt
flag from function driver and always sets LST (xfer complete) bit
on last request. High throughput functions like rndis/rmnet can
queue multiple requests and in some scenario endup with large
number requests pending with h/w. They will only be recycled after
hw completes the last request. Add support for no interrupt flag
flag for sg (scatter/gather) requests so that application driver
can decide when to generate interrupt. Controller will generate
xfer-in-progress event when ioc is set.

Change-Id: If02eb8602cafdbabf4bbe7f829711e9aaa304035
Signed-off-by: default avatarVamsi Krishna <vskrishn@codeaurora.org>
parent 5477461c
Loading
Loading
Loading
Loading
+13 −10
Original line number Diff line number Diff line
@@ -570,7 +570,7 @@ static int dwc3_gadget_set_ep_config(struct dwc3 *dwc, struct dwc3_ep *dep,
		dep->stream_capable = true;
	}

	if (usb_endpoint_xfer_isoc(desc))
	if (!usb_endpoint_xfer_control(desc))
		params.param1 |= DWC3_DEPCFG_XFER_IN_PROGRESS_EN;

	/*
@@ -859,7 +859,8 @@ static void dwc3_gadget_ep_free_request(struct usb_ep *ep,
 */
static void dwc3_prepare_one_trb(struct dwc3_ep *dep,
		struct dwc3_request *req, dma_addr_t dma,
		unsigned length, unsigned last, unsigned chain, unsigned node)
		unsigned length, unsigned last, unsigned chain, unsigned node,
		unsigned ioc)
{
	struct dwc3		*dwc = dep->dwc;
	struct dwc3_trb		*trb;
@@ -910,6 +911,8 @@ update_trb:
	case USB_ENDPOINT_XFER_BULK:
	case USB_ENDPOINT_XFER_INT:
		trb->ctrl = DWC3_TRBCTL_NORMAL;
		if (ioc)
			trb->ctrl |= DWC3_TRB_CTRL_IOC;
		break;
	default:
		/*
@@ -1052,6 +1055,7 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep, bool starting)

			for_each_sg(sg, s, request->num_mapped_sgs, i) {
				unsigned chain = true;
				unsigned	ioc = 0;

				length = sg_dma_len(s);
				dma = sg_dma_address(s);
@@ -1094,6 +1098,7 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep, bool starting)

					if (trbs_left <= temp)
						last_one = true;

				}

start_trb_queuing:
@@ -1104,8 +1109,12 @@ start_trb_queuing:
				if (last_one)
					chain = false;

				if (!last_one && !chain &&
					!request->no_interrupt)
					ioc = 1;

				dwc3_prepare_one_trb(dep, req, dma, length,
						last_one, chain, i);
						last_one, chain, i, ioc);

				if (last_one)
					break;
@@ -1139,7 +1148,7 @@ start_trb_queuing:
				last_one = 1;

			dwc3_prepare_one_trb(dep, req, dma, length,
					last_one, false, 0);
					last_one, false, 0, 0);

			dbg_queue(dep->number, &req->request, 0);
			if (last_one)
@@ -2483,12 +2492,6 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc,
		break;
	case DWC3_DEPEVT_XFERINPROGRESS:
		dep->dbg_ep_events.xferinprogress++;
		if (!usb_endpoint_xfer_isoc(dep->endpoint.desc)) {
			dev_dbg(dwc->dev, "%s is not an Isochronous endpoint\n",
					dep->name);
			return;
		}

		dwc3_endpoint_transfer_complete(dwc, dep, event, 0);
		break;
	case DWC3_DEPEVT_XFERNOTREADY: