seems like a better use for the driver_data field. It also helps decoupling PCI from XHCI-specific ->setup function. Signed-off-by: Felipe Balbi <balbi@xxxxxx> --- drivers/usb/host/xhci-pci.c | 116 +++++++++++++++++++++++++++---------------- 1 files changed, 73 insertions(+), 43 deletions(-) diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 724f09f..da7bde8 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -107,42 +107,6 @@ static int xhci_pci_setup(struct usb_hcd *hcd) xhci->hcc_params = xhci_readl(xhci, &xhci->cap_regs->hcc_params); xhci_print_registers(xhci); - /* Look for vendor-specific quirks */ - if (pdev->vendor == PCI_VENDOR_ID_FRESCO_LOGIC && - pdev->device == PCI_DEVICE_ID_FRESCO_LOGIC_PDK) { - if (pdev->revision == 0x0) { - xhci->quirks |= XHCI_RESET_EP_QUIRK; - xhci_dbg(xhci, "QUIRK: Fresco Logic xHC needs configure" - " endpoint cmd after reset endpoint\n"); - } - /* Fresco Logic confirms: all revisions of this chip do not - * support MSI, even though some of them claim to in their PCI - * capabilities. - */ - xhci->quirks |= XHCI_BROKEN_MSI; - xhci_dbg(xhci, "QUIRK: Fresco Logic revision %u " - "has broken MSI implementation\n", - pdev->revision); - } - - if (pdev->vendor == PCI_VENDOR_ID_NEC) - xhci->quirks |= XHCI_NEC_HOST; - - /* AMD PLL quirk */ - if (pdev->vendor == PCI_VENDOR_ID_AMD && usb_amd_find_chipset_info()) - xhci->quirks |= XHCI_AMD_PLL_FIX; - if (pdev->vendor == PCI_VENDOR_ID_INTEL && - pdev->device == PCI_DEVICE_ID_INTEL_PANTHERPOINT_XHCI) { - xhci->quirks |= XHCI_SPURIOUS_SUCCESS; - xhci->quirks |= XHCI_EP_LIMIT_QUIRK; - xhci->limit_active_eps = 64; - } - if (pdev->vendor == PCI_VENDOR_ID_ETRON && - pdev->device == PCI_DEVICE_ID_ASROCK_P67) { - xhci->quirks |= XHCI_RESET_ON_RESUME; - xhci_dbg(xhci, "QUIRK: Resetting on resume\n"); - } - /* Make sure the HC is halted. */ retval = xhci_halt(xhci); if (retval) @@ -183,20 +147,16 @@ error: return retval; } -static const struct hc_driver xhci_pci_hc_driver; - -/* - * We need to register our own PCI probe function (instead of the USB core's - * function) in order to create a second roothub under xHCI. - */ static int xhci_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) { int retval; struct xhci_hcd *xhci; const struct hc_driver *driver; struct usb_hcd *hcd; + struct xhci_platform_data *data; - driver = &xhci_pci_hc_driver; + data = (struct xhci_platform_data *) id->driver_data; + driver = data->driver; /* Register the USB 2.0 roothub. * FIXME: USB core must know to register the USB 2.0 roothub first. @@ -212,6 +172,20 @@ static int xhci_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) /* USB 2.0 roothub is stored in the PCI device now. */ hcd = dev_get_drvdata(&dev->dev); xhci = hcd_to_xhci(hcd); + + /* Quirk on revision 0 of Fresco Logic's PDK */ + if (dev->vendor == PCI_VENDOR_ID_FRESCO_LOGIC && + dev->device == PCI_DEVICE_ID_FRESCO_LOGIC_PDK) { + if (dev->revision == 0x0) { + data->quirks |= XHCI_RESET_EP_QUIRK; + xhci_dbg(xhci, "QUIRK: Fresco Logic xHC needs configure" + " endpoint cmd after reset endpoint\n"); + } + } + + xhci->quirks = data->quirks; + xhci->limit_active_eps = data->limit_active_eps; + xhci->shared_hcd = usb_create_shared_hcd(driver, &dev->dev, pci_name(dev), hcd); if (!xhci->shared_hcd) { @@ -351,8 +325,64 @@ static const struct hc_driver xhci_pci_hc_driver = { /*-------------------------------------------------------------------------*/ +static DEFINE_XHCI_DATA(fresco_logic) = { + .quirks = XHCI_BROKEN_MSI, + .driver = &xhci_pci_hc_driver, +}; + +static DEFINE_XHCI_DATA(nec) = { + .quirks = XHCI_NEC_HOST, + .driver = &xhci_pci_hc_driver, +}; + +static DEFINE_XHCI_DATA(amd) = { + .quirks = XHCI_AMD_PLL_FIX, + .driver = &xhci_pci_hc_driver, +}; + +static DEFINE_XHCI_DATA(intel_pantherpoint) = { + .quirks = (XHCI_SPURIOUS_SUCCESS + | XHCI_EP_LIMIT_QUIRK), + .limit_active_eps = 64, + .driver = &xhci_pci_hc_driver, +}; + +static DEFINE_XHCI_DATA(etron) = { + .quirks = XHCI_RESET_ON_RESUME, + .driver = &xhci_pci_hc_driver, +}; + /* PCI driver selection metadata; PCI hotplugging uses this */ static DEFINE_PCI_DEVICE_TABLE(pci_ids) = { + /* handle quirky devices here */ + { + PCI_DEVICE(PCI_VENDOR_ID_FRESCO_LOGIC, + PCI_DEVICE_ID_FRESCO_LOGIC_PDK), + .driver_data = (kernel_ulong_t) &fresco_logic_driver_data, + }, + { + PCI_DEVICE(PCI_VENDOR_ID_NEC, PCI_ANY_ID), + .driver_data = (kernel_ulong_t) &nec_driver_data, + }, + { + PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x9600), + .driver_data = (kernel_ulong_t) &amd_driver_data, + }, + { + PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x9601), + .driver_data = (kernel_ulong_t) &amd_driver_data, + }, + { + PCI_DEVICE(PCI_VENDOR_ID_INTEL, + PCI_DEVICE_ID_INTEL_PANTHERPOINT_XHCI), + .driver_data = (kernel_ulong_t) &intel_pantherpoint_driver_data, + }, + { + PCI_DEVICE(PCI_VENDOR_ID_ETRON, + PCI_DEVICE_ID_ASROCK_P67), + .driver_data = (kernel_ulong_t) &etron_driver_data, + }, + /* handle any USB 3.0 xHCI controller */ { PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_XHCI, ~0), -- 1.7.6 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html