Root/
Source at commit 4525beeb9aadbb9e1cb3e9e135f4371553f26a70 created 9 years 11 months ago. By Felipe Balbi, usb: phy: rename usb_nop_xceiv to usb_phy_generic | |
---|---|
1 | /** |
2 | * dwc3-pci.c - PCI Specific glue layer |
3 | * |
4 | * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com |
5 | * |
6 | * Authors: Felipe Balbi <balbi@ti.com>, |
7 | * Sebastian Andrzej Siewior <bigeasy@linutronix.de> |
8 | * |
9 | * This program is free software: you can redistribute it and/or modify |
10 | * it under the terms of the GNU General Public License version 2 of |
11 | * the License as published by the Free Software Foundation. |
12 | * |
13 | * This program is distributed in the hope that it will be useful, |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | * GNU General Public License for more details. |
17 | */ |
18 | |
19 | #include <linux/kernel.h> |
20 | #include <linux/module.h> |
21 | #include <linux/slab.h> |
22 | #include <linux/pci.h> |
23 | #include <linux/platform_device.h> |
24 | |
25 | #include <linux/usb/otg.h> |
26 | #include <linux/usb/usb_phy_gen_xceiv.h> |
27 | |
28 | /* FIXME define these in <linux/pci_ids.h> */ |
29 | #define PCI_VENDOR_ID_SYNOPSYS 0x16c3 |
30 | #define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3 0xabcd |
31 | #define PCI_DEVICE_ID_INTEL_BYT 0x0f37 |
32 | #define PCI_DEVICE_ID_INTEL_MRFLD 0x119e |
33 | |
34 | struct dwc3_pci { |
35 | struct device *dev; |
36 | struct platform_device *dwc3; |
37 | struct platform_device *usb2_phy; |
38 | struct platform_device *usb3_phy; |
39 | }; |
40 | |
41 | static int dwc3_pci_register_phys(struct dwc3_pci *glue) |
42 | { |
43 | struct usb_phy_generic_platform_data pdata; |
44 | struct platform_device *pdev; |
45 | int ret; |
46 | |
47 | memset(&pdata, 0x00, sizeof(pdata)); |
48 | |
49 | pdev = platform_device_alloc("usb_phy_generic", 0); |
50 | if (!pdev) |
51 | return -ENOMEM; |
52 | |
53 | glue->usb2_phy = pdev; |
54 | pdata.type = USB_PHY_TYPE_USB2; |
55 | pdata.gpio_reset = -1; |
56 | |
57 | ret = platform_device_add_data(glue->usb2_phy, &pdata, sizeof(pdata)); |
58 | if (ret) |
59 | goto err1; |
60 | |
61 | pdev = platform_device_alloc("usb_phy_generic", 1); |
62 | if (!pdev) { |
63 | ret = -ENOMEM; |
64 | goto err1; |
65 | } |
66 | |
67 | glue->usb3_phy = pdev; |
68 | pdata.type = USB_PHY_TYPE_USB3; |
69 | |
70 | ret = platform_device_add_data(glue->usb3_phy, &pdata, sizeof(pdata)); |
71 | if (ret) |
72 | goto err2; |
73 | |
74 | ret = platform_device_add(glue->usb2_phy); |
75 | if (ret) |
76 | goto err2; |
77 | |
78 | ret = platform_device_add(glue->usb3_phy); |
79 | if (ret) |
80 | goto err3; |
81 | |
82 | return 0; |
83 | |
84 | err3: |
85 | platform_device_del(glue->usb2_phy); |
86 | |
87 | err2: |
88 | platform_device_put(glue->usb3_phy); |
89 | |
90 | err1: |
91 | platform_device_put(glue->usb2_phy); |
92 | |
93 | return ret; |
94 | } |
95 | |
96 | static int dwc3_pci_probe(struct pci_dev *pci, |
97 | const struct pci_device_id *id) |
98 | { |
99 | struct resource res[2]; |
100 | struct platform_device *dwc3; |
101 | struct dwc3_pci *glue; |
102 | int ret = -ENOMEM; |
103 | struct device *dev = &pci->dev; |
104 | |
105 | glue = devm_kzalloc(dev, sizeof(*glue), GFP_KERNEL); |
106 | if (!glue) { |
107 | dev_err(dev, "not enough memory\n"); |
108 | return -ENOMEM; |
109 | } |
110 | |
111 | glue->dev = dev; |
112 | |
113 | ret = pci_enable_device(pci); |
114 | if (ret) { |
115 | dev_err(dev, "failed to enable pci device\n"); |
116 | return -ENODEV; |
117 | } |
118 | |
119 | pci_set_master(pci); |
120 | |
121 | ret = dwc3_pci_register_phys(glue); |
122 | if (ret) { |
123 | dev_err(dev, "couldn't register PHYs\n"); |
124 | return ret; |
125 | } |
126 | |
127 | dwc3 = platform_device_alloc("dwc3", PLATFORM_DEVID_AUTO); |
128 | if (!dwc3) { |
129 | dev_err(dev, "couldn't allocate dwc3 device\n"); |
130 | ret = -ENOMEM; |
131 | goto err1; |
132 | } |
133 | |
134 | memset(res, 0x00, sizeof(struct resource) * ARRAY_SIZE(res)); |
135 | |
136 | res[0].start = pci_resource_start(pci, 0); |
137 | res[0].end = pci_resource_end(pci, 0); |
138 | res[0].name = "dwc_usb3"; |
139 | res[0].flags = IORESOURCE_MEM; |
140 | |
141 | res[1].start = pci->irq; |
142 | res[1].name = "dwc_usb3"; |
143 | res[1].flags = IORESOURCE_IRQ; |
144 | |
145 | ret = platform_device_add_resources(dwc3, res, ARRAY_SIZE(res)); |
146 | if (ret) { |
147 | dev_err(dev, "couldn't add resources to dwc3 device\n"); |
148 | goto err1; |
149 | } |
150 | |
151 | pci_set_drvdata(pci, glue); |
152 | |
153 | dma_set_coherent_mask(&dwc3->dev, dev->coherent_dma_mask); |
154 | |
155 | dwc3->dev.dma_mask = dev->dma_mask; |
156 | dwc3->dev.dma_parms = dev->dma_parms; |
157 | dwc3->dev.parent = dev; |
158 | glue->dwc3 = dwc3; |
159 | |
160 | ret = platform_device_add(dwc3); |
161 | if (ret) { |
162 | dev_err(dev, "failed to register dwc3 device\n"); |
163 | goto err3; |
164 | } |
165 | |
166 | return 0; |
167 | |
168 | err3: |
169 | platform_device_put(dwc3); |
170 | err1: |
171 | pci_disable_device(pci); |
172 | |
173 | return ret; |
174 | } |
175 | |
176 | static void dwc3_pci_remove(struct pci_dev *pci) |
177 | { |
178 | struct dwc3_pci *glue = pci_get_drvdata(pci); |
179 | |
180 | platform_device_unregister(glue->dwc3); |
181 | platform_device_unregister(glue->usb2_phy); |
182 | platform_device_unregister(glue->usb3_phy); |
183 | pci_disable_device(pci); |
184 | } |
185 | |
186 | static const struct pci_device_id dwc3_pci_id_table[] = { |
187 | { |
188 | PCI_DEVICE(PCI_VENDOR_ID_SYNOPSYS, |
189 | PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3), |
190 | }, |
191 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BYT), }, |
192 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MRFLD), }, |
193 | { } /* Terminating Entry */ |
194 | }; |
195 | MODULE_DEVICE_TABLE(pci, dwc3_pci_id_table); |
196 | |
197 | #ifdef CONFIG_PM_SLEEP |
198 | static int dwc3_pci_suspend(struct device *dev) |
199 | { |
200 | struct pci_dev *pci = to_pci_dev(dev); |
201 | |
202 | pci_disable_device(pci); |
203 | |
204 | return 0; |
205 | } |
206 | |
207 | static int dwc3_pci_resume(struct device *dev) |
208 | { |
209 | struct pci_dev *pci = to_pci_dev(dev); |
210 | int ret; |
211 | |
212 | ret = pci_enable_device(pci); |
213 | if (ret) { |
214 | dev_err(dev, "can't re-enable device --> %d\n", ret); |
215 | return ret; |
216 | } |
217 | |
218 | pci_set_master(pci); |
219 | |
220 | return 0; |
221 | } |
222 | #endif /* CONFIG_PM_SLEEP */ |
223 | |
224 | static const struct dev_pm_ops dwc3_pci_dev_pm_ops = { |
225 | SET_SYSTEM_SLEEP_PM_OPS(dwc3_pci_suspend, dwc3_pci_resume) |
226 | }; |
227 | |
228 | static struct pci_driver dwc3_pci_driver = { |
229 | .name = "dwc3-pci", |
230 | .id_table = dwc3_pci_id_table, |
231 | .probe = dwc3_pci_probe, |
232 | .remove = dwc3_pci_remove, |
233 | .driver = { |
234 | .pm = &dwc3_pci_dev_pm_ops, |
235 | }, |
236 | }; |
237 | |
238 | MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>"); |
239 | MODULE_LICENSE("GPL v2"); |
240 | MODULE_DESCRIPTION("DesignWare USB3 PCI Glue Layer"); |
241 | |
242 | module_pci_driver(dwc3_pci_driver); |
243 |
Branches:
ben-wpan
ben-wpan-stefan
javiroman/ks7010
jz-2.6.34
jz-2.6.34-rc5
jz-2.6.34-rc6
jz-2.6.34-rc7
jz-2.6.35
jz-2.6.36
jz-2.6.37
jz-2.6.38
jz-2.6.39
jz-3.0
jz-3.1
jz-3.11
jz-3.12
jz-3.13
jz-3.15
jz-3.16
jz-3.18-dt
jz-3.2
jz-3.3
jz-3.4
jz-3.5
jz-3.6
jz-3.6-rc2-pwm
jz-3.9
jz-3.9-clk
jz-3.9-rc8
jz47xx
jz47xx-2.6.38
master
Tags:
od-2011-09-04
od-2011-09-18
v2.6.34-rc5
v2.6.34-rc6
v2.6.34-rc7
v3.9