Commit 719de070 authored by Niklas Neronin's avatar Niklas Neronin Committed by Greg Kroah-Hartman
Browse files

usb: xhci-pci: add support for hosts with zero USB3 ports

Add xhci support for PCI hosts that have zero USB3 ports.
Avoid creating a shared Host Controller Driver (HCD) when there is only
one root hub. Additionally, all references to 'xhci->shared_hcd' are now
checked before use.

Only xhci-pci.c requires modification to accommodate this change, as the
xhci core already supports configurations with zero USB3 ports. This
capability was introduced when xHCI Platform and MediaTek added support
for zero USB3 ports.

Closes: https://bugzilla.kernel.org/show_bug.cgi?id=220181


Tested-by: default avatarNick Nielsen <nick.kainielsen@free.fr>
Tested-by: default avatargrm1 <grm1@mailbox.org>
Signed-off-by: default avatarNiklas Neronin <niklas.neronin@linux.intel.com>
Signed-off-by: default avatarMathias Nyman <mathias.nyman@linux.intel.com>
Link: https://lore.kernel.org/r/20250917210726.97100-4-mathias.nyman@linux.intel.com


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 0ed023a8
Loading
Loading
Loading
Loading
+24 −18
Original line number Diff line number Diff line
@@ -610,7 +610,7 @@ int xhci_pci_common_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
	int retval;
	struct xhci_hcd *xhci;
	struct usb_hcd *hcd;
	struct usb_hcd *hcd, *usb3_hcd;
	struct reset_control *reset;

	reset = devm_reset_control_get_optional_exclusive(&dev->dev, NULL);
@@ -636,6 +636,9 @@ int xhci_pci_common_probe(struct pci_dev *dev, const struct pci_device_id *id)
	hcd = dev_get_drvdata(&dev->dev);
	xhci = hcd_to_xhci(hcd);
	xhci->reset = reset;

	xhci->allow_single_roothub = 1;
	if (!xhci_has_one_roothub(xhci)) {
		xhci->shared_hcd = usb_create_shared_hcd(&xhci_pci_hc_driver, &dev->dev,
							 pci_name(dev), hcd);
		if (!xhci->shared_hcd) {
@@ -647,15 +650,18 @@ int xhci_pci_common_probe(struct pci_dev *dev, const struct pci_device_id *id)
		if (retval)
			goto put_usb3_hcd;

	retval = usb_add_hcd(xhci->shared_hcd, dev->irq,
			IRQF_SHARED);
		retval = usb_add_hcd(xhci->shared_hcd, dev->irq, IRQF_SHARED);
		if (retval)
			goto put_usb3_hcd;
	/* Roothub already marked as USB 3.0 speed */
	} else {
		retval = xhci_ext_cap_init(xhci);
		if (retval)
			goto dealloc_usb2_hcd;
	}

	if (!(xhci->quirks & XHCI_BROKEN_STREAMS) &&
			HCC_MAX_PSA(xhci->hcc_params) >= 4)
		xhci->shared_hcd->can_do_streams = 1;
	usb3_hcd = xhci_get_usb3_hcd(xhci);
	if (usb3_hcd && !(xhci->quirks & XHCI_BROKEN_STREAMS) && HCC_MAX_PSA(xhci->hcc_params) >= 4)
		usb3_hcd->can_do_streams = 1;

	/* USB-2 and USB-3 roothubs initialized, allow runtime pm suspend */
	pm_runtime_put_noidle(&dev->dev);