]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
usb: dwc3: dwc3-octeon: Convert to glue driver
authorLadislav Michl <ladis@linux-mips.org>
Mon, 31 Jul 2023 09:30:45 +0000 (11:30 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 4 Aug 2023 12:52:15 +0000 (14:52 +0200)
DWC3 as implemented in Cavium SoC is using UCTL bridge unit
between I/O interconnect and USB controller.

Currently there is no bond with dwc3 core code, so if anything goes
wrong in UCTL setup dwc3 is left in reset, which leads to bus error
while trying to read any device register. Thus any failure in UCTL
initialization ends with kernel panic.

To avoid this move Octeon DWC3 glue code from arch/mips and make it
proper glue driver which is used instead of dwc3-of-simple.

Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
Acked-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Acked-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
Link: https://lore.kernel.org/r/ZMd/ReyiY7wS6DvN@lenoch
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
arch/mips/cavium-octeon/Makefile
arch/mips/cavium-octeon/octeon-platform.c
drivers/usb/dwc3/Kconfig
drivers/usb/dwc3/Makefile
drivers/usb/dwc3/dwc3-octeon.c [moved from arch/mips/cavium-octeon/octeon-usb.c with 91% similarity]
drivers/usb/dwc3/dwc3-of-simple.c

index 7c02e542959a2cdd23e49283f656129e211b1266..2a59265788413e3387cb358e35a9c720d1ba4a3b 100644 (file)
@@ -18,4 +18,3 @@ obj-y += crypto/
 obj-$(CONFIG_MTD)                    += flash_setup.o
 obj-$(CONFIG_SMP)                    += smp.o
 obj-$(CONFIG_OCTEON_ILM)             += oct_ilm.o
-obj-$(CONFIG_USB)                    += octeon-usb.o
index ce05c0dd3acd780493148d17f7a2ede59f7ff482..235c77ce7b18ab3727593591879d9bea77dc3a40 100644 (file)
@@ -450,7 +450,6 @@ static const struct of_device_id octeon_ids[] __initconst = {
        { .compatible = "cavium,octeon-3860-bootbus", },
        { .compatible = "cavium,mdio-mux", },
        { .compatible = "gpio-leds", },
-       { .compatible = "cavium,octeon-7130-usb-uctl", },
        {},
 };
 
index be954a9abbe05e8a18bfbbb1bb2b27869b661f41..98efcbb76c882147f17981ed61dcb360f50c1739 100644 (file)
@@ -168,4 +168,14 @@ config USB_DWC3_AM62
          The Designware Core USB3 IP is programmed to operate in
          in USB 2.0 mode only.
          Say 'Y' or 'M' here if you have one such device
+
+config USB_DWC3_OCTEON
+       tristate "Cavium Octeon Platforms"
+       depends on CAVIUM_OCTEON_SOC || COMPILE_TEST
+       default USB_DWC3
+       help
+         Support Cavium Octeon platforms with DesignWare Core USB3 IP.
+         Only the host mode is currently supported.
+         Say 'Y' or 'M' here if you have one such device.
+
 endif
index 9f66bd82b639e417df07a9a933f92cb16b1a3c59..fe1493d4bbe58e5c4de0adf477e023ac386cd236 100644 (file)
@@ -54,3 +54,4 @@ obj-$(CONFIG_USB_DWC3_ST)             += dwc3-st.o
 obj-$(CONFIG_USB_DWC3_QCOM)            += dwc3-qcom.o
 obj-$(CONFIG_USB_DWC3_IMX8MP)          += dwc3-imx8mp.o
 obj-$(CONFIG_USB_DWC3_XILINX)          += dwc3-xilinx.o
+obj-$(CONFIG_USB_DWC3_OCTEON)          += dwc3-octeon.o
similarity index 91%
rename from arch/mips/cavium-octeon/octeon-usb.c
rename to drivers/usb/dwc3/dwc3-octeon.c
index 2add435ad03872f0b1465fcc9e88d13711b5c4e9..7134cdfc0fb6f608d599897fba4303347a8e8b82 100644 (file)
 #define USBDRD_UCTL_ECC                                0xf0
 #define USBDRD_UCTL_SPARE1                     0xf8
 
-static DEFINE_MUTEX(dwc3_octeon_clocks_mutex);
+struct dwc3_octeon {
+       struct device *dev;
+       void __iomem *base;
+};
 
 #ifdef CONFIG_CAVIUM_OCTEON_SOC
 #include <asm/octeon/octeon.h>
@@ -233,6 +236,11 @@ static inline uint64_t dwc3_octeon_readq(void __iomem *addr)
 static inline void dwc3_octeon_writeq(void __iomem *base, uint64_t val) { }
 
 static inline void dwc3_octeon_config_gpio(int index, int gpio) { }
+
+static uint64_t octeon_get_io_clock_rate(void)
+{
+       return 150000000;
+}
 #endif
 
 static int dwc3_octeon_get_divider(void)
@@ -494,58 +502,59 @@ static void __init dwc3_octeon_phy_reset(void __iomem *base)
        dwc3_octeon_writeq(uctl_ctl_reg, val);
 }
 
