diff options
author | Ben Hutchings <ben@decadent.org.uk> | 2024-07-31 22:32:29 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2024-08-07 12:51:38 +0200 |
commit | 25f51b76f90f10f9bf2fbc05fc51cf685da7ccad (patch) | |
tree | f86cccc1838c1f41d04f775513d183cdffb54e4c /drivers/usb/host/xhci-pci.c | |
parent | f358602425486fce2eac1a9592444c9840557754 (diff) |
xhci-pci: Make xhci-pci-renesas a proper modular driver
If CONFIG_USB_XHCI_PCI_RENESAS is enabled, xhci-pci conditionally
calls into the xhci-pci-renesas module, which means both modules must
be loaded to use any xHCI PCI controller.
The MODULE_FIRMWARE declaration in the base xhci-pci module causes
initramfs-tools to check for and warn about missing firmware for the
Renesas xHCI controllers, when any xHCI PCI controller is present.
And because of the previous oddity, simply moving this declaration to
xhci-pci-renesas wouldn't help.
To fix this, reverse the relationship between the modules:
- Remove the quirk for the Renesas xHCIs, and the driver_data
structure used only for them
- In xhci-pci:
- Rename xhci_pci_probe() to xhci_pci_common_probe()
- Export xhci_pci_common_probe() and xhci_pci_remove()
- Use a new probe function that rejects the Renesas xHCIs and then
calls the common probe function
- In xhci-pci-renesas:
- Stop exporting renesas_xhci_check_request_fw()
- Add a probe function that calls renesas_xhci_check_request_fw()
followed by xhci_pci_common_probe()
- Add and register a new pci_driver matching only the Renesas xHCIs
and using its own probe function, but with other operations the
same as in xhci-pci
- Make CONFIG_USB_XHCI_PCI_RENESAS depend on CONFIG_USB_XHCI_PCI,
not the other way around
Finally, move the MODULE_FIRMWARE declaration to xhci-pci-renesas.
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Tested-by: Cyril Brulebois <cyril@debamax.com>
Link: https://lore.kernel.org/r/ZqqfXYRJf7kGaqus@decadent.org.uk
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/host/xhci-pci.c')
-rw-r--r-- | drivers/usb/host/xhci-pci.c | 57 |
1 files changed, 19 insertions, 38 deletions
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index dc1e345ab67e..b5705ed01d83 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -235,15 +235,6 @@ 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 xhci_driver_data *driver_data; - const struct pci_device_id *id; - - id = pci_match_id(to_pci_driver(pdev->dev.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 && @@ -572,21 +563,13 @@ static int xhci_pci_update_hub_device(struct usb_hcd *hcd, struct usb_device *hd * 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 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 xhci_driver_data *driver_data; struct reset_control *reset; - 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; - } - reset = devm_reset_control_get_optional_exclusive(&dev->dev, NULL); if (IS_ERR(reset)) return PTR_ERR(reset); @@ -651,8 +634,24 @@ put_runtime_pm: pm_runtime_put_noidle(&dev->dev); return retval; } +EXPORT_SYMBOL_NS_GPL(xhci_pci_common_probe, xhci); + +static const struct pci_device_id pci_ids_reject[] = { + /* handled by xhci-pci-renesas */ + { PCI_DEVICE(PCI_VENDOR_ID_RENESAS, 0x0014) }, + { PCI_DEVICE(PCI_VENDOR_ID_RENESAS, 0x0015) }, + { /* end: all zeroes */ } +}; + +static int xhci_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) +{ + if (pci_match_id(pci_ids_reject, dev)) + return -ENODEV; + + return xhci_pci_common_probe(dev, id); +} -static void xhci_pci_remove(struct pci_dev *dev) +void xhci_pci_remove(struct pci_dev *dev) { struct xhci_hcd *xhci; @@ -675,6 +674,7 @@ static void xhci_pci_remove(struct pci_dev *dev) usb_hcd_pci_remove(dev); } +EXPORT_SYMBOL_NS_GPL(xhci_pci_remove, xhci); /* * In some Intel xHCI controllers, in order to get D3 working, @@ -882,19 +882,8 @@ 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[] = { - { PCI_DEVICE(PCI_VENDOR_ID_RENESAS, 0x0014), - .driver_data = (unsigned long)&reneses_data, - }, - { PCI_DEVICE(PCI_VENDOR_ID_RENESAS, 0x0015), - .driver_data = (unsigned long)&reneses_data, - }, /* handle any USB 3.0 xHCI controller */ { PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_XHCI, ~0), }, @@ -902,14 +891,6 @@ static const struct pci_device_id pci_ids[] = { }; MODULE_DEVICE_TABLE(pci, pci_ids); -/* - * Without CONFIG_USB_XHCI_PCI_RENESAS renesas_xhci_check_request_fw() won't - * load firmware, so don't encumber the xhci-pci driver with it. - */ -#if IS_ENABLED(CONFIG_USB_XHCI_PCI_RENESAS) -MODULE_FIRMWARE("renesas_usb_fw.mem"); -#endif - /* pci driver glue; this is a "new style" PCI driver module */ static struct pci_driver xhci_pci_driver = { .name = hcd_name, |