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

Commit cf77ecf3 authored by Kyle Yan's avatar Kyle Yan Committed by Gerrit - the friendly Code Review server
Browse files

Merge "usb: xhci: Clear event handler busy flag upon event ring cleanup" into msm-4.9

parents 536fcda4 873c6b36
Loading
Loading
Loading
Loading
+28 −2
Original line number Diff line number Diff line
@@ -1827,6 +1827,8 @@ void xhci_free_command(struct xhci_hcd *xhci,
int xhci_sec_event_ring_cleanup(struct usb_hcd *hcd, unsigned int intr_num)
{
	int size;
	u32 iman_reg;
	u64 erdp_reg;
	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
	struct device	*dev = xhci_to_hcd(xhci)->self.controller;

@@ -1838,14 +1840,38 @@ int xhci_sec_event_ring_cleanup(struct usb_hcd *hcd, unsigned int intr_num)

	size =
	sizeof(struct xhci_erst_entry)*(xhci->sec_erst[intr_num].num_entries);
	if (xhci->sec_erst[intr_num].entries)
	if (xhci->sec_erst[intr_num].entries) {
		/*
		 * disable irq, ack pending interrupt and clear EHB for xHC to
		 * generate interrupt again when new event ring is setup
		 */
		iman_reg =
			readl_relaxed(&xhci->sec_ir_set[intr_num]->irq_pending);
		iman_reg &= ~IMAN_IE;
		writel_relaxed(iman_reg,
				&xhci->sec_ir_set[intr_num]->irq_pending);
		iman_reg =
			readl_relaxed(&xhci->sec_ir_set[intr_num]->irq_pending);
		if (iman_reg & IMAN_IP)
			writel_relaxed(iman_reg,
				&xhci->sec_ir_set[intr_num]->irq_pending);
		/* make sure IP gets cleared before clearing EHB */
		mb();

		erdp_reg = xhci_read_64(xhci,
				&xhci->sec_ir_set[intr_num]->erst_dequeue);
		xhci_write_64(xhci, erdp_reg | ERST_EHB,
				&xhci->sec_ir_set[intr_num]->erst_dequeue);

		dma_free_coherent(dev, size, xhci->sec_erst[intr_num].entries,
				xhci->sec_erst[intr_num].erst_dma_addr);
		xhci->sec_erst[intr_num].entries = NULL;
	}
	xhci_dbg_trace(xhci, trace_xhci_dbg_init, "Freed SEC ERST#%d",
		intr_num);
	if (xhci->sec_event_ring[intr_num])
		xhci_ring_free(xhci, xhci->sec_event_ring[intr_num]);

	xhci->sec_event_ring[intr_num] = NULL;
	xhci_dbg_trace(xhci, trace_xhci_dbg_init,
		"Freed sec event ring");