diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-11 08:27:49 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-11 08:27:49 +0000 |
commit | ace9429bb58fd418f0c81d4c2835699bddf6bde6 (patch) | |
tree | b2d64bc10158fdd5497876388cd68142ca374ed3 /drivers/usb/gadget/udc/cdns2/cdns2-pci.c | |
parent | Initial commit. (diff) | |
download | linux-ace9429bb58fd418f0c81d4c2835699bddf6bde6.tar.xz linux-ace9429bb58fd418f0c81d4c2835699bddf6bde6.zip |
Adding upstream version 6.6.15.upstream/6.6.15
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'drivers/usb/gadget/udc/cdns2/cdns2-pci.c')
-rw-r--r-- | drivers/usb/gadget/udc/cdns2/cdns2-pci.c | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/drivers/usb/gadget/udc/cdns2/cdns2-pci.c b/drivers/usb/gadget/udc/cdns2/cdns2-pci.c new file mode 100644 index 0000000000..1691541c94 --- /dev/null +++ b/drivers/usb/gadget/udc/cdns2/cdns2-pci.c @@ -0,0 +1,138 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Cadence USBHS-DEV controller - PCI Glue driver. + * + * Copyright (C) 2023 Cadence. + * + * Author: Pawel Laszczak <pawell@cadence.com> + * + */ + +#include <linux/pm_runtime.h> +#include <linux/slab.h> +#include <linux/pci.h> + +#include "cdns2-gadget.h" + +#define PCI_DRIVER_NAME "cdns-pci-usbhs" +#define CDNS_VENDOR_ID 0x17cd +#define CDNS_DEVICE_ID 0x0120 +#define PCI_BAR_DEV 0 +#define PCI_DEV_FN_DEVICE 0 + +static int cdns2_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *id) +{ + resource_size_t rsrc_start, rsrc_len; + struct device *dev = &pdev->dev; + struct cdns2_device *priv_dev; + struct resource *res; + int ret; + + /* For GADGET PCI (devfn) function number is 0. */ + if (!id || pdev->devfn != PCI_DEV_FN_DEVICE || + pdev->class != PCI_CLASS_SERIAL_USB_DEVICE) + return -EINVAL; + + ret = pcim_enable_device(pdev); + if (ret) { + dev_err(&pdev->dev, "Enabling PCI device has failed %d\n", ret); + return ret; + } + + pci_set_master(pdev); + + priv_dev = devm_kzalloc(&pdev->dev, sizeof(*priv_dev), GFP_KERNEL); + if (!priv_dev) + return -ENOMEM; + + 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"); + return -EBUSY; + } + + priv_dev->regs = devm_ioremap(dev, rsrc_start, rsrc_len); + if (!priv_dev->regs) { + dev_dbg(dev, "error mapping memory\n"); + return -EFAULT; + } + + priv_dev->irq = pdev->irq; + dev_dbg(dev, "USBSS-DEV physical base addr: %pa\n", + &rsrc_start); + + priv_dev->dev = dev; + + priv_dev->eps_supported = 0x000f000f; + priv_dev->onchip_tx_buf = 16; + priv_dev->onchip_rx_buf = 16; + + ret = cdns2_gadget_init(priv_dev); + if (ret) + return ret; + + pci_set_drvdata(pdev, priv_dev); + + device_wakeup_enable(&pdev->dev); + if (pci_dev_run_wake(pdev)) + pm_runtime_put_noidle(&pdev->dev); + + return 0; +} + +static void cdns2_pci_remove(struct pci_dev *pdev) +{ + struct cdns2_device *priv_dev = pci_get_drvdata(pdev); + + if (pci_dev_run_wake(pdev)) + pm_runtime_get_noresume(&pdev->dev); + + cdns2_gadget_remove(priv_dev); +} + +static int cdns2_pci_suspend(struct device *dev) +{ + struct cdns2_device *priv_dev = dev_get_drvdata(dev); + + return cdns2_gadget_suspend(priv_dev); +} + +static int cdns2_pci_resume(struct device *dev) +{ + struct cdns2_device *priv_dev = dev_get_drvdata(dev); + + return cdns2_gadget_resume(priv_dev, 1); +} + +static const struct dev_pm_ops cdns2_pci_pm_ops = { + SYSTEM_SLEEP_PM_OPS(cdns2_pci_suspend, cdns2_pci_resume) +}; + +static const struct pci_device_id cdns2_pci_ids[] = { + { PCI_VENDOR_ID_CDNS, CDNS_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, + PCI_CLASS_SERIAL_USB_DEVICE, PCI_ANY_ID }, + { 0, } +}; + +static struct pci_driver cdns2_pci_driver = { + .name = "cdns2-pci", + .id_table = &cdns2_pci_ids[0], + .probe = cdns2_pci_probe, + .remove = cdns2_pci_remove, + .driver = { + .pm = pm_ptr(&cdns2_pci_pm_ops), + } +}; + +module_pci_driver(cdns2_pci_driver); +MODULE_DEVICE_TABLE(pci, cdns2_pci_ids); + +MODULE_ALIAS("pci:cdns2"); +MODULE_AUTHOR("Pawel Laszczak <pawell@cadence.com>"); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Cadence CDNS2 PCI driver"); |