Revert "usb: cdns3: Add USBSSP platform driver support"

This reverts commit 6076388ca1.

There were some build issues as reported by Arnd, so revert this for
now.

Cc: Peter Chen <peter.chen@cixtech.com>
Cc: Pawel Laszczak <pawell@cadence.com>
Reported-by: Arnd Bergmann <arnd@kernel.org>
Link: https://lore.kernel.org/r/ac+LEWMCQpLSnfoD@nchen-desktop
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Greg Kroah-Hartman 2026-04-03 14:05:13 +02:00
parent 49eac82653
commit 29fea9f4ec
9 changed files with 175 additions and 161 deletions

View File

@ -20,6 +20,10 @@ config USB_CDNS3
Say Y here if your system has a Cadence USB3 dual-role controller.
It supports: dual-role switch, Host-only, and Peripheral-only.
If you choose to build this driver is a dynamically linked
as module, the module will be called cdns3.ko.
endif
if USB_CDNS3
config USB_CDNS3_GADGET
@ -85,27 +89,29 @@ config USB_CDNS3_STARFIVE
If you choose to build this driver as module it will
be dynamically linked and module will be called cdns3-starfive.ko
endif
endif # USB_CDNS3
if USB_CDNS_SUPPORT
config USB_CDNSP
tristate "Cadence USBSSP Dual-Role Controller"
depends on 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 USBSSP dual-role controller.
It supports: dual-role switch, Host-only, and Peripheral-only.
Cadence CDNSP Controller device mode is very similar to XHCI controller.
Therefore some algorithms used has been taken from xHCI driver.
Host controller is compliant with XHCI so it uses standard XHCI driver.
Say Y here if your system has a Cadence CDNSP dual-role controller.
It supports: dual-role switch Host-only, and Peripheral-only.
if USB_CDNSP
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 USBSSP device controller"
depends on USB_GADGET=y || USB_GADGET=USB_CDNSP
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 USBSSP-DEV driver.
Cadence CDNSP-DEV driver.
Cadence CDNSP Device Controller in device mode is
very similar to XHCI controller. Therefore some algorithms
@ -114,8 +120,8 @@ config USB_CDNSP_GADGET
It doesn't support LS.
config USB_CDNSP_HOST
bool "Cadence USBSSP host controller"
depends on USB=y || USB=USB_CDNSP
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
@ -124,16 +130,4 @@ config USB_CDNSP_HOST
Host controller is compliant with XHCI so it uses
standard XHCI driver.
config USB_CDNSP_PCI
tristate "Cadence USBSSP support on PCIe-based platforms"
depends on USB_PCI && ACPI
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
endif # USB_CDNSP
endif # USB_CDNS_SUPPORT
endif

View File

@ -4,33 +4,41 @@ 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
ifeq ($(CONFIG_USB),m)
obj-m += cdns-usb-common.o
obj-m += cdns3-plat.o
obj-m += cdns3.o
else
obj-$(CONFIG_USB_CDNS_SUPPORT) += cdns-usb-common.o
obj-$(CONFIG_USB_CDNS_SUPPORT) += cdns3-plat.o
obj-$(CONFIG_USB_CDNS3) += cdns3.o
endif
cdns-usb-common-$(CONFIG_USB_CDNS_HOST) += host.o
cdns3-$(CONFIG_USB_CDNS3_GADGET) += cdns3-gadget.o cdns3-ep0.o
# For CDNS3 gadget
ifneq ($(CONFIG_USB_CDNS3_GADGET),)
cdns3-y := cdns3-gadget.o cdns3-ep0.o
cdns3-$(CONFIG_TRACING) += cdns3-trace.o
obj-$(CONFIG_USB_CDNS3) += cdns3.o
endif
obj-$(CONFIG_USB_CDNS3_PCI_WRAP) += cdns3-pci-wrap.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
# For CDNSP gadget
ifneq ($(CONFIG_USB_CDNSP_GADGET),)
cdnsp-y := cdnsp-ring.o cdnsp-gadget.o \
cdnsp-mem.o cdnsp-ep0.o
cdnsp-$(CONFIG_TRACING) += cdnsp-trace.o
obj-$(CONFIG_USB_CDNSP) += cdnsp.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
obj-$(CONFIG_USB_CDNSP_PCI) += cdnsp-pci.o

View File

@ -3508,7 +3508,3 @@ int cdns3_gadget_init(struct cdns *cdns)
return 0;
}
EXPORT_SYMBOL_GPL(cdns3_gadget_init);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Cadence USBSS DRD Driver - gadget");

View File

