xref: /linux/drivers/usb/gadget/udc/cdns2/cdns2-pci.c (revision ec16a3cdf37e507013062f9c4a2067eacdd12b62)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Cadence USBHS-DEV controller - PCI Glue driver.
4  *
5  * Copyright (C) 2023 Cadence.
6  *
7  * Author: Pawel Laszczak <pawell@cadence.com>
8  *
9  */
10 
11 #include <linux/pm_runtime.h>
12 #include <linux/slab.h>
13 #include <linux/pci.h>
14 
15 #include "cdns2-gadget.h"
16 
17 #define PCI_DRIVER_NAME		"cdns-pci-usbhs"
18 #define PCI_BAR_DEV		0
19 #define PCI_DEV_FN_DEVICE	0
20 
21 static int cdns2_pci_probe(struct pci_dev *pdev,
22 			   const struct pci_device_id *id)
23 {
24 	resource_size_t rsrc_start, rsrc_len;
25 	struct device *dev = &pdev->dev;
26 	struct cdns2_device *priv_dev;
27 	struct resource *res;
28 	int ret;
29 
30 	/* For GADGET PCI (devfn) function number is 0. */
31 	if (!id || pdev->devfn != PCI_DEV_FN_DEVICE ||
32 	    pdev->class != PCI_CLASS_SERIAL_USB_DEVICE)
33 		return -EINVAL;
34 
35 	ret = pcim_enable_device(pdev);
36 	if (ret) {
37 		dev_err(&pdev->dev, "Enabling PCI device has failed %d\n", ret);
38 		return ret;
39 	}
40 
41 	pci_set_master(pdev);
42 
43 	priv_dev = devm_kzalloc(&pdev->dev, sizeof(*priv_dev), GFP_KERNEL);
44 	if (!priv_dev)
45 		return -ENOMEM;
46 
47 	dev_dbg(dev, "Initialize resources\n");
48 	rsrc_start = pci_resource_start(pdev, PCI_BAR_DEV);
49 	rsrc_len = pci_resource_len(pdev, PCI_BAR_DEV);
50 
51 	res = devm_request_mem_region(dev, rsrc_start, rsrc_len, "dev");
52 	if (!res) {
53 		dev_dbg(dev, "controller already in use\n");
54 		return -EBUSY;
55 	}
56 
57 	priv_dev->regs = devm_ioremap(dev, rsrc_start, rsrc_len);
58 	if (!priv_dev->regs) {
59 		dev_dbg(dev, "error mapping memory\n");
60 		return -EFAULT;
61 	}
62 
63 	priv_dev->irq = pdev->irq;
64 	dev_dbg(dev, "USBSS-DEV physical base addr: %pa\n",
65 		&rsrc_start);
66 
67 	priv_dev->dev = dev;
68 
69 	priv_dev->eps_supported = 0x000f000f;
70 	priv_dev->onchip_tx_buf = 16;
71 	priv_dev->onchip_rx_buf = 16;
72 
73 	ret = cdns2_gadget_init(priv_dev);
74 	if (ret)
75 		return ret;
76 
77 	pci_set_drvdata(pdev, priv_dev);
78 
79 	device_wakeup_enable(&pdev->dev);
80 	if (pci_dev_run_wake(pdev))
81 		pm_runtime_put_noidle(&pdev->dev);
82 
83 	return 0;
84 }
85 
86 static void cdns2_pci_remove(struct pci_dev *pdev)
87 {
88 	struct cdns2_device *priv_dev = pci_get_drvdata(pdev);
89 
90 	if (pci_dev_run_wake(pdev))
91 		pm_runtime_get_noresume(&pdev->dev);
92 
93 	cdns2_gadget_remove(priv_dev);
94 }
95 
96 static int cdns2_pci_suspend(struct device *dev)
97 {
98 	struct cdns2_device *priv_dev = dev_get_drvdata(dev);
99 
100 	return cdns2_gadget_suspend(priv_dev);
101 }
102 
103 static int cdns2_pci_resume(struct device *dev)
104 {
105 	struct cdns2_device *priv_dev = dev_get_drvdata(dev);
106 
107 	return cdns2_gadget_resume(priv_dev, 1);
108 }
109 
110 static const struct dev_pm_ops cdns2_pci_pm_ops = {
111 	SYSTEM_SLEEP_PM_OPS(cdns2_pci_suspend, cdns2_pci_resume)
112 };
113 
114 static const struct pci_device_id cdns2_pci_ids[] = {
115 	{ PCI_DEVICE(PCI_VENDOR_ID_CDNS, PCI_DEVICE_ID_CDNS_USB),
116 	  .class = PCI_CLASS_SERIAL_USB_DEVICE },
117 	{ 0, }
118 };
119 
120 static struct pci_driver cdns2_pci_driver = {
121 	.name = "cdns2-pci",
122 	.id_table = cdns2_pci_ids,
123 	.probe = cdns2_pci_probe,
124 	.remove = cdns2_pci_remove,
125 	.driver = {
126 		.pm = pm_ptr(&cdns2_pci_pm_ops),
127 	}
128 };
129 
130 module_pci_driver(cdns2_pci_driver);
131 MODULE_DEVICE_TABLE(pci, cdns2_pci_ids);
132 
133 MODULE_ALIAS("pci:cdns2");
134 MODULE_AUTHOR("Pawel Laszczak <pawell@cadence.com>");
135 MODULE_LICENSE("GPL");
136 MODULE_DESCRIPTION("Cadence CDNS2 PCI driver");
137