Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Cadence PCI Glue driver.
0004  *
0005  * Copyright (C) 2019 Cadence.
0006  *
0007  * Author: Pawel Laszczak <pawell@cadence.com>
0008  *
0009  */
0010 
0011 #include <linux/platform_device.h>
0012 #include <linux/dma-mapping.h>
0013 #include <linux/kernel.h>
0014 #include <linux/module.h>
0015 #include <linux/slab.h>
0016 #include <linux/pci.h>
0017 
0018 #include "core.h"
0019 #include "gadget-export.h"
0020 
0021 #define PCI_BAR_HOST        0
0022 #define PCI_BAR_OTG     0
0023 #define PCI_BAR_DEV     2
0024 
0025 #define PCI_DEV_FN_HOST_DEVICE  0
0026 #define PCI_DEV_FN_OTG      1
0027 
0028 #define PCI_DRIVER_NAME     "cdns-pci-usbssp"
0029 #define PLAT_DRIVER_NAME    "cdns-usbssp"
0030 
0031 #define CDNS_VENDOR_ID      0x17cd
0032 #define CDNS_DEVICE_ID      0x0100
0033 #define CDNS_DRD_IF     (PCI_CLASS_SERIAL_USB << 8 | 0x80)
0034 
0035 static struct pci_dev *cdnsp_get_second_fun(struct pci_dev *pdev)
0036 {
0037     struct pci_dev *func;
0038 
0039     /*
0040      * Gets the second function.
0041      * It's little tricky, but this platform has two function.
0042      * The fist keeps resources for Host/Device while the second
0043      * keeps resources for DRD/OTG.
0044      */
0045     func = pci_get_device(pdev->vendor, pdev->device, NULL);
0046     if (!func)
0047         return NULL;
0048 
0049     if (func->devfn == pdev->devfn) {
0050         func = pci_get_device(pdev->vendor, pdev->device, func);
0051         if (!func)
0052             return NULL;
0053     }
0054 
0055     return func;
0056 }
0057 
0058 static int cdnsp_pci_probe(struct pci_dev *pdev,
0059                const struct pci_device_id *id)
0060 {
0061     struct device *dev = &pdev->dev;
0062     struct pci_dev *func;
0063     struct resource *res;
0064     struct cdns *cdnsp;
0065     int ret;
0066 
0067     /*
0068      * For GADGET/HOST PCI (devfn) function number is 0,
0069      * for OTG PCI (devfn) function number is 1.
0070      */
0071     if (!id || (pdev->devfn != PCI_DEV_FN_HOST_DEVICE &&
0072             pdev->devfn != PCI_DEV_FN_OTG))
0073         return -EINVAL;
0074 
0075     func = cdnsp_get_second_fun(pdev);
0076     if (!func)
0077         return -EINVAL;
0078 
0079     if (func->class == PCI_CLASS_SERIAL_USB_XHCI ||
0080         pdev->class == PCI_CLASS_SERIAL_USB_XHCI) {
0081         ret = -EINVAL;
0082         goto put_pci;
0083     }
0084 
0085     ret = pcim_enable_device(pdev);
0086     if (ret) {
0087         dev_err(&pdev->dev, "Enabling PCI device has failed %d\n", ret);
0088         goto put_pci;
0089     }
0090 
0091     pci_set_master(pdev);
0092     if (pci_is_enabled(func)) {
0093         cdnsp = pci_get_drvdata(func);
0094     } else {
0095         cdnsp = kzalloc(sizeof(*cdnsp), GFP_KERNEL);
0096         if (!cdnsp) {
0097             ret = -ENOMEM;
0098             goto disable_pci;
0099         }
0100     }
0101 
0102     /* For GADGET device function number is 0. */
0103     if (pdev->devfn == 0) {
0104         resource_size_t rsrc_start, rsrc_len;
0105 
0106         /* Function 0: host(BAR_0) + device(BAR_1).*/
0107         dev_dbg(dev, "Initialize resources\n");
0108         rsrc_start = pci_resource_start(pdev, PCI_BAR_DEV);
0109         rsrc_len = pci_resource_len(pdev, PCI_BAR_DEV);
0110         res = devm_request_mem_region(dev, rsrc_start, rsrc_len, "dev");
0111         if (!res) {
0112             dev_dbg(dev, "controller already in use\n");
0113             ret = -EBUSY;
0114             goto free_cdnsp;
0115         }
0116 
0117         cdnsp->dev_regs = devm_ioremap(dev, rsrc_start, rsrc_len);
0118         if (!cdnsp->dev_regs) {
0119             dev_dbg(dev, "error mapping memory\n");
0120             ret = -EFAULT;
0121             goto free_cdnsp;
0122         }
0123 
0124         cdnsp->dev_irq = pdev->irq;
0125         dev_dbg(dev, "USBSS-DEV physical base addr: %pa\n",
0126             &rsrc_start);
0127 
0128         res = &cdnsp->xhci_res[0];
0129         res->start = pci_resource_start(pdev, PCI_BAR_HOST);
0130         res->end = pci_resource_end(pdev, PCI_BAR_HOST);
0131         res->name = "xhci";
0132         res->flags = IORESOURCE_MEM;
0133         dev_dbg(dev, "USBSS-XHCI physical base addr: %pa\n",
0134             &res->start);
0135 
0136         /* Interrupt for XHCI, */
0137         res = &cdnsp->xhci_res[1];
0138         res->start = pdev->irq;
0139         res->name = "host";
0140         res->flags = IORESOURCE_IRQ;
0141     } else {
0142         res = &cdnsp->otg_res;
0143         res->start = pci_resource_start(pdev, PCI_BAR_OTG);
0144         res->end =   pci_resource_end(pdev, PCI_BAR_OTG);
0145         res->name = "otg";
0146         res->flags = IORESOURCE_MEM;
0147         dev_dbg(dev, "CDNSP-DRD physical base addr: %pa\n",
0148             &res->start);
0149 
0150         /* Interrupt for OTG/DRD. */
0151         cdnsp->otg_irq = pdev->irq;
0152     }
0153 
0154     if (pci_is_enabled(func)) {
0155         cdnsp->dev = dev;
0156         cdnsp->gadget_init = cdnsp_gadget_init;
0157 
0158         ret = cdns_init(cdnsp);
0159         if (ret)
0160             goto free_cdnsp;
0161     }
0162 
0163     pci_set_drvdata(pdev, cdnsp);
0164 
0165     device_wakeup_enable(&pdev->dev);
0166     if (pci_dev_run_wake(pdev))
0167         pm_runtime_put_noidle(&pdev->dev);
0168 
0169     return 0;
0170 
0171 free_cdnsp:
0172     if (!pci_is_enabled(func))
0173         kfree(cdnsp);
0174 
0175 disable_pci:
0176     pci_disable_device(pdev);
0177 
0178 put_pci:
0179     pci_dev_put(func);
0180 
0181     return ret;
0182 }
0183 
0184 static void cdnsp_pci_remove(struct pci_dev *pdev)
0185 {
0186     struct cdns *cdnsp;
0187     struct pci_dev *func;
0188 
0189     func = cdnsp_get_second_fun(pdev);
0190     cdnsp = (struct cdns *)pci_get_drvdata(pdev);
0191 
0192     if (pci_dev_run_wake(pdev))
0193         pm_runtime_get_noresume(&pdev->dev);
0194 
0195     if (!pci_is_enabled(func)) {
0196         kfree(cdnsp);
0197         goto pci_put;
0198     }
0199 
0200     cdns_remove(cdnsp);
0201 
0202 pci_put:
0203     pci_dev_put(func);
0204 }
0205 
0206 static int __maybe_unused cdnsp_pci_suspend(struct device *dev)
0207 {
0208     struct cdns *cdns = dev_get_drvdata(dev);
0209 
0210     return cdns_suspend(cdns);
0211 }
0212 
0213 static int __maybe_unused cdnsp_pci_resume(struct device *dev)
0214 {
0215     struct cdns *cdns = dev_get_drvdata(dev);
0216     unsigned long flags;
0217     int ret;
0218 
0219     spin_lock_irqsave(&cdns->lock, flags);
0220     ret = cdns_resume(cdns, 1);
0221     spin_unlock_irqrestore(&cdns->lock, flags);
0222 
0223     return ret;
0224 }
0225 
0226 static const struct dev_pm_ops cdnsp_pci_pm_ops = {
0227     SET_SYSTEM_SLEEP_PM_OPS(cdnsp_pci_suspend, cdnsp_pci_resume)
0228 };
0229 
0230 static const struct pci_device_id cdnsp_pci_ids[] = {
0231     { PCI_VENDOR_ID_CDNS, CDNS_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,
0232       PCI_CLASS_SERIAL_USB_DEVICE, PCI_ANY_ID },
0233     { PCI_VENDOR_ID_CDNS, CDNS_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,
0234       CDNS_DRD_IF, PCI_ANY_ID },
0235     { 0, }
0236 };
0237 
0238 static struct pci_driver cdnsp_pci_driver = {
0239     .name = "cdnsp-pci",
0240     .id_table = &cdnsp_pci_ids[0],
0241     .probe = cdnsp_pci_probe,
0242     .remove = cdnsp_pci_remove,
0243     .driver = {
0244         .pm = &cdnsp_pci_pm_ops,
0245     }
0246 };
0247 
0248 module_pci_driver(cdnsp_pci_driver);
0249 MODULE_DEVICE_TABLE(pci, cdnsp_pci_ids);
0250 
0251 MODULE_ALIAS("pci:cdnsp");
0252 MODULE_AUTHOR("Pawel Laszczak <pawell@cadence.com>");
0253 MODULE_LICENSE("GPL v2");
0254 MODULE_DESCRIPTION("Cadence CDNSP PCI driver");