Blame view
drivers/usb/dwc3/dwc3-pci.c
6.47 KB
72246da40 usb: Introduce De... |
1 2 3 4 |
/** * dwc3-pci.c - PCI Specific glue layer * * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com |
72246da40 usb: Introduce De... |
5 6 7 8 |
* * Authors: Felipe Balbi <balbi@ti.com>, * Sebastian Andrzej Siewior <bigeasy@linutronix.de> * |
5945f789c usb: dwc3: switch... |
9 10 11 |
* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 of * the License as published by the Free Software Foundation. |
72246da40 usb: Introduce De... |
12 |
* |
5945f789c usb: dwc3: switch... |
13 14 15 16 |
* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. |
72246da40 usb: Introduce De... |
17 18 19 |
*/ #include <linux/kernel.h> |
46a57283e usb: include modu... |
20 |
#include <linux/module.h> |
72246da40 usb: Introduce De... |
21 22 23 |
#include <linux/slab.h> #include <linux/pci.h> #include <linux/platform_device.h> |
e3ec3eb79 usb: dwc3: pci: a... |
24 |
#include <linux/usb/otg.h> |
d7078df6b usb: phy: rename ... |
25 |
#include <linux/usb/usb_phy_generic.h> |
e3ec3eb79 usb: dwc3: pci: a... |
26 |
|
8f317b471 usb: dwc3: initia... |
27 |
#include "platform_data.h" |
72246da40 usb: Introduce De... |
28 29 30 |
/* FIXME define these in <linux/pci_ids.h> */ #define PCI_VENDOR_ID_SYNOPSYS 0x16c3 #define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3 0xabcd |
b62cd96de usb: dwc3: pci: a... |
31 |
#define PCI_DEVICE_ID_INTEL_BYT 0x0f37 |
85601f8cf usb: dwc3: add su... |
32 |
#define PCI_DEVICE_ID_INTEL_MRFLD 0x119e |
7d643664e usb: dwc3: pci: A... |
33 |
#define PCI_DEVICE_ID_INTEL_BSW 0x22B7 |
84a2b61b6 usb: dwc3: pci: a... |
34 35 |
#define PCI_DEVICE_ID_INTEL_SPTLP 0x9d30 #define PCI_DEVICE_ID_INTEL_SPTH 0xa130 |
72246da40 usb: Introduce De... |
36 |
|
72246da40 usb: Introduce De... |
37 38 39 |
struct dwc3_pci { struct device *dev; struct platform_device *dwc3; |
e3ec3eb79 usb: dwc3: pci: a... |
40 41 |
struct platform_device *usb2_phy; struct platform_device *usb3_phy; |
72246da40 usb: Introduce De... |
42 |
}; |
41ac7b3ab usb: remove use o... |
43 |
static int dwc3_pci_register_phys(struct dwc3_pci *glue) |
e3ec3eb79 usb: dwc3: pci: a... |
44 |
{ |
4525beeb9 usb: phy: rename ... |
45 |
struct usb_phy_generic_platform_data pdata; |
e3ec3eb79 usb: dwc3: pci: a... |
46 47 48 49 |
struct platform_device *pdev; int ret; memset(&pdata, 0x00, sizeof(pdata)); |
4525beeb9 usb: phy: rename ... |
50 |
pdev = platform_device_alloc("usb_phy_generic", 0); |
e3ec3eb79 usb: dwc3: pci: a... |
51 52 53 54 55 |
if (!pdev) return -ENOMEM; glue->usb2_phy = pdev; pdata.type = USB_PHY_TYPE_USB2; |
13518673f usb: dwc3: fix th... |
56 |
pdata.gpio_reset = -1; |
e3ec3eb79 usb: dwc3: pci: a... |
57 58 59 60 |
ret = platform_device_add_data(glue->usb2_phy, &pdata, sizeof(pdata)); if (ret) goto err1; |
4525beeb9 usb: phy: rename ... |
61 |
pdev = platform_device_alloc("usb_phy_generic", 1); |
e3ec3eb79 usb: dwc3: pci: a... |
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
if (!pdev) { ret = -ENOMEM; goto err1; } glue->usb3_phy = pdev; pdata.type = USB_PHY_TYPE_USB3; ret = platform_device_add_data(glue->usb3_phy, &pdata, sizeof(pdata)); if (ret) goto err2; ret = platform_device_add(glue->usb2_phy); if (ret) goto err2; ret = platform_device_add(glue->usb3_phy); if (ret) goto err3; return 0; err3: platform_device_del(glue->usb2_phy); err2: platform_device_put(glue->usb3_phy); err1: platform_device_put(glue->usb2_phy); return ret; } |
41ac7b3ab usb: remove use o... |
95 |
static int dwc3_pci_probe(struct pci_dev *pci, |
72246da40 usb: Introduce De... |
96 97 98 99 100 |
const struct pci_device_id *id) { struct resource res[2]; struct platform_device *dwc3; struct dwc3_pci *glue; |
b09e99ee7 usb: dwc3: no nee... |
101 |
int ret; |
802ca8506 usb: dwc3: use de... |
102 |
struct device *dev = &pci->dev; |
8f317b471 usb: dwc3: initia... |
103 104 105 |
struct dwc3_platform_data dwc3_pdata; memset(&dwc3_pdata, 0x00, sizeof(dwc3_pdata)); |
72246da40 usb: Introduce De... |
106 |
|
802ca8506 usb: dwc3: use de... |
107 |
glue = devm_kzalloc(dev, sizeof(*glue), GFP_KERNEL); |
734d5a539 usb: dwc3: remove... |
108 |
if (!glue) |
802ca8506 usb: dwc3: use de... |
109 |
return -ENOMEM; |
72246da40 usb: Introduce De... |
110 |
|
1d0467939 usb: dwc3: clean ... |
111 |
glue->dev = dev; |
72246da40 usb: Introduce De... |
112 |
|
f1c7e7108 usb: dwc3: conver... |
113 |
ret = pcim_enable_device(pci); |
72246da40 usb: Introduce De... |
114 |
if (ret) { |
802ca8506 usb: dwc3: use de... |
115 116 117 |
dev_err(dev, "failed to enable pci device "); return -ENODEV; |
72246da40 usb: Introduce De... |
118 |
} |
72246da40 usb: Introduce De... |
119 |
pci_set_master(pci); |
e3ec3eb79 usb: dwc3: pci: a... |
120 121 122 123 124 125 |
ret = dwc3_pci_register_phys(glue); if (ret) { dev_err(dev, "couldn't register PHYs "); return ret; } |
124dafde8 usb: dwc3: remove... |
126 |
dwc3 = platform_device_alloc("dwc3", PLATFORM_DEVID_AUTO); |
72246da40 usb: Introduce De... |
127 |
if (!dwc3) { |
802ca8506 usb: dwc3: use de... |
128 129 |
dev_err(dev, "couldn't allocate dwc3 device "); |
f1c7e7108 usb: dwc3: conver... |
130 |
return -ENOMEM; |
72246da40 usb: Introduce De... |
131 132 133 134 135 136 137 138 139 140 141 142 |
} memset(res, 0x00, sizeof(struct resource) * ARRAY_SIZE(res)); res[0].start = pci_resource_start(pci, 0); res[0].end = pci_resource_end(pci, 0); res[0].name = "dwc_usb3"; res[0].flags = IORESOURCE_MEM; res[1].start = pci->irq; res[1].name = "dwc_usb3"; res[1].flags = IORESOURCE_IRQ; |
9755449d5 usb: dwc3: add su... |
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 |
if (pci->vendor == PCI_VENDOR_ID_AMD && pci->device == PCI_DEVICE_ID_AMD_NL_USB) { dwc3_pdata.has_lpm_erratum = true; dwc3_pdata.lpm_nyet_threshold = 0xf; dwc3_pdata.u2exit_lfps_quirk = true; dwc3_pdata.u2ss_inp3_quirk = true; dwc3_pdata.req_p1p2p3_quirk = true; dwc3_pdata.del_p1p2p3_quirk = true; dwc3_pdata.del_phy_power_chg_quirk = true; dwc3_pdata.lfps_filter_quirk = true; dwc3_pdata.rx_detect_poll_quirk = true; dwc3_pdata.tx_de_emphasis_quirk = true; dwc3_pdata.tx_de_emphasis = 1; /* * FIXME these quirks should be removed when AMD NL * taps out */ dwc3_pdata.disable_scramble_quirk = true; dwc3_pdata.dis_u3_susphy_quirk = true; dwc3_pdata.dis_u2_susphy_quirk = true; } |
72246da40 usb: Introduce De... |
167 168 |
ret = platform_device_add_resources(dwc3, res, ARRAY_SIZE(res)); if (ret) { |
802ca8506 usb: dwc3: use de... |
169 170 |
dev_err(dev, "couldn't add resources to dwc3 device "); |
f1c7e7108 usb: dwc3: conver... |
171 |
return ret; |
72246da40 usb: Introduce De... |
172 173 174 |
} pci_set_drvdata(pci, glue); |
8f317b471 usb: dwc3: initia... |
175 176 177 |
ret = platform_device_add_data(dwc3, &dwc3_pdata, sizeof(dwc3_pdata)); if (ret) goto err3; |
802ca8506 usb: dwc3: use de... |
178 |
dma_set_coherent_mask(&dwc3->dev, dev->coherent_dma_mask); |
72246da40 usb: Introduce De... |
179 |
|
802ca8506 usb: dwc3: use de... |
180 181 182 |
dwc3->dev.dma_mask = dev->dma_mask; dwc3->dev.dma_parms = dev->dma_parms; dwc3->dev.parent = dev; |
1d0467939 usb: dwc3: clean ... |
183 |
glue->dwc3 = dwc3; |
72246da40 usb: Introduce De... |
184 185 186 |
ret = platform_device_add(dwc3); if (ret) { |
802ca8506 usb: dwc3: use de... |
187 188 189 |
dev_err(dev, "failed to register dwc3 device "); goto err3; |
72246da40 usb: Introduce De... |
190 191 192 |
} return 0; |
802ca8506 usb: dwc3: use de... |
193 |
err3: |
72246da40 usb: Introduce De... |
194 |
platform_device_put(dwc3); |
72246da40 usb: Introduce De... |
195 196 |
return ret; } |
fb4e98ab6 usb: remove use o... |
197 |
static void dwc3_pci_remove(struct pci_dev *pci) |
72246da40 usb: Introduce De... |
198 199 |
{ struct dwc3_pci *glue = pci_get_drvdata(pci); |
f28c42c57 usb: dwc3: pci: P... |
200 |
platform_device_unregister(glue->dwc3); |
e3ec3eb79 usb: dwc3: pci: a... |
201 202 |
platform_device_unregister(glue->usb2_phy); platform_device_unregister(glue->usb3_phy); |
72246da40 usb: Introduce De... |
203 |
} |
782df20c5 usb: dwc3: pci: r... |
204 |
static const struct pci_device_id dwc3_pci_id_table[] = { |
72246da40 usb: Introduce De... |
205 206 207 208 |
{ PCI_DEVICE(PCI_VENDOR_ID_SYNOPSYS, PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3), }, |
7d643664e usb: dwc3: pci: A... |
209 |
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BSW), }, |
b62cd96de usb: dwc3: pci: a... |
210 |
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BYT), }, |
85601f8cf usb: dwc3: add su... |
211 |
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MRFLD), }, |
84a2b61b6 usb: dwc3: pci: a... |
212 213 |
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SPTLP), }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SPTH), }, |
9755449d5 usb: dwc3: add su... |
214 |
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_NL_USB), }, |
72246da40 usb: Introduce De... |
215 216 217 |
{ } /* Terminating Entry */ }; MODULE_DEVICE_TABLE(pci, dwc3_pci_id_table); |
fb74d282d usb: dwc3: pci: a... |
218 |
#ifdef CONFIG_PM_SLEEP |
68907a774 usb: dwc3: pci: a... |
219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 |
static int dwc3_pci_suspend(struct device *dev) { struct pci_dev *pci = to_pci_dev(dev); pci_disable_device(pci); return 0; } static int dwc3_pci_resume(struct device *dev) { struct pci_dev *pci = to_pci_dev(dev); int ret; ret = pci_enable_device(pci); if (ret) { dev_err(dev, "can't re-enable device --> %d ", ret); return ret; } pci_set_master(pci); return 0; } |
fb74d282d usb: dwc3: pci: a... |
244 |
#endif /* CONFIG_PM_SLEEP */ |
68907a774 usb: dwc3: pci: a... |
245 246 247 248 |
static const struct dev_pm_ops dwc3_pci_dev_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(dwc3_pci_suspend, dwc3_pci_resume) }; |
72246da40 usb: Introduce De... |
249 |
static struct pci_driver dwc3_pci_driver = { |
0949e99b0 usb: dwc3: fetch ... |
250 |
.name = "dwc3-pci", |
72246da40 usb: Introduce De... |
251 252 |
.id_table = dwc3_pci_id_table, .probe = dwc3_pci_probe, |
7690417db usb: remove use o... |
253 |
.remove = dwc3_pci_remove, |
68907a774 usb: dwc3: pci: a... |
254 |
.driver = { |
fb74d282d usb: dwc3: pci: a... |
255 |
.pm = &dwc3_pci_dev_pm_ops, |
68907a774 usb: dwc3: pci: a... |
256 |
}, |
72246da40 usb: Introduce De... |
257 258 259 |
}; MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>"); |
5945f789c usb: dwc3: switch... |
260 |
MODULE_LICENSE("GPL v2"); |
72246da40 usb: Introduce De... |
261 |
MODULE_DESCRIPTION("DesignWare USB3 PCI Glue Layer"); |
956563362 DWC3: use module_... |
262 |
module_pci_driver(dwc3_pci_driver); |