-static int __init dwc3_octeon_device_init(void)
+static int dwc3_octeon_probe(struct platform_device *pdev)
 {
-       const char compat_node_name[] = "cavium,octeon-7130-usb-uctl";
-       struct platform_device *pdev;
-       struct device_node *node;
-       struct resource *res;
-       void __iomem *base;
+       struct device *dev = &pdev->dev;
+       struct device_node *node = dev->of_node;
+       struct dwc3_octeon *octeon;
+       int err;
 
-       /*
-        * There should only be three universal controllers, "uctl"
-        * in the device tree. Two USB and a SATA, which we ignore.
-        */
-       node = NULL;
-       do {
-               node = of_find_node_by_name(node, "uctl");
-               if (!node)
-                       return -ENODEV;
-
-               if (of_device_is_compatible(node, compat_node_name)) {
-                       pdev = of_find_device_by_node(node);
-                       if (!pdev)
-                               return -ENODEV;
-
-                       /*
-                        * The code below maps in the registers necessary for
-                        * setting up the clocks and reseting PHYs. We must
-                        * release the resources so the dwc3 subsystem doesn't
-                        * know the difference.
-                        */
-                       base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
-                       if (IS_ERR(base)) {
-                               put_device(&pdev->dev);
-                               return PTR_ERR(base);
-                       }
+       octeon = devm_kzalloc(dev, sizeof(*octeon), GFP_KERNEL);
+       if (!octeon)
+               return -ENOMEM;
 
-                       mutex_lock(&dwc3_octeon_clocks_mutex);
-                       if (dwc3_octeon_clocks_start(&pdev->dev, base) == 0)
-                               dev_info(&pdev->dev, "clocks initialized.\n");
-                       dwc3_octeon_set_endian_mode(base);
-                       dwc3_octeon_phy_reset(base);
-                       mutex_unlock(&dwc3_octeon_clocks_mutex);
-                       devm_iounmap(&pdev->dev, base);
-                       devm_release_mem_region(&pdev->dev, res->start,
-                                               resource_size(res));
-                       put_device(&pdev->dev);
-               }
-       } while (node != NULL);
+       octeon->dev = dev;
+       octeon->base = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(octeon->base))
+               return PTR_ERR(octeon->base);
 
-       return 0;
+       err = dwc3_octeon_clocks_start(dev, octeon->base);
+       if (err)
+               return err;
+
+       dwc3_octeon_set_endian_mode(octeon->base);
+       dwc3_octeon_phy_reset(octeon->base);
+
+       platform_set_drvdata(pdev, octeon);
+
+       return of_platform_populate(node, NULL, NULL, dev);
+}
+
+static void dwc3_octeon_remove(struct platform_device *pdev)
+{
+       struct dwc3_octeon *octeon = platform_get_drvdata(pdev);
+
+       of_platform_depopulate(octeon->dev);
+       platform_set_drvdata(pdev, NULL);
 }
-device_initcall(dwc3_octeon_device_init);
 
+static const struct of_device_id dwc3_octeon_of_match[] = {
+       { .compatible = "cavium,octeon-7130-usb-uctl" },
+       { },
+};
+MODULE_DEVICE_TABLE(of, dwc3_octeon_of_match);
+
+static struct platform_driver dwc3_octeon_driver = {
+       .probe          = dwc3_octeon_probe,
+       .remove_new     = dwc3_octeon_remove,
+       .driver         = {
+               .name   = "dwc3-octeon",
+               .of_match_table = dwc3_octeon_of_match,
+       },
+};
+module_platform_driver(dwc3_octeon_driver);
+
+MODULE_ALIAS("platform:dwc3-octeon");
 MODULE_AUTHOR("David Daney <david.daney@cavium.com>");
 MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("USB driver for OCTEON III SoC");
+MODULE_DESCRIPTION("DesignWare USB3 OCTEON III Glue Layer");
index 7e6ad8fe61a5a2ba1f7a6768fefd9337fba94fc0..d1539fc9eabdae5d572ab58986a457f877c0b065 100644 (file)
@@ -170,7 +170,6 @@ static const struct dev_pm_ops dwc3_of_simple_dev_pm_ops = {
 
 static const struct of_device_id of_dwc3_simple_match[] = {
        { .compatible = "rockchip,rk3399-dwc3" },
-       { .compatible = "cavium,octeon-7130-usb-uctl" },
        { .compatible = "sprd,sc9860-dwc3" },
        { .compatible = "allwinner,sun50i-h6-dwc3" },
        { .compatible = "hisilicon,hi3670-dwc3" },