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: cdns3: Add USBSSP platform driver support

The Cadence USBSSP (CDNSP) controller was previously only accessible
through PCI, coupling the gadget driver with the PCI glue layer into a
single monolithic module (cdnsp-udc-pci). This prevented using the
CDNSP IP on SoC/platform designs that expose the controller through
device tree. It restructures the driver to decouple the CDNSP gadget
from PCI.

- Introduce CONFIG_USB_CDNSP as a standalone tristate (analogous to
CONFIG_USB_CDNS3), with USB_CDNSP_GADGET and USB_CDNSP_HOST as
bool sub-options. The gadget code builds as a separate cdnsp.ko
module.

- Regroup USBSSP and CDNS3 Kconfig options under the USB_CDNS_SUPPORT
menu so they appear properly grouped in menuconfig.

- Refactor cdnsp-pci.c into a thin PCI-to-platform wrapper (similar
to cdns3-pci-wrap.c) that registers a platform device and passes
PCI resources and platform data to the common platform driver.

- Auto-detect the controller version (USBSS vs USBSSP) at runtime by
reading the DRD/OTG Device ID register in cdns_drd_init(), and select
the appropriate gadget init function (cdns3_gadget_init or
cdnsp_gadget_init) based on cdns->version. This follows the same
pattern already used for host initialization.

- Fix gadget-export.h to use IS_REACHABLE() keyed on the tristate
module config (CONFIG_USB_CDNS3/CONFIG_USB_CDNSP) instead of
IS_ENABLED() on the bool gadget config. The bool configs are always
'y' when enabled, causing IS_ENABLED/IS_REACHABLE to always return
true and resulting in link errors when cdns-usb-common is built-in
but the gadget module is loadable.

- Add missing MODULE_LICENSE()/MODULE_DESCRIPTION() and
EXPORT_SYMBOL_GPL() to the cdns3 and cdnsp gadget modules, required
by modpost.

- Pass override_apb_timeout through cdns3_platform_data so the PCI
wrapper can communicate PCI-specific APB timeout values to the
common driver.

This patch is Assisted-by: Cursor:claude-4.6-opus

Signed-off-by: Peter Chen <peter.chen@cixtech.com>
Acked-by: Pawel Laszczak <pawell@cadence.com>
Link: https://patch.msgid.link/20260316064831.274865-3-peter.chen@cixtech.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Peter Chen and committed by
Greg Kroah-Hartman
6076388c fb14e7f7

