aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/drivers/usb/host/xhci-pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/xhci-pci.c')
-rw-r--r--drivers/usb/host/xhci-pci.c47
1 files changed, 38 insertions, 9 deletions
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index 766b74723e64..ef513c2fb843 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -15,6 +15,7 @@
#include "xhci.h"
#include "xhci-trace.h"
+#include "xhci-pci.h"
#define SSIC_PORT_NUM 2
#define SSIC_PORT_CFG2 0x880c
@@ -87,7 +88,16 @@ static int xhci_pci_reinit(struct xhci_hcd *xhci, struct pci_dev *pdev)
static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
{
- struct pci_dev *pdev = to_pci_dev(dev);
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct xhci_driver_data *driver_data;
+ const struct pci_device_id *id;
+
+ id = pci_match_id(pdev->driver->id_table, pdev);
+
+ if (id && id->driver_data) {
+ driver_data = (struct xhci_driver_data *)id->driver_data;
+ xhci->quirks |= driver_data->quirks;
+ }
/* Look for vendor-specific quirks */
if (pdev->vendor == PCI_VENDOR_ID_FRESCO_LOGIC &&
@@ -327,10 +337,15 @@ static int xhci_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
int retval;
struct xhci_hcd *xhci;
- struct hc_driver *driver;
struct usb_hcd *hcd;
+ struct xhci_driver_data *driver_data;
- driver = (struct hc_driver *)id->driver_data;
+ driver_data = (struct xhci_driver_data *)id->driver_data;
+ if (driver_data && driver_data->quirks & XHCI_RENESAS_FW_QUIRK) {
+ retval = renesas_xhci_check_request_fw(dev, id);
+ if (retval)
+ return retval;
+ }
/* Prevent runtime suspending between USB-2 and USB-3 initialization */
pm_runtime_get_noresume(&dev->dev);
@@ -341,7 +356,7 @@ static int xhci_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
* to say USB 2.0, but I'm not sure what the implications would be in
* the other parts of the HCD code.
*/
- retval = usb_hcd_pci_probe(dev, id);
+ retval = usb_hcd_pci_probe(dev, id, &xhci_pci_hc_driver);
if (retval)
goto put_runtime_pm;
@@ -349,8 +364,8 @@ 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);
- xhci->shared_hcd = usb_create_shared_hcd(driver, &dev->dev,
- pci_name(dev), hcd);
+ xhci->shared_hcd = usb_create_shared_hcd(&xhci_pci_hc_driver, &dev->dev,
+ pci_name(dev), hcd);
if (!xhci->shared_hcd) {
retval = -ENOMEM;
goto dealloc_usb2_hcd;
@@ -392,6 +407,9 @@ static void xhci_pci_remove(struct pci_dev *dev)
struct xhci_hcd *xhci;
xhci = hcd_to_xhci(pci_get_drvdata(dev));
+ if (xhci->quirks & XHCI_RENESAS_FW_QUIRK)
+ renesas_xhci_pci_exit(dev);
+
xhci->xhc_state |= XHCI_STATE_REMOVING;
if (xhci->quirks & XHCI_DEFAULT_PM_RUNTIME_ALLOW)
@@ -543,15 +561,26 @@ static void xhci_pci_shutdown(struct usb_hcd *hcd)
/*-------------------------------------------------------------------------*/
+static const struct xhci_driver_data reneses_data = {
+ .quirks = XHCI_RENESAS_FW_QUIRK,
+ .firmware = "renesas_usb_fw.mem",
+};
+
/* PCI driver selection metadata; PCI hotplugging uses this */
-static const struct pci_device_id pci_ids[] = { {
+static const struct pci_device_id pci_ids[] = {
+ { PCI_DEVICE(0x1912, 0x0014),
+ .driver_data = (unsigned long)&reneses_data,
+ },
+ { PCI_DEVICE(0x1912, 0x0015),
+ .driver_data = (unsigned long)&reneses_data,
+ },
/* handle any USB 3.0 xHCI controller */
- PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_XHCI, ~0),
- .driver_data = (unsigned long) &xhci_pci_hc_driver,
+ { PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_XHCI, ~0),
},
{ /* end: all zeroes */ }
};
MODULE_DEVICE_TABLE(pci, pci_ids);
+MODULE_FIRMWARE("renesas_usb_fw.mem");
/* pci driver glue; this is a "new style" PCI driver module */
static struct pci_driver xhci_pci_driver = {