usb: dwc2: add pci_device_id driver_data parse support
authorYinbo Zhu <zhuyinbo@loongson.cn>
Tue, 15 Aug 2023 06:58:33 +0000 (14:58 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 22 Aug 2023 12:49:12 +0000 (14:49 +0200)
The dwc2 driver has everything we need to run in PCI mode except
for pci_device_id driver_data parse.  With that to set Loongson
dwc2 element and added identified as PCI_VENDOR_ID_LOONGSON
and PCI_DEVICE_ID_LOONGSON_DWC2 in dwc2_pci_ids, the Loongson
dwc2 controller will work.

Signed-off-by: Yinbo Zhu <zhuyinbo@loongson.cn>
Link: https://lore.kernel.org/r/20230815065833.3375-1-zhuyinbo@loongson.cn
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/dwc2/core.h
drivers/usb/dwc2/params.c
drivers/usb/dwc2/pci.c

index 0bb4c0c845bfa6d5ddde3228da328062bd4dd572..c92a1da46a01473ea2f2c9d6f94eabd1f92a8bb0 100644 (file)
@@ -1330,6 +1330,7 @@ irqreturn_t dwc2_handle_common_intr(int irq, void *dev);
 /* The device ID match table */
 extern const struct of_device_id dwc2_of_match_table[];
 extern const struct acpi_device_id dwc2_acpi_match[];
+extern const struct pci_device_id dwc2_pci_ids[];
 
 int dwc2_lowlevel_hw_enable(struct dwc2_hsotg *hsotg);
 int dwc2_lowlevel_hw_disable(struct dwc2_hsotg *hsotg);
index 4c7c3dd15f9bec95158b8f4f10743207be010993..93f52e371cddb6ecb2fef3b068858a39df9c2578 100644 (file)
@@ -7,9 +7,14 @@
 #include <linux/module.h>
 #include <linux/of_device.h>
 #include <linux/usb/of.h>
+#include <linux/pci_ids.h>
+#include <linux/pci.h>
 
 #include "core.h"
 
+#define PCI_PRODUCT_ID_HAPS_HSOTG      0xabc0
+#define PCI_DEVICE_ID_LOONGSON_DWC2    0x7a04
+
 static void dwc2_set_bcm_params(struct dwc2_hsotg *hsotg)
 {
        struct dwc2_core_params *p = &hsotg->params;
@@ -55,6 +60,14 @@ static void dwc2_set_jz4775_params(struct dwc2_hsotg *hsotg)
                !device_property_read_bool(hsotg->dev, "disable-over-current");
 }
 
+static void dwc2_set_loongson_params(struct dwc2_hsotg *hsotg)
+{
+       struct dwc2_core_params *p = &hsotg->params;
+
+       p->phy_utmi_width = 8;
+       p->power_down = DWC2_POWER_DOWN_PARAM_PARTIAL;
+}
+
 static void dwc2_set_x1600_params(struct dwc2_hsotg *hsotg)
 {
        struct dwc2_core_params *p = &hsotg->params;
@@ -302,6 +315,23 @@ const struct acpi_device_id dwc2_acpi_match[] = {
 };
 MODULE_DEVICE_TABLE(acpi, dwc2_acpi_match);
 
+const struct pci_device_id dwc2_pci_ids[] = {
+       {
+               PCI_DEVICE(PCI_VENDOR_ID_SYNOPSYS, PCI_PRODUCT_ID_HAPS_HSOTG),
+       },
+       {
+               PCI_DEVICE(PCI_VENDOR_ID_STMICRO,
+                          PCI_DEVICE_ID_STMICRO_USB_OTG),
+       },
+       {
+               PCI_DEVICE(PCI_VENDOR_ID_LOONGSON, PCI_DEVICE_ID_LOONGSON_DWC2),
+               .driver_data = (unsigned long)dwc2_set_loongson_params,
+       },
+       { /* end: all zeroes */ }
+};
+MODULE_DEVICE_TABLE(pci, dwc2_pci_ids);
+EXPORT_SYMBOL_GPL(dwc2_pci_ids);
+
 static void dwc2_set_param_otg_cap(struct dwc2_hsotg *hsotg)
 {
        switch (hsotg->hw_params.op_mode) {
@@ -948,13 +978,20 @@ int dwc2_init_params(struct dwc2_hsotg *hsotg)
        if (match && match->data) {
                set_params = match->data;
                set_params(hsotg);
-       } else {
+       } else if (!match) {
                const struct acpi_device_id *amatch;
+               const struct pci_device_id *pmatch = NULL;
 
                amatch = acpi_match_device(dwc2_acpi_match, hsotg->dev);
                if (amatch && amatch->driver_data) {
                        set_params = (set_params_cb)amatch->driver_data;
                        set_params(hsotg);
+               } else if (!amatch)
+                       pmatch = pci_match_id(dwc2_pci_ids, to_pci_dev(hsotg->dev->parent));
+
+               if (pmatch && pmatch->driver_data) {
+                       set_params = (set_params_cb)pmatch->driver_data;
+                       set_params(hsotg);
                }
        }
 
index b7306ed8be4c1b38eed5f7b74db1a7ee657bf908..f3a1e4232a31dcd44345e18a7ecaca0039b92f1d 100644 (file)
@@ -24,7 +24,7 @@
 #include <linux/platform_device.h>
 #include <linux/usb/usb_phy_generic.h>
 
-#define PCI_PRODUCT_ID_HAPS_HSOTG      0xabc0
+#include "core.h"
 
 static const char dwc2_driver_name[] = "dwc2-pci";
 
@@ -122,18 +122,6 @@ err:
        return ret;
 }
 
-static const struct pci_device_id dwc2_pci_ids[] = {
-       {
-               PCI_DEVICE(PCI_VENDOR_ID_SYNOPSYS, PCI_PRODUCT_ID_HAPS_HSOTG),
-       },
-       {
-               PCI_DEVICE(PCI_VENDOR_ID_STMICRO,
-                          PCI_DEVICE_ID_STMICRO_USB_OTG),
-       },
-       { /* end: all zeroes */ }
-};
-MODULE_DEVICE_TABLE(pci, dwc2_pci_ids);
-
 static struct pci_driver dwc2_pci_driver = {
        .name = dwc2_driver_name,
        .id_table = dwc2_pci_ids,