diff options
Diffstat (limited to 'drivers/usb/dwc3/dwc3-pci.c')
-rw-r--r-- | drivers/usb/dwc3/dwc3-pci.c | 178 |
1 files changed, 32 insertions, 146 deletions
diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index b642a2f998f9..8d950569d557 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c | |||
@@ -22,9 +22,6 @@ | |||
22 | #include <linux/pci.h> | 22 | #include <linux/pci.h> |
23 | #include <linux/platform_device.h> | 23 | #include <linux/platform_device.h> |
24 | 24 | ||
25 | #include <linux/usb/otg.h> | ||
26 | #include <linux/usb/usb_phy_generic.h> | ||
27 | |||
28 | #include "platform_data.h" | 25 | #include "platform_data.h" |
29 | 26 | ||
30 | /* FIXME define these in <linux/pci_ids.h> */ | 27 | /* FIXME define these in <linux/pci_ids.h> */ |
@@ -36,66 +33,41 @@ | |||
36 | #define PCI_DEVICE_ID_INTEL_SPTLP 0x9d30 | 33 | #define PCI_DEVICE_ID_INTEL_SPTLP 0x9d30 |
37 | #define PCI_DEVICE_ID_INTEL_SPTH 0xa130 | 34 | #define PCI_DEVICE_ID_INTEL_SPTH 0xa130 |
38 | 35 | ||
39 | struct dwc3_pci { | 36 | static int dwc3_pci_quirks(struct pci_dev *pdev) |
40 | struct device *dev; | ||
41 | struct platform_device *dwc3; | ||
42 | struct platform_device *usb2_phy; | ||
43 | struct platform_device *usb3_phy; | ||
44 | }; | ||
45 | |||
46 | static int dwc3_pci_register_phys(struct dwc3_pci *glue) | ||
47 | { | 37 | { |
48 | struct usb_phy_generic_platform_data pdata; | 38 | if (pdev->vendor == PCI_VENDOR_ID_AMD && |
49 | struct platform_device *pdev; | 39 | pdev->device == PCI_DEVICE_ID_AMD_NL_USB) { |
50 | int ret; | 40 | struct dwc3_platform_data pdata; |
51 | 41 | ||
52 | memset(&pdata, 0x00, sizeof(pdata)); | 42 | memset(&pdata, 0, sizeof(pdata)); |
53 | 43 | ||
54 | pdev = platform_device_alloc("usb_phy_generic", 0); | 44 | pdata.has_lpm_erratum = true; |
55 | if (!pdev) | 45 | pdata.lpm_nyet_threshold = 0xf; |
56 | return -ENOMEM; | ||
57 | |||
58 | glue->usb2_phy = pdev; | ||
59 | pdata.type = USB_PHY_TYPE_USB2; | ||
60 | pdata.gpio_reset = -1; | ||
61 | 46 | ||
62 | ret = platform_device_add_data(glue->usb2_phy, &pdata, sizeof(pdata)); | 47 | pdata.u2exit_lfps_quirk = true; |
63 | if (ret) | 48 | pdata.u2ss_inp3_quirk = true; |
64 | goto err1; | 49 | pdata.req_p1p2p3_quirk = true; |
50 | pdata.del_p1p2p3_quirk = true; | ||
51 | pdata.del_phy_power_chg_quirk = true; | ||
52 | pdata.lfps_filter_quirk = true; | ||
53 | pdata.rx_detect_poll_quirk = true; | ||
65 | 54 | ||
66 | pdev = platform_device_alloc("usb_phy_generic", 1); | 55 | pdata.tx_de_emphasis_quirk = true; |
67 | if (!pdev) { | 56 | pdata.tx_de_emphasis = 1; |
68 | ret = -ENOMEM; | ||
69 | goto err1; | ||
70 | } | ||
71 | 57 | ||
72 | glue->usb3_phy = pdev; | 58 | /* |
73 | pdata.type = USB_PHY_TYPE_USB3; | 59 | * FIXME these quirks should be removed when AMD NL |
74 | 60 | * taps out | |
75 | ret = platform_device_add_data(glue->usb3_phy, &pdata, sizeof(pdata)); | 61 | */ |
76 | if (ret) | 62 | pdata.disable_scramble_quirk = true; |
77 | goto err2; | 63 | pdata.dis_u3_susphy_quirk = true; |
78 | 64 | pdata.dis_u2_susphy_quirk = true; | |
79 | ret = platform_device_add(glue->usb2_phy); | ||
80 | if (ret) | ||
81 | goto err2; | ||
82 | 65 | ||
83 | ret = platform_device_add(glue->usb3_phy); | 66 | return platform_device_add_data(pci_get_drvdata(pdev), &pdata, |
84 | if (ret) | 67 | sizeof(pdata)); |
85 | goto err3; | 68 | } |
86 | 69 | ||
87 | return 0; | 70 | return 0; |
88 | |||
89 | err3: | ||
90 | platform_device_del(glue->usb2_phy); | ||
91 | |||
92 | err2: | ||
93 | platform_device_put(glue->usb3_phy); | ||
94 | |||
95 | err1: | ||
96 | platform_device_put(glue->usb2_phy); | ||
97 | |||
98 | return ret; | ||
99 | } | 71 | } |
100 | 72 | ||
101 | static int dwc3_pci_probe(struct pci_dev *pci, | 73 | static int dwc3_pci_probe(struct pci_dev *pci, |
@@ -103,18 +75,8 @@ static int dwc3_pci_probe(struct pci_dev *pci, | |||
103 | { | 75 | { |
104 | struct resource res[2]; | 76 | struct resource res[2]; |
105 | struct platform_device *dwc3; | 77 | struct platform_device *dwc3; |
106 | struct dwc3_pci *glue; | ||
107 | int ret; | 78 | int ret; |
108 | struct device *dev = &pci->dev; | 79 | struct device *dev = &pci->dev; |
109 | struct dwc3_platform_data dwc3_pdata; | ||
110 | |||
111 | memset(&dwc3_pdata, 0x00, sizeof(dwc3_pdata)); | ||
112 | |||
113 | glue = devm_kzalloc(dev, sizeof(*glue), GFP_KERNEL); | ||
114 | if (!glue) | ||
115 | return -ENOMEM; | ||
116 | |||
117 | glue->dev = dev; | ||
118 | 80 | ||
119 | ret = pcim_enable_device(pci); | 81 | ret = pcim_enable_device(pci); |
120 | if (ret) { | 82 | if (ret) { |
@@ -124,12 +86,6 @@ static int dwc3_pci_probe(struct pci_dev *pci, | |||
124 | 86 | ||
125 | pci_set_master(pci); | 87 | pci_set_master(pci); |
126 | 88 | ||
127 | ret = dwc3_pci_register_phys(glue); | ||
128 | if (ret) { | ||
129 | dev_err(dev, "couldn't register PHYs\n"); | ||
130 | return ret; | ||
131 | } | ||
132 | |||
133 | dwc3 = platform_device_alloc("dwc3", PLATFORM_DEVID_AUTO); | 89 | dwc3 = platform_device_alloc("dwc3", PLATFORM_DEVID_AUTO); |
134 | if (!dwc3) { | 90 | if (!dwc3) { |
135 | dev_err(dev, "couldn't allocate dwc3 device\n"); | 91 | dev_err(dev, "couldn't allocate dwc3 device\n"); |
@@ -147,70 +103,34 @@ static int dwc3_pci_probe(struct pci_dev *pci, | |||
147 | res[1].name = "dwc_usb3"; | 103 | res[1].name = "dwc_usb3"; |
148 | res[1].flags = IORESOURCE_IRQ; | 104 | res[1].flags = IORESOURCE_IRQ; |
149 | 105 | ||
150 | if (pci->vendor == PCI_VENDOR_ID_AMD && | ||
151 | pci->device == PCI_DEVICE_ID_AMD_NL_USB) { | ||
152 | dwc3_pdata.has_lpm_erratum = true; | ||
153 | dwc3_pdata.lpm_nyet_threshold = 0xf; | ||
154 | |||
155 | dwc3_pdata.u2exit_lfps_quirk = true; | ||
156 | dwc3_pdata.u2ss_inp3_quirk = true; | ||
157 | dwc3_pdata.req_p1p2p3_quirk = true; | ||
158 | dwc3_pdata.del_p1p2p3_quirk = true; | ||
159 | dwc3_pdata.del_phy_power_chg_quirk = true; | ||
160 | dwc3_pdata.lfps_filter_quirk = true; | ||
161 | dwc3_pdata.rx_detect_poll_quirk = true; | ||
162 | |||
163 | dwc3_pdata.tx_de_emphasis_quirk = true; | ||
164 | dwc3_pdata.tx_de_emphasis = 1; | ||
165 | |||
166 | /* | ||
167 | * FIXME these quirks should be removed when AMD NL | ||
168 | * taps out | ||
169 | */ | ||
170 | dwc3_pdata.disable_scramble_quirk = true; | ||
171 | dwc3_pdata.dis_u3_susphy_quirk = true; | ||
172 | dwc3_pdata.dis_u2_susphy_quirk = true; | ||
173 | } | ||
174 | |||
175 | ret = platform_device_add_resources(dwc3, res, ARRAY_SIZE(res)); | 106 | ret = platform_device_add_resources(dwc3, res, ARRAY_SIZE(res)); |
176 | if (ret) { | 107 | if (ret) { |
177 | dev_err(dev, "couldn't add resources to dwc3 device\n"); | 108 | dev_err(dev, "couldn't add resources to dwc3 device\n"); |
178 | return ret; | 109 | return ret; |
179 | } | 110 | } |
180 | 111 | ||
181 | pci_set_drvdata(pci, glue); | 112 | pci_set_drvdata(pci, dwc3); |
182 | 113 | ret = dwc3_pci_quirks(pci); | |
183 | ret = platform_device_add_data(dwc3, &dwc3_pdata, sizeof(dwc3_pdata)); | ||
184 | if (ret) | 114 | if (ret) |
185 | goto err3; | 115 | goto err; |
186 | |||
187 | dma_set_coherent_mask(&dwc3->dev, dev->coherent_dma_mask); | ||
188 | 116 | ||
189 | dwc3->dev.dma_mask = dev->dma_mask; | ||
190 | dwc3->dev.dma_parms = dev->dma_parms; | ||
191 | dwc3->dev.parent = dev; | 117 | dwc3->dev.parent = dev; |
192 | glue->dwc3 = dwc3; | ||
193 | 118 | ||
194 | ret = platform_device_add(dwc3); | 119 | ret = platform_device_add(dwc3); |
195 | if (ret) { | 120 | if (ret) { |
196 | dev_err(dev, "failed to register dwc3 device\n"); | 121 | dev_err(dev, "failed to register dwc3 device\n"); |
197 | goto err3; | 122 | goto err; |
198 | } | 123 | } |
199 | 124 | ||
200 | return 0; | 125 | return 0; |
201 | 126 | err: | |
202 | err3: | ||
203 | platform_device_put(dwc3); | 127 | platform_device_put(dwc3); |
204 | return ret; | 128 | return ret; |
205 | } | 129 | } |
206 | 130 | ||
207 | static void dwc3_pci_remove(struct pci_dev *pci) | 131 | static void dwc3_pci_remove(struct pci_dev *pci) |
208 | { | 132 | { |
209 | struct dwc3_pci *glue = pci_get_drvdata(pci); | 133 | platform_device_unregister(pci_get_drvdata(pci)); |
210 | |||
211 | platform_device_unregister(glue->dwc3); | ||
212 | platform_device_unregister(glue->usb2_phy); | ||
213 | platform_device_unregister(glue->usb3_phy); | ||
214 | } | 134 | } |
215 | 135 | ||
216 | static const struct pci_device_id dwc3_pci_id_table[] = { | 136 | static const struct pci_device_id dwc3_pci_id_table[] = { |
@@ -228,45 +148,11 @@ static const struct pci_device_id dwc3_pci_id_table[] = { | |||
228 | }; | 148 | }; |
229 | MODULE_DEVICE_TABLE(pci, dwc3_pci_id_table); | 149 | MODULE_DEVICE_TABLE(pci, dwc3_pci_id_table); |
230 | 150 | ||
231 | #ifdef CONFIG_PM_SLEEP | ||
232 | static int dwc3_pci_suspend(struct device *dev) | ||
233 | { | ||
234 | struct pci_dev *pci = to_pci_dev(dev); | ||
235 | |||
236 | pci_disable_device(pci); | ||
237 | |||
238 | return 0; | ||
239 | } | ||
240 | |||
241 | static int dwc3_pci_resume(struct device *dev) | ||
242 | { | ||
243 | struct pci_dev *pci = to_pci_dev(dev); | ||
244 | int ret; | ||
245 | |||
246 | ret = pci_enable_device(pci); | ||
247 | if (ret) { | ||
248 | dev_err(dev, "can't re-enable device --> %d\n", ret); | ||
249 | return ret; | ||
250 | } | ||
251 | |||
252 | pci_set_master(pci); | ||
253 | |||
254 | return 0; | ||
255 | } | ||
256 | #endif /* CONFIG_PM_SLEEP */ | ||
257 | |||
258 | static const struct dev_pm_ops dwc3_pci_dev_pm_ops = { | ||
259 | SET_SYSTEM_SLEEP_PM_OPS(dwc3_pci_suspend, dwc3_pci_resume) | ||
260 | }; | ||
261 | |||
262 | static struct pci_driver dwc3_pci_driver = { | 151 | static struct pci_driver dwc3_pci_driver = { |
263 | .name = "dwc3-pci", | 152 | .name = "dwc3-pci", |
264 | .id_table = dwc3_pci_id_table, | 153 | .id_table = dwc3_pci_id_table, |
265 | .probe = dwc3_pci_probe, | 154 | .probe = dwc3_pci_probe, |
266 | .remove = dwc3_pci_remove, | 155 | .remove = dwc3_pci_remove, |
267 | .driver = { | ||
268 | .pm = &dwc3_pci_dev_pm_ops, | ||
269 | }, | ||
270 | }; | 156 | }; |
271 | 157 | ||
272 | MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>"); | 158 | MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>"); |