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

Commit 80922d7b authored by Puma Hsu's avatar Puma Hsu Committed by Greg Kroah-Hartman
Browse files

xhci: re-initialize the HC during resume if HCE was set



commit 8b328f8002bcf29ef517ee4bf234e09aabec4d2e upstream.

When HCE(Host Controller Error) is set, it means an internal
error condition has been detected. Software needs to re-initialize
the HC, so add this check in xhci resume.

Cc: stable@vger.kernel.org
Signed-off-by: default avatarPuma Hsu <pumahsu@google.com>
Signed-off-by: default avatarMathias Nyman <mathias.nyman@linux.intel.com>
Link: https://lore.kernel.org/r/20220215123320.1253947-2-mathias.nyman@linux.intel.com


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 0139a100
Loading
Loading
Loading
Loading
+13 −6
Original line number Diff line number Diff line
@@ -1091,6 +1091,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
	int			retval = 0;
	bool			comp_timer_running = false;
	bool			pending_portevent = false;
	bool			reinit_xhc = false;

	if (!hcd->state)
		return 0;
@@ -1107,10 +1108,11 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
	set_bit(HCD_FLAG_HW_ACCESSIBLE, &xhci->shared_hcd->flags);

	spin_lock_irq(&xhci->lock);
	if ((xhci->quirks & XHCI_RESET_ON_RESUME) || xhci->broken_suspend)
		hibernated = true;

	if (!hibernated) {
	if (hibernated || xhci->quirks & XHCI_RESET_ON_RESUME || xhci->broken_suspend)
		reinit_xhc = true;

	if (!reinit_xhc) {
		/*
		 * Some controllers might lose power during suspend, so wait
		 * for controller not ready bit to clear, just as in xHC init.
@@ -1143,12 +1145,17 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
			spin_unlock_irq(&xhci->lock);
			return -ETIMEDOUT;
		}
		temp = readl(&xhci->op_regs->status);
	}

	/* If restore operation fails, re-initialize the HC during resume */
	if ((temp & STS_SRE) || hibernated) {
	temp = readl(&xhci->op_regs->status);

	/* re-initialize the HC on Restore Error, or Host Controller Error */
	if (temp & (STS_SRE | STS_HCE)) {
		reinit_xhc = true;
		xhci_warn(xhci, "xHC error in resume, USBSTS 0x%x, Reinit\n", temp);
	}

	if (reinit_xhc) {
		if ((xhci->quirks & XHCI_COMP_MODE_QUIRK) &&
				!(xhci_all_ports_seen_u0(xhci))) {
			del_timer_sync(&xhci->comp_mode_recovery_timer);