Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

usb: dwc3: dwc3-octeon: Convert to glue driver

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>

authored by

Ladislav Michl and committed by
Greg Kroah-Hartman
976f82e8 b35935d6

+66 -49
-1
arch/mips/cavium-octeon/Makefile
··· 18 18 obj-$(CONFIG_MTD) += flash_setup.o 19 19 obj-$(CONFIG_SMP) += smp.o 20 20 obj-$(CONFIG_OCTEON_ILM) += oct_ilm.o 21 - obj-$(CONFIG_USB) += octeon-usb.o
-1
arch/mips/cavium-octeon/octeon-platform.c
··· 450 450 { .compatible = "cavium,octeon-3860-bootbus", }, 451 451 { .compatible = "cavium,mdio-mux", }, 452 452 { .compatible = "gpio-leds", }, 453 - { .compatible = "cavium,octeon-7130-usb-uctl", }, 454 453 {}, 455 454 }; 456 455
+55 -46
arch/mips/cavium-octeon/octeon-usb.c drivers/usb/dwc3/dwc3-octeon.c
··· 187 187 #define USBDRD_UCTL_ECC 0xf0 188 188 #define USBDRD_UCTL_SPARE1 0xf8 189 189 190 - static DEFINE_MUTEX(dwc3_octeon_clocks_mutex); 190 + struct dwc3_octeon { 191 + struct device *dev; 192 + void __iomem *base; 193 + }; 191 194 192 195 #ifdef CONFIG_CAVIUM_OCTEON_SOC 193 196 #include <asm/octeon/octeon.h> ··· 236 233 static inline void dwc3_octeon_writeq(void __iomem *base, uint64_t val) { } 237 234 238 235 static inline void dwc3_octeon_config_gpio(int index, int gpio) { } 236 + 237 + static uint64_t octeon_get_io_clock_rate(void) 238 + { 239 + return 150000000; 240 + } 239 241 #endif 240 242 241 243 static int dwc3_octeon_get_divider(void) ··· 502 494 dwc3_octeon_writeq(uctl_ctl_reg, val); 503 495 } 504 496 505 - static int __init dwc3_octeon_device_init(void) 497 + static int dwc3_octeon_probe(struct platform_device *pdev) 506 498 { 507 - const char compat_node_name[] = "cavium,octeon-7130-usb-uctl"; 508 - struct platform_device *pdev; 509 - struct device_node *node; 510 - struct resource *res; 511 - void __iomem *base; 499 + struct device *dev = &pdev->dev; 500 + struct device_node *node = dev->of_node; 501 + struct dwc3_octeon *octeon; 502 + int err; 512 503 513 - /* 514 - * There should only be three universal controllers, "uctl" 515 - * in the device tree. Two USB and a SATA, which we ignore. 516 - */ 517 - node = NULL; 518 - do { 519 - node = of_find_node_by_name(node, "uctl"); 520 - if (!node) 521 - return -ENODEV; 504 + octeon = devm_kzalloc(dev, sizeof(*octeon), GFP_KERNEL); 505 + if (!octeon) 506 + return -ENOMEM; 522 507 523 - if (of_device_is_compatible(node, compat_node_name)) { 524 - pdev = of_find_device_by_node(node); 525 - if (!pdev) 526 - return -ENODEV; 508 + octeon->dev = dev; 509 + octeon->base = devm_platform_ioremap_resource(pdev, 0); 510 + if (IS_ERR(octeon->base)) 511 + return PTR_ERR(octeon->base); 527 512 528 - /* 529 - * The code below maps in the registers necessary for 530 - * setting up the clocks and reseting PHYs. We must 531 - * release the resources so the dwc3 subsystem doesn't 532 - * know the difference. 533 - */ 534 - base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); 535 - if (IS_ERR(base)) { 536 - put_device(&pdev->dev); 537 - return PTR_ERR(base); 538 - } 513 + err = dwc3_octeon_clocks_start(dev, octeon->base); 514 + if (err) 515 + return err; 539 516 540 - mutex_lock(&dwc3_octeon_clocks_mutex); 541 - if (dwc3_octeon_clocks_start(&pdev->dev, base) == 0) 542 - dev_info(&pdev->dev, "clocks initialized.\n"); 543 - dwc3_octeon_set_endian_mode(base); 544 - dwc3_octeon_phy_reset(base); 545 - mutex_unlock(&dwc3_octeon_clocks_mutex); 546 - devm_iounmap(&pdev->dev, base); 547 - devm_release_mem_region(&pdev->dev, res->start, 548 - resource_size(res)); 549 - put_device(&pdev->dev); 550 - } 551 - } while (node != NULL); 517 + dwc3_octeon_set_endian_mode(octeon->base); 518 + dwc3_octeon_phy_reset(octeon->base); 552 519 553 - return 0; 520 + platform_set_drvdata(pdev, octeon); 521 + 522 + return of_platform_populate(node, NULL, NULL, dev); 554 523 } 555 - device_initcall(dwc3_octeon_device_init); 556 524 525 + static void dwc3_octeon_remove(struct platform_device *pdev) 526 + { 527 + struct dwc3_octeon *octeon = platform_get_drvdata(pdev); 528 + 529 + of_platform_depopulate(octeon->dev); 530 + platform_set_drvdata(pdev, NULL); 531 + } 532 + 533 + static const struct of_device_id dwc3_octeon_of_match[] = { 534 + { .compatible = "cavium,octeon-7130-usb-uctl" }, 535 + { }, 536 + }; 537 + MODULE_DEVICE_TABLE(of, dwc3_octeon_of_match); 538 + 539 + static struct platform_driver dwc3_octeon_driver = { 540 + .probe = dwc3_octeon_probe, 541 + .remove_new = dwc3_octeon_remove, 542 + .driver = { 543 + .name = "dwc3-octeon", 544 + .of_match_table = dwc3_octeon_of_match, 545 + }, 546 + }; 547 + module_platform_driver(dwc3_octeon_driver); 548 + 549 + MODULE_ALIAS("platform:dwc3-octeon"); 557 550 MODULE_AUTHOR("David Daney <david.daney@cavium.com>"); 558 551 MODULE_LICENSE("GPL"); 559 - MODULE_DESCRIPTION("USB driver for OCTEON III SoC"); 552 + MODULE_DESCRIPTION("DesignWare USB3 OCTEON III Glue Layer");
+10
drivers/usb/dwc3/Kconfig
··· 168 168 The Designware Core USB3 IP is programmed to operate in 169 169 in USB 2.0 mode only. 170 170 Say 'Y' or 'M' here if you have one such device 171 + 172 + config USB_DWC3_OCTEON 173 + tristate "Cavium Octeon Platforms" 174 + depends on CAVIUM_OCTEON_SOC || COMPILE_TEST 175 + default USB_DWC3 176 + help 177 + Support Cavium Octeon platforms with DesignWare Core USB3 IP. 178 + Only the host mode is currently supported. 179 + Say 'Y' or 'M' here if you have one such device. 180 + 171 181 endif
+1
drivers/usb/dwc3/Makefile
··· 54 54 obj-$(CONFIG_USB_DWC3_QCOM) += dwc3-qcom.o 55 55 obj-$(CONFIG_USB_DWC3_IMX8MP) += dwc3-imx8mp.o 56 56 obj-$(CONFIG_USB_DWC3_XILINX) += dwc3-xilinx.o 57 + obj-$(CONFIG_USB_DWC3_OCTEON) += dwc3-octeon.o
-1
drivers/usb/dwc3/dwc3-of-simple.c
··· 170 170 171 171 static const struct of_device_id of_dwc3_simple_match[] = { 172 172 { .compatible = "rockchip,rk3399-dwc3" }, 173 - { .compatible = "cavium,octeon-7130-usb-uctl" }, 174 173 { .compatible = "sprd,sc9860-dwc3" }, 175 174 { .compatible = "allwinner,sun50i-h6-dwc3" }, 176 175 { .compatible = "hisilicon,hi3670-dwc3" },