obj-$(CONFIG_USB_ISP1760) += isp1760/
obj-$(CONFIG_USB_CDNS_SUPPORT) += cdns3/
-obj-$(CONFIG_USB_CDNS3) += cdns3/
-obj-$(CONFIG_USB_CDNSP_PCI) += cdns3/
obj-$(CONFIG_USB_FOTG210) += fotg210/
config USB_CDNS_SUPPORT
tristate "Cadence USB Support"
- depends on USB_SUPPORT && (USB || USB_GADGET) && HAS_DMA
+ depends on USB_SUPPORT && HAS_DMA
+ depends on USB || USB_GADGET
+ depends on USB if !USB_GADGET
+ depends on USB_GADGET if !USB
select USB_XHCI_PLATFORM if USB_XHCI_HCD
select USB_ROLE_SWITCH
help
dual-role controller.
It supports: dual-role switch, Host-only, and Peripheral-only.
-config USB_CDNS_HOST
- bool
-
if USB_CDNS_SUPPORT
config USB_CDNS3
- tristate "Cadence USB3 Dual-Role Controller"
+ tristate "Cadence USB dual-role controller (USBSS and USBSSP)"
depends on USB_CDNS_SUPPORT
help
- Say Y here if your system has a Cadence USB3 dual-role controller.
- It supports: dual-role switch, Host-only, and Peripheral-only.
+ Say Y or M here if your system has an on-chip Cadence USB
+ dual-role controller. This covers both USBSS (USB 3.0) and
+ USBSSP (SuperSpeed Plus) IP; the driver detects the variant at
+ runtime.
- If you choose to build this driver is a dynamically linked
- as module, the module will be called cdns3.ko.
-endif
+ The core driver (core, DRD, generic platform binding for the
+ "cdns,usb3" device tree compatible, optional host and gadget)
+ builds as one module named cdns.ko when built as a loadable
+ module.
+
+ It supports: dual-role switch, Host-only, and Peripheral-only.
if USB_CDNS3
-config USB_CDNS3_GADGET
- bool "Cadence USB3 device controller"
- depends on USB_GADGET=y || USB_GADGET=USB_CDNS3
+config USB_CDNS3_HOST
+ bool "Cadence USB host controller (xHCI)"
+ depends on USB=y || USB=USB_CDNS3
help
- Say Y here to enable device controller functionality of the
- Cadence USBSS-DEV driver.
+ Say Y here to enable host controller functionality for Cadence
+ USBSS and USBSSP dual-role controllers.
- This controller supports FF, HS and SS mode. It doesn't support
- LS and SSP mode.
+ The host controller is xHCI compliant and uses the standard
+ xHCI driver.
-config USB_CDNS3_HOST
- bool "Cadence USB3 host controller"
- depends on USB=y || USB=USB_CDNS3
- select USB_CDNS_HOST
+config USB_CDNS3_GADGET
+ bool "Cadence USB device controller (USBSS and USBSSP)"
+ depends on USB_GADGET=y || USB_GADGET=USB_CDNS3
help
- Say Y here to enable host controller functionality of the
- Cadence driver.
+ Say Y here to include Cadence USB device (gadget) support for
+ both USBSS (USB 3.0) and USBSSP (SuperSpeed Plus) IP in the
+ cdns.ko module. The implementation is selected at runtime from
+ the detected controller version.
- Host controller is compliant with XHCI so it will use
- standard XHCI driver.
+ USBSS gadget supports FF, HS and SS mode (not LS or SSP).
+ USBSSP gadget supports FF, HS, SS and SSP mode (not LS).
+
+comment "Platform glue driver support"
config USB_CDNS3_PCI_WRAP
tristate "Cadence USB3 support on PCIe-based platforms"
If you choose to build this driver as module it will
be dynamically linked and module will be called cdns3-pci.ko
+config USB_CDNSP_PCI
+ tristate "Cadence USBSSP support on PCIe-based platforms"
+ depends on USB_PCI && ACPI
+ default USB_CDNS3
+ help
+ If you're using the USBSSP Core IP with a PCIe, please say
+ 'Y' or 'M' here.
+
+ If you choose to build this driver as module it will
+ be dynamically linked and module will be called cdnsp-pci.ko
+
config USB_CDNS3_TI
tristate "Cadence USB3 support on TI platforms"
depends on ARCH_K3 || COMPILE_TEST
config USB_CDNS3_STARFIVE
tristate "Cadence USB3 support on StarFive SoC platforms"
depends on ARCH_STARFIVE || COMPILE_TEST
+ default USB_CDNS3
help
Say 'Y' or 'M' here if you are building for StarFive SoCs
platforms that contain Cadence USB3 controller core.
If you choose to build this driver as module it will
be dynamically linked and module will be called cdns3-starfive.ko
-endif
-
-if USB_CDNS_SUPPORT
-
-config USB_CDNSP_PCI
- tristate "Cadence CDNSP Dual-Role Controller"
- depends on USB_CDNS_SUPPORT && USB_PCI && ACPI
- help
- Say Y here if your system has a Cadence CDNSP dual-role controller.
- It supports: dual-role switch Host-only, and Peripheral-only.
-
- If you choose to build this driver is a dynamically linked
- module, the module will be called cdnsp.ko.
-endif
-
-if USB_CDNSP_PCI
-
-config USB_CDNSP_GADGET
- bool "Cadence CDNSP device controller"
- depends on USB_GADGET=y || USB_GADGET=USB_CDNSP_PCI
- help
- Say Y here to enable device controller functionality of the
- Cadence CDNSP-DEV driver.
-
- Cadence CDNSP Device Controller in device mode is
- very similar to XHCI controller. Therefore some algorithms
- used has been taken from host driver.
- This controller supports FF, HS, SS and SSP mode.
- It doesn't support LS.
-
-config USB_CDNSP_HOST
- bool "Cadence CDNSP host controller"
- depends on USB=y || USB=USB_CDNSP_PCI
- select USB_CDNS_HOST
- help
- Say Y here to enable host controller functionality of the
- Cadence driver.
- Host controller is compliant with XHCI so it uses
- standard XHCI driver.
+endif # USB_CDNS3
-endif
+endif # USB_CDNS_SUPPORT
CFLAGS_cdns3-trace.o := -I$(src)
CFLAGS_cdnsp-trace.o := -I$(src)
-cdns-usb-common-y := core.o drd.o
-cdns3-y := cdns3-plat.o
+obj-$(CONFIG_USB_CDNS3) += cdns.o
-ifeq ($(CONFIG_USB),m)
-obj-m += cdns-usb-common.o
-obj-m += cdns3.o
-else
-obj-$(CONFIG_USB_CDNS_SUPPORT) += cdns-usb-common.o
-obj-$(CONFIG_USB_CDNS3) += cdns3.o
-endif
+cdns-y := core.o drd.o cdns3-plat.o
+cdns-$(CONFIG_USB_CDNS3_HOST) += host.o
-cdns-usb-common-$(CONFIG_USB_CDNS_HOST) += host.o
-cdns3-$(CONFIG_USB_CDNS3_GADGET) += cdns3-gadget.o cdns3-ep0.o
+ifneq ($(CONFIG_USB_CDNS3_GADGET),)
+cdns-y += cdns3-gadget.o cdns3-ep0.o \
+ cdnsp-ring.o cdnsp-gadget.o \
+ cdnsp-mem.o cdnsp-ep0.o
+endif
+ifneq ($(CONFIG_TRACING),)
ifneq ($(CONFIG_USB_CDNS3_GADGET),)
-cdns3-$(CONFIG_TRACING) += cdns3-trace.o
+cdns-y += cdns3-trace.o cdnsp-trace.o
+endif
endif
+##
+# Platform-specific glue layers (PCI wrappers, SoC integration)
+##
obj-$(CONFIG_USB_CDNS3_PCI_WRAP) += cdns3-pci-wrap.o
+obj-$(CONFIG_USB_CDNSP_PCI) += cdnsp-pci.o
obj-$(CONFIG_USB_CDNS3_TI) += cdns3-ti.o
obj-$(CONFIG_USB_CDNS3_IMX) += cdns3-imx.o
obj-$(CONFIG_USB_CDNS3_STARFIVE) += cdns3-starfive.o
-
-cdnsp-udc-pci-y := cdnsp-pci.o
-
-ifdef CONFIG_USB_CDNSP_PCI
-ifeq ($(CONFIG_USB),m)
-obj-m += cdnsp-udc-pci.o
-else
-obj-$(CONFIG_USB_CDNSP_PCI) += cdnsp-udc-pci.o
-endif
-endif
-
-cdnsp-udc-pci-$(CONFIG_USB_CDNSP_GADGET) += cdnsp-ring.o cdnsp-gadget.o \
- cdnsp-mem.o cdnsp-ep0.o
-
-ifneq ($(CONFIG_USB_CDNSP_GADGET),)
-cdnsp-udc-pci-$(CONFIG_TRACING) += cdnsp-trace.o
-endif
return 0;
}
+EXPORT_SYMBOL_GPL(cdns3_gadget_init);
#include "core.h"
#include "gadget-export.h"
+#include "host-export.h"
#include "drd.h"
static int set_phy_power_on(struct cdns *cdns)
phy_power_off(cdns->usb2_phy);
}
+static int cdns3_plat_gadget_init(struct cdns *cdns)
+{
+ if (cdns->version < CDNSP_CONTROLLER_V2)
+ return cdns3_gadget_init(cdns);
+ else
+ return cdnsp_gadget_init(cdns);
+}
+
+static int cdns3_plat_host_init(struct cdns *cdns)
+{
+ return cdns_host_init(cdns);
+}
+
/**
* cdns3_plat_probe - probe for cdns3 core device
* @pdev: Pointer to cdns3 core platform device
cdns->dev = dev;
cdns->pdata = dev_get_platdata(dev);
+ if (cdns->pdata && cdns->pdata->override_apb_timeout)
+ cdns->override_apb_timeout = cdns->pdata->override_apb_timeout;
platform_set_drvdata(pdev, cdns);
if (ret)
goto err_phy_power_on;
- cdns->gadget_init = cdns3_gadget_init;
-
ret = cdns_init(cdns);
if (ret)
goto err_cdns_init;
+ cdns->gadget_init = cdns3_plat_gadget_init;
+ cdns->host_init = cdns3_plat_host_init;
+ ret = cdns_core_init_role(cdns);
+ if (ret)
+ goto err_cdns_init;
+
device_set_wakeup_capable(dev, true);
pm_runtime_set_active(dev);
pm_runtime_enable(dev);
module_platform_driver(cdns3_driver);
MODULE_ALIAS("platform:cdns3");
-MODULE_AUTHOR("Pawel Laszczak <pawell@cadence.com>");
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("Cadence USB3 DRD Controller Driver");
return 0;
}
+EXPORT_SYMBOL_GPL(cdnsp_gadget_init);
// SPDX-License-Identifier: GPL-2.0
/*
- * Cadence PCI Glue driver.
+ * Cadence USBSSP PCI Glue driver.
*
* Copyright (C) 2019 Cadence.
*
#include <linux/pci.h>
#include "core.h"
-#include "gadget-export.h"
+
+struct cdnsp_wrap {
+ struct platform_device *plat_dev;
+ struct resource dev_res[6];
+ int devfn;
+};
+
+#define RES_IRQ_HOST_ID 0
+#define RES_IRQ_PERIPHERAL_ID 1
+#define RES_IRQ_OTG_ID 2
+#define RES_HOST_ID 3
+#define RES_DEV_ID 4
+#define RES_DRD_ID 5
#define PCI_BAR_HOST 0
#define PCI_BAR_OTG 0
#define PCI_DEV_FN_OTG 1
#define PCI_DRIVER_NAME "cdns-pci-usbssp"
-#define PLAT_DRIVER_NAME "cdns-usbssp"
+#define PLAT_DRIVER_NAME "cdns-usb3"
-#define CHICKEN_APB_TIMEOUT_VALUE 0x1C20
+#define CHICKEN_APB_TIMEOUT_VALUE 0x1C20
static struct pci_dev *cdnsp_get_second_fun(struct pci_dev *pdev)
{
/*
* Gets the second function.
- * Platform has two function. The fist keeps resources for
- * Host/Device while the secon keeps resources for DRD/OTG.
+ * Platform has two function. The first keeps resources for
+ * Host/Device while the second keeps resources for DRD/OTG.
*/
if (pdev->device == PCI_DEVICE_ID_CDNS_USBSSP)
return pci_get_device(pdev->vendor, PCI_DEVICE_ID_CDNS_USBSS, NULL);
static int cdnsp_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *id)
{
- struct device *dev = &pdev->dev;
- struct pci_dev *func;
+ struct platform_device_info plat_info;
+ static struct cdns3_platform_data pdata;
+ struct cdnsp_wrap *wrap;
struct resource *res;
- struct cdns *cdnsp;
- int ret;
+ struct pci_dev *func;
+ int ret = 0;
/*
* For GADGET/HOST PCI (devfn) function number is 0,
}
pci_set_master(pdev);
+
if (pci_is_enabled(func)) {
- cdnsp = pci_get_drvdata(func);
+ wrap = pci_get_drvdata(func);
} else {
- cdnsp = kzalloc_obj(*cdnsp);
- if (!cdnsp) {
+ wrap = kzalloc_obj(*wrap);
+ if (!wrap) {
ret = -ENOMEM;
goto put_pci;
}
}
- /* For GADGET device function number is 0. */
- if (pdev->devfn == 0) {
- resource_size_t rsrc_start, rsrc_len;
-
- /* Function 0: host(BAR_0) + device(BAR_1).*/
- dev_dbg(dev, "Initialize resources\n");
- rsrc_start = pci_resource_start(pdev, PCI_BAR_DEV);
- rsrc_len = pci_resource_len(pdev, PCI_BAR_DEV);
- res = devm_request_mem_region(dev, rsrc_start, rsrc_len, "dev");
- if (!res) {
- dev_dbg(dev, "controller already in use\n");
- ret = -EBUSY;
- goto free_cdnsp;
- }
-
- cdnsp->dev_regs = devm_ioremap(dev, rsrc_start, rsrc_len);
- if (!cdnsp->dev_regs) {
- dev_dbg(dev, "error mapping memory\n");
- ret = -EFAULT;
- goto free_cdnsp;
- }
-
- cdnsp->dev_irq = pdev->irq;
- dev_dbg(dev, "USBSS-DEV physical base addr: %pa\n",
- &rsrc_start);
-
- res = &cdnsp->xhci_res[0];
- res->start = pci_resource_start(pdev, PCI_BAR_HOST);
- res->end = pci_resource_end(pdev, PCI_BAR_HOST);
- res->name = "xhci";
- res->flags = IORESOURCE_MEM;
- dev_dbg(dev, "USBSS-XHCI physical base addr: %pa\n",
- &res->start);
-
- /* Interrupt for XHCI, */
- res = &cdnsp->xhci_res[1];
- res->start = pdev->irq;
- res->name = "host";
- res->flags = IORESOURCE_IRQ;
+ res = wrap->dev_res;
+
+ if (pdev->devfn == PCI_DEV_FN_HOST_DEVICE) {
+ /* Function 0: host(BAR_0) + device(BAR_2). */
+ dev_dbg(&pdev->dev, "Initialize Device resources\n");
+ res[RES_DEV_ID].start = pci_resource_start(pdev, PCI_BAR_DEV);
+ res[RES_DEV_ID].end = pci_resource_end(pdev, PCI_BAR_DEV);
+ res[RES_DEV_ID].name = "dev";
+ res[RES_DEV_ID].flags = IORESOURCE_MEM;
+ dev_dbg(&pdev->dev, "USBSSP-DEV physical base addr: %pa\n",
+ &res[RES_DEV_ID].start);
+
+ res[RES_HOST_ID].start = pci_resource_start(pdev, PCI_BAR_HOST);
+ res[RES_HOST_ID].end = pci_resource_end(pdev, PCI_BAR_HOST);
+ res[RES_HOST_ID].name = "xhci";
+ res[RES_HOST_ID].flags = IORESOURCE_MEM;
+ dev_dbg(&pdev->dev, "USBSSP-XHCI physical base addr: %pa\n",
+ &res[RES_HOST_ID].start);
+
+ /* Interrupt for XHCI */
+ wrap->dev_res[RES_IRQ_HOST_ID].start = pdev->irq;
+ wrap->dev_res[RES_IRQ_HOST_ID].name = "host";
+ wrap->dev_res[RES_IRQ_HOST_ID].flags = IORESOURCE_IRQ;
+
+ /* Interrupt for device. It's the same as for HOST. */
+ wrap->dev_res[RES_IRQ_PERIPHERAL_ID].start = pdev->irq;
+ wrap->dev_res[RES_IRQ_PERIPHERAL_ID].name = "peripheral";
+ wrap->dev_res[RES_IRQ_PERIPHERAL_ID].flags = IORESOURCE_IRQ;
} else {
- res = &cdnsp->otg_res;
- res->start = pci_resource_start(pdev, PCI_BAR_OTG);
- res->end = pci_resource_end(pdev, PCI_BAR_OTG);
- res->name = "otg";
- res->flags = IORESOURCE_MEM;
- dev_dbg(dev, "CDNSP-DRD physical base addr: %pa\n",
- &res->start);
+ res[RES_DRD_ID].start = pci_resource_start(pdev, PCI_BAR_OTG);
+ res[RES_DRD_ID].end = pci_resource_end(pdev, PCI_BAR_OTG);
+ res[RES_DRD_ID].name = "otg";
+ res[RES_DRD_ID].flags = IORESOURCE_MEM;
+ dev_dbg(&pdev->dev, "CDNSP-DRD physical base addr: %pa\n",
+ &res[RES_DRD_ID].start);
/* Interrupt for OTG/DRD. */
- cdnsp->otg_irq = pdev->irq;
+ wrap->dev_res[RES_IRQ_OTG_ID].start = pdev->irq;
+ wrap->dev_res[RES_IRQ_OTG_ID].name = "otg";
+ wrap->dev_res[RES_IRQ_OTG_ID].flags = IORESOURCE_IRQ;
}
- /*
- * Cadence PCI based platform require some longer timeout for APB
- * to fixes domain clock synchronization issue after resuming
- * controller from L1 state.
- */
- cdnsp->override_apb_timeout = CHICKEN_APB_TIMEOUT_VALUE;
- pci_set_drvdata(pdev, cdnsp);
-
if (pci_is_enabled(func)) {
- cdnsp->dev = dev;
- cdnsp->gadget_init = cdnsp_gadget_init;
-
- ret = cdns_init(cdnsp);
- if (ret)
- goto free_cdnsp;
+ /* set up platform device info */
+ pdata.override_apb_timeout = CHICKEN_APB_TIMEOUT_VALUE;
+ memset(&plat_info, 0, sizeof(plat_info));
+ plat_info.parent = &pdev->dev;
+ plat_info.fwnode = pdev->dev.fwnode;
+ plat_info.name = PLAT_DRIVER_NAME;
+ plat_info.id = pdev->devfn;
+ plat_info.res = wrap->dev_res;
+ plat_info.num_res = ARRAY_SIZE(wrap->dev_res);
+ plat_info.dma_mask = pdev->dma_mask;
+ plat_info.data = &pdata;
+ plat_info.size_data = sizeof(pdata);
+ wrap->devfn = pdev->devfn;
+ /* register platform device */
+ wrap->plat_dev = platform_device_register_full(&plat_info);
+ if (IS_ERR(wrap->plat_dev)) {
+ ret = PTR_ERR(wrap->plat_dev);
+ kfree(wrap);
+ goto put_pci;
+ }
}
- device_wakeup_enable(&pdev->dev);
- if (pci_dev_run_wake(pdev))
- pm_runtime_put_noidle(&pdev->dev);
-
- return 0;
-
-free_cdnsp:
- if (!pci_is_enabled(func))
- kfree(cdnsp);
-
+ pci_set_drvdata(pdev, wrap);
put_pci:
pci_dev_put(func);
-
return ret;
}
static void cdnsp_pci_remove(struct pci_dev *pdev)
{
- struct cdns *cdnsp;
+ struct cdnsp_wrap *wrap;
struct pci_dev *func;
func = cdnsp_get_second_fun(pdev);
- cdnsp = (struct cdns *)pci_get_drvdata(pdev);
+ wrap = pci_get_drvdata(pdev);
- if (pci_dev_run_wake(pdev))
- pm_runtime_get_noresume(&pdev->dev);
+ if (wrap->devfn == pdev->devfn)
+ platform_device_unregister(wrap->plat_dev);
- if (pci_is_enabled(func)) {
- cdns_remove(cdnsp);
- } else {
- kfree(cdnsp);
- }
+ if (!pci_is_enabled(func))
+ kfree(wrap);
pci_dev_put(func);
}
-static int __maybe_unused cdnsp_pci_suspend(struct device *dev)
-{
- struct cdns *cdns = dev_get_drvdata(dev);
-
- return cdns_suspend(cdns);
-}
-
-static int __maybe_unused cdnsp_pci_resume(struct device *dev)
-{
- struct cdns *cdns = dev_get_drvdata(dev);
- unsigned long flags;
- int ret;
-
- spin_lock_irqsave(&cdns->lock, flags);
- ret = cdns_resume(cdns);
- spin_unlock_irqrestore(&cdns->lock, flags);
- cdns_set_active(cdns, 1);
-
- return ret;
-}
-
-static const struct dev_pm_ops cdnsp_pci_pm_ops = {
- SET_SYSTEM_SLEEP_PM_OPS(cdnsp_pci_suspend, cdnsp_pci_resume)
-};
-
static const struct pci_device_id cdnsp_pci_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_CDNS, PCI_DEVICE_ID_CDNS_USBSSP),
.class = PCI_CLASS_SERIAL_USB_DEVICE },
};
static struct pci_driver cdnsp_pci_driver = {
- .name = "cdnsp-pci",
+ .name = PCI_DRIVER_NAME,
.id_table = cdnsp_pci_ids,
.probe = cdnsp_pci_probe,
.remove = cdnsp_pci_remove,
- .driver = {
- .pm = &cdnsp_pci_pm_ops,
- }
};
module_pci_driver(cdnsp_pci_driver);
MODULE_ALIAS("pci:cdnsp");
MODULE_AUTHOR("Pawel Laszczak <pawell@cadence.com>");
MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("Cadence CDNSP PCI driver");
+MODULE_DESCRIPTION("Cadence CDNSP PCI wrapper");
#include <linux/pm_runtime.h>
#include "core.h"
-#include "host-export.h"
#include "drd.h"
static int cdns_idle_init(struct cdns *cdns);
*
* Returns 0 on success otherwise negative errno
*/
-static int cdns_core_init_role(struct cdns *cdns)
+int cdns_core_init_role(struct cdns *cdns)
{
struct device *dev = cdns->dev;
enum usb_dr_mode best_dr_mode;
* can be restricted later depending on strap pin configuration.
*/
if (dr_mode == USB_DR_MODE_UNKNOWN) {
- if (cdns->version == CDNSP_CONTROLLER_V2) {
- if (IS_ENABLED(CONFIG_USB_CDNSP_HOST) &&
- IS_ENABLED(CONFIG_USB_CDNSP_GADGET))
- dr_mode = USB_DR_MODE_OTG;
- else if (IS_ENABLED(CONFIG_USB_CDNSP_HOST))
- dr_mode = USB_DR_MODE_HOST;
- else if (IS_ENABLED(CONFIG_USB_CDNSP_GADGET))
- dr_mode = USB_DR_MODE_PERIPHERAL;
- } else {
- if (IS_ENABLED(CONFIG_USB_CDNS3_HOST) &&
- IS_ENABLED(CONFIG_USB_CDNS3_GADGET))
- dr_mode = USB_DR_MODE_OTG;
- else if (IS_ENABLED(CONFIG_USB_CDNS3_HOST))
- dr_mode = USB_DR_MODE_HOST;
- else if (IS_ENABLED(CONFIG_USB_CDNS3_GADGET))
- dr_mode = USB_DR_MODE_PERIPHERAL;
- }
+ if (IS_ENABLED(CONFIG_USB_CDNS3_HOST) &&
+ IS_ENABLED(CONFIG_USB_CDNS3_GADGET))
+ dr_mode = USB_DR_MODE_OTG;
+ else if (IS_ENABLED(CONFIG_USB_CDNS3_HOST))
+ dr_mode = USB_DR_MODE_HOST;
+ else if (IS_ENABLED(CONFIG_USB_CDNS3_GADGET))
+ dr_mode = USB_DR_MODE_PERIPHERAL;
}
/*
dr_mode = best_dr_mode;
if (dr_mode == USB_DR_MODE_OTG || dr_mode == USB_DR_MODE_HOST) {
- if ((cdns->version == CDNSP_CONTROLLER_V2 &&
- IS_ENABLED(CONFIG_USB_CDNSP_HOST)) ||
- (cdns->version < CDNSP_CONTROLLER_V2 &&
- IS_ENABLED(CONFIG_USB_CDNS3_HOST)))
- ret = cdns_host_init(cdns);
+ if (cdns->host_init)
+ ret = cdns->host_init(cdns);
else
ret = -ENXIO;
goto err;
}
+ dev_dbg(dev, "Cadence USB3 core: probe succeed\n");
+
return 0;
err:
cdns_exit_roles(cdns);
return ret;
}
+EXPORT_SYMBOL_GPL(cdns_core_init_role);
/**
* cdns_hw_role_state_machine - role switch state machine based on hw events.
if (ret)
goto init_failed;
- ret = cdns_core_init_role(cdns);
- if (ret)
- goto init_failed;
-
spin_lock_init(&cdns->lock);
- dev_dbg(dev, "Cadence USB3 core: probe succeed\n");
-
return 0;
init_failed:
cdns_drd_exit(cdns);
MODULE_AUTHOR("Peter Chen <peter.chen@nxp.com>");
MODULE_AUTHOR("Pawel Laszczak <pawell@cadence.com>");
MODULE_AUTHOR("Roger Quadros <rogerq@ti.com>");
-MODULE_DESCRIPTION("Cadence USBSS and USBSSP DRD Driver");
+MODULE_DESCRIPTION("Cadence USBSS/USBSSP DRD driver (core, DRD, platform, optional host/gadget)");
MODULE_LICENSE("GPL");
unsigned long quirks;
#define CDNS3_DEFAULT_PM_RUNTIME_ALLOW BIT(0)
#define CDNS3_DRD_SUSPEND_RESIDENCY_ENABLE BIT(1)
+ u32 override_apb_timeout; /* 0 = use default (e.g. for PCI) */
};
/**
* @override_apb_timeout: hold value of APB timeout. For value 0 the default
* value in CHICKEN_BITS_3 will be preserved.
* @gadget_init: pointer to gadget initialization function
+ * @host_init: pointer to host initialization function
*/
struct cdns {
struct device *dev;
spinlock_t lock;
struct xhci_plat_priv *xhci_plat_data;
u32 override_apb_timeout;
-
int (*gadget_init)(struct cdns *cdns);
+ int (*host_init)(struct cdns *cdns);
};
int cdns_hw_role_switch(struct cdns *cdns);
int cdns_init(struct cdns *cdns);
int cdns_remove(struct cdns *cdns);
+int cdns_core_init_role(struct cdns *cdns);
#ifdef CONFIG_PM_SLEEP
int cdns_resume(struct cdns *cdns);
#ifndef __LINUX_CDNS3_GADGET_EXPORT
#define __LINUX_CDNS3_GADGET_EXPORT
-#if IS_ENABLED(CONFIG_USB_CDNSP_GADGET)
+#if IS_ENABLED(CONFIG_USB_CDNS3_GADGET)
int cdnsp_gadget_init(struct cdns *cdns);
+int cdns3_gadget_init(struct cdns *cdns);
#else
static inline int cdnsp_gadget_init(struct cdns *cdns)
return -ENXIO;
}
-#endif /* CONFIG_USB_CDNSP_GADGET */
-
-#if IS_ENABLED(CONFIG_USB_CDNS3_GADGET)
-
-int cdns3_gadget_init(struct cdns *cdns);
-#else
-
static inline int cdns3_gadget_init(struct cdns *cdns)
{
return -ENXIO;
#ifndef __LINUX_CDNS3_HOST_EXPORT
#define __LINUX_CDNS3_HOST_EXPORT
-#if IS_ENABLED(CONFIG_USB_CDNS_HOST)
+#if IS_ENABLED(CONFIG_USB_CDNS3_HOST)
int cdns_host_init(struct cdns *cdns);
static inline void cdns_host_exit(struct cdns *cdns) { }
-#endif /* USB_CDNS_HOST */
+#endif /* CONFIG_USB_CDNS3_HOST */
#endif /* __LINUX_CDNS3_HOST_EXPORT */