+160 -174
+28 -22
drivers/usb/cdns3/Kconfig
··· 20 20 Say Y here if your system has a Cadence USB3 dual-role controller. 21 21 It supports: dual-role switch, Host-only, and Peripheral-only. 22 22 23 - If you choose to build this driver is a dynamically linked 24 - as module, the module will be called cdns3.ko. 25 - endif 26 - 27 23 if USB_CDNS3 28 24 29 25 config USB_CDNS3_GADGET ··· 85 89 86 90 If you choose to build this driver as module it will 87 91 be dynamically linked and module will be called cdns3-starfive.ko 88 - endif 89 92 90 - if USB_CDNS_SUPPORT 93 + endif # USB_CDNS3 91 94 92 - config USB_CDNSP_PCI 93 - tristate "Cadence CDNSP Dual-Role Controller" 94 - depends on USB_CDNS_SUPPORT && USB_PCI && ACPI 95 + config USB_CDNSP 96 + tristate "Cadence USBSSP Dual-Role Controller" 97 + depends on USB_CDNS_SUPPORT 95 98 help 96 - Say Y here if your system has a Cadence CDNSP dual-role controller. 97 - It supports: dual-role switch Host-only, and Peripheral-only. 99 + Say Y here if your system has a Cadence USBSSP dual-role controller. 100 + It supports: dual-role switch, Host-only, and Peripheral-only. 101 + Cadence CDNSP Controller device mode is very similar to XHCI controller. 102 + Therefore some algorithms used has been taken from xHCI driver. 103 + Host controller is compliant with XHCI so it uses standard XHCI driver. 98 104 99 - If you choose to build this driver is a dynamically linked 100 - module, the module will be called cdnsp.ko. 101 - endif 102 - 103 - if USB_CDNSP_PCI 105 + if USB_CDNSP 104 106 105 107 config USB_CDNSP_GADGET 106 - bool "Cadence CDNSP device controller" 107 - depends on USB_GADGET=y || USB_GADGET=USB_CDNSP_PCI 108 + bool "Cadence USBSSP device controller" 109 + depends on USB_GADGET=y || USB_GADGET=USB_CDNSP 108 110 help 109 111 Say Y here to enable device controller functionality of the 110 - Cadence CDNSP-DEV driver. 112 + Cadence USBSSP-DEV driver. 111 113 112 114 Cadence CDNSP Device Controller in device mode is 113 115 very similar to XHCI controller. Therefore some algorithms ··· 114 120 It doesn't support LS. 115 121 116 122 config USB_CDNSP_HOST 117 - bool "Cadence CDNSP host controller" 118 - depends on USB=y || USB=USB_CDNSP_PCI 123 + bool "Cadence USBSSP host controller" 124 + depends on USB=y || USB=USB_CDNSP 119 125 select USB_CDNS_HOST 120 126 help 121 127 Say Y here to enable host controller functionality of the ··· 124 130 Host controller is compliant with XHCI so it uses 125 131 standard XHCI driver. 126 132 127 - endif 133 + config USB_CDNSP_PCI 134 + tristate "Cadence USBSSP support on PCIe-based platforms" 135 + depends on USB_PCI && ACPI 136 + help 137 + If you're using the USBSSP Core IP with a PCIe, please say 138 + 'Y' or 'M' here. 139 + 140 + If you choose to build this driver as module it will 141 + be dynamically linked and module will be called cdnsp-pci.ko 142 + 143 + endif # USB_CDNSP 144 + 145 + endif # USB_CDNS_SUPPORT
+11 -19
drivers/usb/cdns3/Makefile
··· 4 4 CFLAGS_cdnsp-trace.o := -I$(src) 5 5 6 6 cdns-usb-common-y := core.o drd.o 7 - cdns3-y := cdns3-plat.o 8 7 9 8 ifeq ($(CONFIG_USB),m) 10 9 obj-m += cdns-usb-common.o 11 - obj-m += cdns3.o 10 + obj-m += cdns3-plat.o 12 11 else 13 12 obj-$(CONFIG_USB_CDNS_SUPPORT) += cdns-usb-common.o 14 - obj-$(CONFIG_USB_CDNS3) += cdns3.o 13 + obj-$(CONFIG_USB_CDNS_SUPPORT) += cdns3-plat.o 15 14 endif 16 15 17 16 cdns-usb-common-$(CONFIG_USB_CDNS_HOST) += host.o 18 - cdns3-$(CONFIG_USB_CDNS3_GADGET) += cdns3-gadget.o cdns3-ep0.o 19 17 18 + # For CDNS3 gadget 20 19 ifneq ($(CONFIG_USB_CDNS3_GADGET),) 20 + cdns3-y := cdns3-gadget.o cdns3-ep0.o 21 21 cdns3-$(CONFIG_TRACING) += cdns3-trace.o 22 + obj-$(CONFIG_USB_CDNS3) += cdns3.o 22 23 endif 23 - 24 24 obj-$(CONFIG_USB_CDNS3_PCI_WRAP) += cdns3-pci-wrap.o 25 25 obj-$(CONFIG_USB_CDNS3_TI) += cdns3-ti.o 26 26 obj-$(CONFIG_USB_CDNS3_IMX) += cdns3-imx.o 27 27 obj-$(CONFIG_USB_CDNS3_STARFIVE) += cdns3-starfive.o 28 28 29 - cdnsp-udc-pci-y := cdnsp-pci.o 30 - 31 - ifdef CONFIG_USB_CDNSP_PCI 32 - ifeq ($(CONFIG_USB),m) 33 - obj-m += cdnsp-udc-pci.o 34 - else 35 - obj-$(CONFIG_USB_CDNSP_PCI) += cdnsp-udc-pci.o 36 - endif 37 - endif 38 - 39 - cdnsp-udc-pci-$(CONFIG_USB_CDNSP_GADGET) += cdnsp-ring.o cdnsp-gadget.o \ 40 - cdnsp-mem.o cdnsp-ep0.o 41 - 29 + # For CDNSP gadget 42 30 ifneq ($(CONFIG_USB_CDNSP_GADGET),) 43 - cdnsp-udc-pci-$(CONFIG_TRACING) += cdnsp-trace.o 31 + cdnsp-y := cdnsp-ring.o cdnsp-gadget.o \ 32 + cdnsp-mem.o cdnsp-ep0.o 33 + cdnsp-$(CONFIG_TRACING) += cdnsp-trace.o 34 + obj-$(CONFIG_USB_CDNSP) += cdnsp.o 44 35 endif 36 + obj-$(CONFIG_USB_CDNSP_PCI) += cdnsp-pci.o
+4
drivers/usb/cdns3/cdns3-gadget.c
··· 3508 3508 3509 3509 return 0; 3510 3510 } 3511 + EXPORT_SYMBOL_GPL(cdns3_gadget_init); 3512 + 3513 + MODULE_LICENSE("GPL"); 3514 + MODULE_DESCRIPTION("Cadence USBSS DRD Driver - gadget");
+15 -2
drivers/usb/cdns3/cdns3-plat.c
··· 44 44 phy_power_off(cdns->usb2_phy); 45 45 } 46 46 47 + static int cdns3_plat_gadget_init(struct cdns *cdns) 48 + { 49 + if (cdns->version < CDNSP_CONTROLLER_V2) 50 + return cdns3_gadget_init(cdns); 51 + else 52 + return cdnsp_gadget_init(cdns); 53 + } 54 + 47 55 /** 48 56 * cdns3_plat_probe - probe for cdns3 core device 49 57 * @pdev: Pointer to cdns3 core platform device ··· 72 64 73 65 cdns->dev = dev; 74 66 cdns->pdata = dev_get_platdata(dev); 67 + if (cdns->pdata && cdns->pdata->override_apb_timeout) 68 + cdns->override_apb_timeout = cdns->pdata->override_apb_timeout; 75 69 76 70 platform_set_drvdata(pdev, cdns); 77 71 ··· 153 143 if (ret) 154 144 goto err_phy_power_on; 155 145 156 - cdns->gadget_init = cdns3_gadget_init; 157 - 158 146 ret = cdns_init(cdns); 147 + if (ret) 148 + goto err_cdns_init; 149 + 150 + cdns->gadget_init = cdns3_plat_gadget_init; 151 + ret = cdns_core_init_role(cdns); 159 152 if (ret) 160 153 goto err_cdns_init; 161 154
+4
drivers/usb/cdns3/cdnsp-gadget.c
··· 2075 2075 2076 2076 return 0; 2077 2077 } 2078 + EXPORT_SYMBOL_GPL(cdnsp_gadget_init); 2079 + 2080 + MODULE_LICENSE("GPL"); 2081 + MODULE_DESCRIPTION("Cadence CDNSP DRD Driver - gadget");
+89 -120
drivers/usb/cdns3/cdnsp-pci.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 2 /* 3 - * Cadence PCI Glue driver. 3 + * Cadence USBSSP PCI Glue driver. 4 4 * 5 5 * Copyright (C) 2019 Cadence. 6 6 * ··· 16 16 #include <linux/pci.h> 17 17 18 18 #include "core.h" 19 - #include "gadget-export.h" 19 + 20 + struct cdnsp_wrap { 21 + struct platform_device *plat_dev; 22 + struct resource dev_res[6]; 23 + int devfn; 24 + }; 25 + 26 + #define RES_IRQ_HOST_ID 0 27 + #define RES_IRQ_PERIPHERAL_ID 1 28 + #define RES_IRQ_OTG_ID 2 29 + #define RES_HOST_ID 3 30 + #define RES_DEV_ID 4 31 + #define RES_DRD_ID 5 20 32 21 33 #define PCI_BAR_HOST 0 22 34 #define PCI_BAR_OTG 0 ··· 38 26 #define PCI_DEV_FN_OTG 1 39 27 40 28 #define PCI_DRIVER_NAME "cdns-pci-usbssp" 41 - #define PLAT_DRIVER_NAME "cdns-usbssp" 29 + #define PLAT_DRIVER_NAME "cdns-usb3" 42 30 43 - #define CHICKEN_APB_TIMEOUT_VALUE 0x1C20 31 + #define CHICKEN_APB_TIMEOUT_VALUE 0x1C20 44 32 45 33 static struct pci_dev *cdnsp_get_second_fun(struct pci_dev *pdev) 46 34 { 47 35 /* 48 36 * Gets the second function. 49 - * Platform has two function. The fist keeps resources for 50 - * Host/Device while the secon keeps resources for DRD/OTG. 37 + * Platform has two function. The first keeps resources for 38 + * Host/Device while the second keeps resources for DRD/OTG. 51 39 */ 52 40 if (pdev->device == PCI_DEVICE_ID_CDNS_USBSSP) 53 41 return pci_get_device(pdev->vendor, PCI_DEVICE_ID_CDNS_USBSS, NULL); ··· 60 48 static int cdnsp_pci_probe(struct pci_dev *pdev, 61 49 const struct pci_device_id *id) 62 50 { 63 - struct device *dev = &pdev->dev; 64 - struct pci_dev *func; 51 + struct platform_device_info plat_info; 52 + static struct cdns3_platform_data pdata; 53 + struct cdnsp_wrap *wrap; 65 54 struct resource *res; 66 - struct cdns *cdnsp; 67 - int ret; 55 + struct pci_dev *func; 56 + int ret = 0; 68 57 69 58 /* 70 59 * For GADGET/HOST PCI (devfn) function number is 0, ··· 92 79 } 93 80 94 81 pci_set_master(pdev); 82 + 95 83 if (pci_is_enabled(func)) { 96 - cdnsp = pci_get_drvdata(func); 84 + wrap = pci_get_drvdata(func); 97 85 } else { 98 - cdnsp = kzalloc_obj(*cdnsp); 99 - if (!cdnsp) { 86 + wrap = kzalloc_obj(*wrap); 87 + if (!wrap) { 100 88 ret = -ENOMEM; 101 89 goto put_pci; 102 90 } 103 91 } 104 92 105 - /* For GADGET device function number is 0. */ 106 - if (pdev->devfn == 0) { 107 - resource_size_t rsrc_start, rsrc_len; 93 + res = wrap->dev_res; 108 94 109 - /* Function 0: host(BAR_0) + device(BAR_1).*/ 110 - dev_dbg(dev, "Initialize resources\n"); 111 - rsrc_start = pci_resource_start(pdev, PCI_BAR_DEV); 112 - rsrc_len = pci_resource_len(pdev, PCI_BAR_DEV); 113 - res = devm_request_mem_region(dev, rsrc_start, rsrc_len, "dev"); 114 - if (!res) { 115 - dev_dbg(dev, "controller already in use\n"); 116 - ret = -EBUSY; 117 - goto free_cdnsp; 118 - } 95 + if (pdev->devfn == PCI_DEV_FN_HOST_DEVICE) { 96 + /* Function 0: host(BAR_0) + device(BAR_2). */ 97 + dev_dbg(&pdev->dev, "Initialize Device resources\n"); 98 + res[RES_DEV_ID].start = pci_resource_start(pdev, PCI_BAR_DEV); 99 + res[RES_DEV_ID].end = pci_resource_end(pdev, PCI_BAR_DEV); 100 + res[RES_DEV_ID].name = "dev"; 101 + res[RES_DEV_ID].flags = IORESOURCE_MEM; 102 + dev_dbg(&pdev->dev, "USBSSP-DEV physical base addr: %pa\n", 103 + &res[RES_DEV_ID].start); 119 104 120 - cdnsp->dev_regs = devm_ioremap(dev, rsrc_start, rsrc_len); 121 - if (!cdnsp->dev_regs) { 122 - dev_dbg(dev, "error mapping memory\n"); 123 - ret = -EFAULT; 124 - goto free_cdnsp; 125 - } 105 + res[RES_HOST_ID].start = pci_resource_start(pdev, PCI_BAR_HOST); 106 + res[RES_HOST_ID].end = pci_resource_end(pdev, PCI_BAR_HOST); 107 + res[RES_HOST_ID].name = "xhci"; 108 + res[RES_HOST_ID].flags = IORESOURCE_MEM; 109 + dev_dbg(&pdev->dev, "USBSSP-XHCI physical base addr: %pa\n", 110 + &res[RES_HOST_ID].start); 126 111 127 - cdnsp->dev_irq = pdev->irq; 128 - dev_dbg(dev, "USBSS-DEV physical base addr: %pa\n", 129 - &rsrc_start); 112 + /* Interrupt for XHCI */ 113 + wrap->dev_res[RES_IRQ_HOST_ID].start = pdev->irq; 114 + wrap->dev_res[RES_IRQ_HOST_ID].name = "host"; 115 + wrap->dev_res[RES_IRQ_HOST_ID].flags = IORESOURCE_IRQ; 130 116 131 - res = &cdnsp->xhci_res[0]; 132 - res->start = pci_resource_start(pdev, PCI_BAR_HOST); 133 - res->end = pci_resource_end(pdev, PCI_BAR_HOST); 134 - res->name = "xhci"; 135 - res->flags = IORESOURCE_MEM; 136 - dev_dbg(dev, "USBSS-XHCI physical base addr: %pa\n", 137 - &res->start); 138 - 139 - /* Interrupt for XHCI, */ 140 - res = &cdnsp->xhci_res[1]; 141 - res->start = pdev->irq; 142 - res->name = "host"; 143 - res->flags = IORESOURCE_IRQ; 117 + /* Interrupt for device. It's the same as for HOST. */ 118 + wrap->dev_res[RES_IRQ_PERIPHERAL_ID].start = pdev->irq; 119 + wrap->dev_res[RES_IRQ_PERIPHERAL_ID].name = "peripheral"; 120 + wrap->dev_res[RES_IRQ_PERIPHERAL_ID].flags = IORESOURCE_IRQ; 144 121 } else { 145 - res = &cdnsp->otg_res; 146 - res->start = pci_resource_start(pdev, PCI_BAR_OTG); 147 - res->end = pci_resource_end(pdev, PCI_BAR_OTG); 148 - res->name = "otg"; 149 - res->flags = IORESOURCE_MEM; 150 - dev_dbg(dev, "CDNSP-DRD physical base addr: %pa\n", 151 - &res->start); 122 + res[RES_DRD_ID].start = pci_resource_start(pdev, PCI_BAR_OTG); 123 + res[RES_DRD_ID].end = pci_resource_end(pdev, PCI_BAR_OTG); 124 + res[RES_DRD_ID].name = "otg"; 125 + res[RES_DRD_ID].flags = IORESOURCE_MEM; 126 + dev_dbg(&pdev->dev, "CDNSP-DRD physical base addr: %pa\n", 127 + &res[RES_DRD_ID].start); 152 128 153 129 /* Interrupt for OTG/DRD. */ 154 - cdnsp->otg_irq = pdev->irq; 130 + wrap->dev_res[RES_IRQ_OTG_ID].start = pdev->irq; 131 + wrap->dev_res[RES_IRQ_OTG_ID].name = "otg"; 132 + wrap->dev_res[RES_IRQ_OTG_ID].flags = IORESOURCE_IRQ; 155 133 } 156 - 157 - /* 158 - * Cadence PCI based platform require some longer timeout for APB 159 - * to fixes domain clock synchronization issue after resuming 160 - * controller from L1 state. 161 - */ 162 - cdnsp->override_apb_timeout = CHICKEN_APB_TIMEOUT_VALUE; 163 - pci_set_drvdata(pdev, cdnsp); 164 134 165 135 if (pci_is_enabled(func)) { 166 - cdnsp->dev = dev; 167 - cdnsp->gadget_init = cdnsp_gadget_init; 168 - 169 - ret = cdns_init(cdnsp); 170 - if (ret) 171 - goto free_cdnsp; 136 + /* set up platform device info */ 137 + pdata.override_apb_timeout = CHICKEN_APB_TIMEOUT_VALUE; 138 + memset(&plat_info, 0, sizeof(plat_info)); 139 + plat_info.parent = &pdev->dev; 140 + plat_info.fwnode = pdev->dev.fwnode; 141 + plat_info.name = PLAT_DRIVER_NAME; 142 + plat_info.id = pdev->devfn; 143 + plat_info.res = wrap->dev_res; 144 + plat_info.num_res = ARRAY_SIZE(wrap->dev_res); 145 + plat_info.dma_mask = pdev->dma_mask; 146 + plat_info.data = &pdata; 147 + plat_info.size_data = sizeof(pdata); 148 + wrap->devfn = pdev->devfn; 149 + /* register platform device */ 150 + wrap->plat_dev = platform_device_register_full(&plat_info); 151 + if (IS_ERR(wrap->plat_dev)) { 152 + ret = PTR_ERR(wrap->plat_dev); 153 + kfree(wrap); 154 + goto put_pci; 155 + } 172 156 } 173 157 174 - device_wakeup_enable(&pdev->dev); 175 - if (pci_dev_run_wake(pdev)) 176 - pm_runtime_put_noidle(&pdev->dev); 177 - 178 - return 0; 179 - 180 - free_cdnsp: 181 - if (!pci_is_enabled(func)) 182 - kfree(cdnsp); 183 - 158 + pci_set_drvdata(pdev, wrap); 184 159 put_pci: 185 160 pci_dev_put(func); 186 - 187 161 return ret; 188 162 } 189 163 190 164 static void cdnsp_pci_remove(struct pci_dev *pdev) 191 165 { 192 - struct cdns *cdnsp; 166 + struct cdnsp_wrap *wrap; 193 167 struct pci_dev *func; 194 168 195 169 func = cdnsp_get_second_fun(pdev); 196 - cdnsp = (struct cdns *)pci_get_drvdata(pdev); 170 + wrap = pci_get_drvdata(pdev); 197 171 198 - if (pci_dev_run_wake(pdev)) 199 - pm_runtime_get_noresume(&pdev->dev); 172 + if (wrap->devfn == pdev->devfn) 173 + platform_device_unregister(wrap->plat_dev); 200 174 201 - if (pci_is_enabled(func)) { 202 - cdns_remove(cdnsp); 203 - } else { 204 - kfree(cdnsp); 205 - } 175 + if (!pci_is_enabled(func)) 176 + kfree(wrap); 206 177 207 178 pci_dev_put(func); 208 179 } 209 - 210 - static int __maybe_unused cdnsp_pci_suspend(struct device *dev) 211 - { 212 - struct cdns *cdns = dev_get_drvdata(dev); 213 - 214 - return cdns_suspend(cdns); 215 - } 216 - 217 - static int __maybe_unused cdnsp_pci_resume(struct device *dev) 218 - { 219 - struct cdns *cdns = dev_get_drvdata(dev); 220 - unsigned long flags; 221 - int ret; 222 - 223 - spin_lock_irqsave(&cdns->lock, flags); 224 - ret = cdns_resume(cdns); 225 - spin_unlock_irqrestore(&cdns->lock, flags); 226 - cdns_set_active(cdns, 1); 227 - 228 - return ret; 229 - } 230 - 231 - static const struct dev_pm_ops cdnsp_pci_pm_ops = { 232 - SET_SYSTEM_SLEEP_PM_OPS(cdnsp_pci_suspend, cdnsp_pci_resume) 233 - }; 234 180 235 181 static const struct pci_device_id cdnsp_pci_ids[] = { 236 182 { PCI_DEVICE(PCI_VENDOR_ID_CDNS, PCI_DEVICE_ID_CDNS_USBSSP), ··· 202 230 }; 203 231 204 232 static struct pci_driver cdnsp_pci_driver = { 205 - .name = "cdnsp-pci", 233 + .name = PCI_DRIVER_NAME, 206 234 .id_table = cdnsp_pci_ids, 207 235 .probe = cdnsp_pci_probe, 208 236 .remove = cdnsp_pci_remove, 209 - .driver = { 210 - .pm = &cdnsp_pci_pm_ops, 211 - } 212 237 }; 213 238 214 239 module_pci_driver(cdnsp_pci_driver); ··· 214 245 MODULE_ALIAS("pci:cdnsp"); 215 246 MODULE_AUTHOR("Pawel Laszczak <pawell@cadence.com>"); 216 247 MODULE_LICENSE("GPL v2"); 217 - MODULE_DESCRIPTION("Cadence CDNSP PCI driver"); 248 + MODULE_DESCRIPTION("Cadence CDNSP PCI wrapper");
+4 -7
drivers/usb/cdns3/core.c
··· 80 80 * 81 81 * Returns 0 on success otherwise negative errno 82 82 */ 83 - static int cdns_core_init_role(struct cdns *cdns) 83 + int cdns_core_init_role(struct cdns *cdns) 84 84 { 85 85 struct device *dev = cdns->dev; 86 86 enum usb_dr_mode best_dr_mode; ··· 197 197 goto err; 198 198 } 199 199 200 + dev_dbg(dev, "Cadence USB3 core: probe succeed\n"); 201 + 200 202 return 0; 201 203 err: 202 204 cdns_exit_roles(cdns); 203 205 return ret; 204 206 } 207 + EXPORT_SYMBOL_GPL(cdns_core_init_role); 205 208 206 209 /** 207 210 * cdns_hw_role_state_machine - role switch state machine based on hw events. ··· 472 469 if (ret) 473 470 goto init_failed; 474 471 475 - ret = cdns_core_init_role(cdns); 476 - if (ret) 477 - goto init_failed; 478 - 479 472 spin_lock_init(&cdns->lock); 480 - 481 - dev_dbg(dev, "Cadence USB3 core: probe succeed\n"); 482 473 483 474 return 0; 484 475 init_failed:
+3 -2
drivers/usb/cdns3/core.h
··· 45 45 unsigned long quirks; 46 46 #define CDNS3_DEFAULT_PM_RUNTIME_ALLOW BIT(0) 47 47 #define CDNS3_DRD_SUSPEND_RESIDENCY_ENABLE BIT(1) 48 + u32 override_apb_timeout; /* 0 = use default (e.g. for PCI) */ 48 49 }; 49 50 50 51 /** ··· 120 119 struct cdns3_platform_data *pdata; 121 120 spinlock_t lock; 122 121 struct xhci_plat_priv *xhci_plat_data; 123 - u32 override_apb_timeout; 124 - 125 122 int (*gadget_init)(struct cdns *cdns); 123 + u32 override_apb_timeout; 126 124 }; 127 125 128 126 int cdns_hw_role_switch(struct cdns *cdns); 129 127 int cdns_init(struct cdns *cdns); 130 128 int cdns_remove(struct cdns *cdns); 129 + int cdns_core_init_role(struct cdns *cdns); 131 130 132 131 #ifdef CONFIG_PM_SLEEP 133 132 int cdns_resume(struct cdns *cdns);
+2 -2
drivers/usb/cdns3/gadget-export.h
··· 10 10 #ifndef __LINUX_CDNS3_GADGET_EXPORT 11 11 #define __LINUX_CDNS3_GADGET_EXPORT 12 12 13 - #if IS_ENABLED(CONFIG_USB_CDNSP_GADGET) 13 + #if defined(CONFIG_USB_CDNSP_GADGET) && IS_REACHABLE(CONFIG_USB_CDNSP) 14 14 15 15 int cdnsp_gadget_init(struct cdns *cdns); 16 16 #else ··· 22 22 23 23 #endif /* CONFIG_USB_CDNSP_GADGET */ 24 24 25 - #if IS_ENABLED(CONFIG_USB_CDNS3_GADGET) 25 + #if defined(CONFIG_USB_CDNS3_GADGET) && IS_REACHABLE(CONFIG_USB_CDNS3) 26 26 27 27 int cdns3_gadget_init(struct cdns *cdns); 28 28 #else