@ -44,14 +44,6 @@ static void set_phy_power_off(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);
}
/**
* cdns3_plat_probe - probe for cdns3 core device
* @pdev: Pointer to cdns3 core platform device
@ -72,8 +64,6 @@ static int cdns3_plat_probe(struct platform_device *pdev)
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);
@ -153,12 +143,9 @@ static int cdns3_plat_probe(struct platform_device *pdev)
if (ret)
goto err_phy_power_on;
ret = cdns_init(cdns);
if (ret)
goto err_cdns_init;
cdns->gadget_init = cdns3_gadget_init;
cdns->gadget_init = cdns3_plat_gadget_init;
ret = cdns_core_init_role(cdns);
ret = cdns_init(cdns);
if (ret)
goto err_cdns_init;

View File

@ -2075,7 +2075,3 @@ int cdnsp_gadget_init(struct cdns *cdns)
return 0;
}
EXPORT_SYMBOL_GPL(cdnsp_gadget_init);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Cadence CDNSP DRD Driver - gadget");

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Cadence USBSSP PCI Glue driver.
* Cadence PCI Glue driver.
*
* Copyright (C) 2019 Cadence.
*
@ -16,19 +16,7 @@
#include <linux/pci.h>
#include "core.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
#include "gadget-export.h"
#define PCI_BAR_HOST 0
#define PCI_BAR_OTG 0
@ -38,16 +26,16 @@ struct cdnsp_wrap {
#define PCI_DEV_FN_OTG 1
#define PCI_DRIVER_NAME "cdns-pci-usbssp"
#define PLAT_DRIVER_NAME "cdns-usb3"
#define PLAT_DRIVER_NAME "cdns-usbssp"
#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 first keeps resources for
* Host/Device while the second keeps resources for DRD/OTG.
* Platform has two function. The fist keeps resources for
* Host/Device while the secon 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);
@ -60,12 +48,11 @@ static struct pci_dev *cdnsp_get_second_fun(struct pci_dev *pdev)
static int cdnsp_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *id)
{
struct platform_device_info plat_info;
static struct cdns3_platform_data pdata;
struct cdnsp_wrap *wrap;
struct resource *res;
struct device *dev = &pdev->dev;
struct pci_dev *func;
int ret = 0;
struct resource *res;
struct cdns *cdnsp;
int ret;
/*
* For GADGET/HOST PCI (devfn) function number is 0,
@ -92,105 +79,146 @@ static int cdnsp_pci_probe(struct pci_dev *pdev,
}
pci_set_master(pdev);
if (pci_is_enabled(func)) {
wrap = pci_get_drvdata(func);
cdnsp = pci_get_drvdata(func);
} else {
wrap = kzalloc_obj(*wrap);
if (!wrap) {
cdnsp = kzalloc_obj(*cdnsp);
if (!cdnsp) {
ret = -ENOMEM;
goto put_pci;
}
}
res = wrap->dev_res;
/* For GADGET device function number is 0. */
if (pdev->devfn == 0) {
resource_size_t rsrc_start, rsrc_len;
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);
/* 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;
}
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);
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;
}
/* 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;
cdnsp->dev_irq = pdev->irq;
dev_dbg(dev, "USBSS-DEV physical base addr: %pa\n",
&rsrc_start);
/* 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;
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;
} else {
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);
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);
/* Interrupt for OTG/DRD. */
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;
cdnsp->otg_irq = pdev->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)) {
/* 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;
}
cdnsp->dev = dev;
cdnsp->gadget_init = cdnsp_gadget_init;
ret = cdns_init(cdnsp);
if (ret)
goto free_cdnsp;
}
pci_set_drvdata(pdev, wrap);
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);
put_pci:
pci_dev_put(func);
return ret;
}
static void cdnsp_pci_remove(struct pci_dev *pdev)
{
struct cdnsp_wrap *wrap;
struct cdns *cdnsp;
struct pci_dev *func;
func = cdnsp_get_second_fun(pdev);
wrap = pci_get_drvdata(pdev);
cdnsp = (struct cdns *)pci_get_drvdata(pdev);
if (wrap->devfn == pdev->devfn)
platform_device_unregister(wrap->plat_dev);
if (pci_dev_run_wake(pdev))
pm_runtime_get_noresume(&pdev->dev);
if (!pci_is_enabled(func))
kfree(wrap);
if (pci_is_enabled(func)) {
cdns_remove(cdnsp);
} else {
kfree(cdnsp);
}
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 },
@ -202,10 +230,13 @@ static const struct pci_device_id cdnsp_pci_ids[] = {
};
static struct pci_driver cdnsp_pci_driver = {
.name = PCI_DRIVER_NAME,
.name = "cdnsp-pci",
.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);
@ -214,4 +245,4 @@ MODULE_DEVICE_TABLE(pci, cdnsp_pci_ids);
MODULE_ALIAS("pci:cdnsp");
MODULE_AUTHOR("Pawel Laszczak <pawell@cadence.com>");
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("Cadence CDNSP PCI wrapper");
MODULE_DESCRIPTION("Cadence CDNSP PCI driver");

View File

@ -80,7 +80,7 @@ static void cdns_exit_roles(struct cdns *cdns)
*
* Returns 0 on success otherwise negative errno
*/
int cdns_core_init_role(struct cdns *cdns)
static int cdns_core_init_role(struct cdns *cdns)
{
struct device *dev = cdns->dev;
enum usb_dr_mode best_dr_mode;
@ -197,14 +197,11 @@ int cdns_core_init_role(struct cdns *cdns)
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.
@ -472,8 +469,14 @@ int cdns_init(struct cdns *cdns)
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);

View File

@ -45,7 +45,6 @@ struct cdns3_platform_data {
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) */
};
/**
@ -120,14 +119,14 @@ struct cdns {
struct cdns3_platform_data *pdata;
spinlock_t lock;
struct xhci_plat_priv *xhci_plat_data;
int (*gadget_init)(struct cdns *cdns);
u32 override_apb_timeout;
int (*gadget_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);

View File

@ -10,7 +10,7 @@
#ifndef __LINUX_CDNS3_GADGET_EXPORT
#define __LINUX_CDNS3_GADGET_EXPORT
#if defined(CONFIG_USB_CDNSP_GADGET) && IS_REACHABLE(CONFIG_USB_CDNSP)
#if IS_ENABLED(CONFIG_USB_CDNSP_GADGET)
int cdnsp_gadget_init(struct cdns *cdns);
#else
@ -22,7 +22,7 @@ static inline int cdnsp_gadget_init(struct cdns *cdns)
#endif /* CONFIG_USB_CDNSP_GADGET */
#if defined(CONFIG_USB_CDNS3_GADGET) && IS_REACHABLE(CONFIG_USB_CDNS3)
#if IS_ENABLED(CONFIG_USB_CDNS3_GADGET)
int cdns3_gadget_init(struct cdns *cdns);
#else