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

Commit 677bcd72 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "usb: XHCI: Implement xhci_handshake_check_state() API"

parents 759499e7 40ca9e4e
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -351,13 +351,13 @@ static int xhci_abort_cmd_ring(struct xhci_hcd *xhci, unsigned long flags)
			&xhci->op_regs->cmd_ring);

	/* Section 4.6.1.2 of xHCI 1.0 spec says software should also time the
	 * completion of the Command Abort operation. If CRR is not negated in 5
	 * seconds then driver handles it as if host died (-ENODEV).
	 * completion of the Command Abort operation. If CRR is not negated in a
	 * timely manner then driver handles it as if host died (-ENODEV).
	 * In the future we should distinguish between -ENODEV and -ETIMEDOUT
	 * and try to recover a -ETIMEDOUT with a host controller reset.
	 */
	ret = xhci_handshake(&xhci->op_regs->cmd_ring,
			CMD_RING_RUNNING, 0, 5 * 1000 * 1000);
	ret = xhci_handshake_check_state(xhci, &xhci->op_regs->cmd_ring,
			CMD_RING_RUNNING, 0, 1000 * 1000);
	if (ret < 0) {
		xhci_err(xhci, "Abort failed to stop command ring: %d\n", ret);
		xhci_halt(xhci);
+22 −1
Original line number Diff line number Diff line
@@ -83,6 +83,27 @@ int xhci_handshake(void __iomem *ptr, u32 mask, u32 done, int usec)
	return -ETIMEDOUT;
}

int xhci_handshake_check_state(struct xhci_hcd *xhci,
		void __iomem *ptr, u32 mask, u32 done, int usec)
{
	u32	result;

	do {
		result = readl_relaxed(ptr);
		if (result == ~(u32)0)	/* card removed */
			return -ENODEV;
		/* host removed. Bail out */
		if (xhci->xhc_state & XHCI_STATE_REMOVING)
			return -ENODEV;
		result &= mask;
		if (result == done)
			return 0;
		udelay(1);
		usec--;
	} while (usec > 0);
	return -ETIMEDOUT;
}

/*
 * Disable interrupts and begin the xHCI halting process.
 */
@@ -206,7 +227,7 @@ int xhci_reset(struct xhci_hcd *xhci)
	if (xhci->quirks & XHCI_INTEL_HOST)
		udelay(1000);

	ret = xhci_handshake(&xhci->op_regs->command,
	ret = xhci_handshake_check_state(xhci, &xhci->op_regs->command,
			CMD_RESET, 0, 10 * 1000 * 1000);
	if (ret)
		return ret;
+2 −0
Original line number Diff line number Diff line
@@ -2040,6 +2040,8 @@ int xhci_sec_event_ring_cleanup(struct usb_hcd *hcd, unsigned int intr_num);
/* xHCI host controller glue */
typedef void (*xhci_get_quirks_t)(struct device *, struct xhci_hcd *);
int xhci_handshake(void __iomem *ptr, u32 mask, u32 done, int usec);
int xhci_handshake_check_state(struct xhci_hcd *xhci,
		void __iomem *ptr, u32 mask, u32 done, int usec);
void xhci_quiesce(struct xhci_hcd *xhci);
int xhci_halt(struct xhci_hcd *xhci);
int xhci_start(struct xhci_hcd *xhci);