1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19#include <linux/kernel.h>
20#include <linux/module.h>
21#include <linux/pci.h>
22#include <linux/usb.h>
23
24#include <asm/io.h>
25#include <asm/irq.h>
26
27#ifdef CONFIG_PPC_PMAC
28#include <asm/machdep.h>
29#include <asm/pmac_feature.h>
30#include <asm/pci-bridge.h>
31#include <asm/prom.h>
32#endif
33
34#include "usb.h"
35#include "hcd.h"
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
59{
60 struct hc_driver *driver;
61 struct usb_hcd *hcd;
62 int retval;
63
64 if (usb_disabled())
65 return -ENODEV;
66
67 if (!id)
68 return -EINVAL;
69 driver = (struct hc_driver *)id->driver_data;
70 if (!driver)
71 return -EINVAL;
72
73 if (pci_enable_device(dev) < 0)
74 return -ENODEV;
75 dev->current_state = PCI_D0;
76
77 if (!dev->irq) {
78 dev_err(&dev->dev,
79 "Found HC with no IRQ. Check BIOS/PCI %s setup!\n",
80 pci_name(dev));
81 retval = -ENODEV;
82 goto err1;
83 }
84
85 hcd = usb_create_hcd(driver, &dev->dev, pci_name(dev));
86 if (!hcd) {
87 retval = -ENOMEM;
88 goto err1;
89 }
90
91 if (driver->flags & HCD_MEMORY) {
92
93 hcd->rsrc_start = pci_resource_start(dev, 0);
94 hcd->rsrc_len = pci_resource_len(dev, 0);
95 if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,
96 driver->description)) {
97 dev_dbg(&dev->dev, "controller already in use\n");
98 retval = -EBUSY;
99 goto err2;
100 }
101 hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len);
102 if (hcd->regs == NULL) {
103 dev_dbg(&dev->dev, "error mapping memory\n");
104 retval = -EFAULT;
105 goto err3;
106 }
107
108 } else {
109
110 int region;
111
112 for (region = 0; region < PCI_ROM_RESOURCE; region++) {
113 if (!(pci_resource_flags(dev, region) &
114 IORESOURCE_IO))
115 continue;
116
117 hcd->rsrc_start = pci_resource_start(dev, region);
118 hcd->rsrc_len = pci_resource_len(dev, region);
119 if (request_region(hcd->rsrc_start, hcd->rsrc_len,
120 driver->description))
121 break;
122 }
123 if (region == PCI_ROM_RESOURCE) {
124 dev_dbg(&dev->dev, "no i/o regions available\n");
125 retval = -EBUSY;
126 goto err1;
127 }
128 }
129
130 pci_set_master(dev);
131
132 retval = usb_add_hcd(hcd, dev->irq, IRQF_DISABLED | IRQF_SHARED);
133 if (retval != 0)
134 goto err4;
135 return retval;
136
137 err4:
138 if (driver->flags & HCD_MEMORY) {
139 iounmap(hcd->regs);
140 err3:
141 release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
142 } else
143 release_region(hcd->rsrc_start, hcd->rsrc_len);
144 err2:
145 usb_put_hcd(hcd);
146 err1:
147 pci_disable_device(dev);
148 dev_err(&dev->dev, "init %s fail, %d\n", pci_name(dev), retval);
149 return retval;
150}
151EXPORT_SYMBOL_GPL(usb_hcd_pci_probe);
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168void usb_hcd_pci_remove(struct pci_dev *dev)
169{
170 struct usb_hcd *hcd;
171
172 hcd = pci_get_drvdata(dev);
173 if (!hcd)
174 return;
175
176 usb_remove_hcd(hcd);
177 if (hcd->driver->flags & HCD_MEMORY) {
178 iounmap(hcd->regs);
179 release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
180 } else {
181 release_region(hcd->rsrc_start, hcd->rsrc_len);
182 }
183 usb_put_hcd(hcd);
184 pci_disable_device(dev);
185}
186EXPORT_SYMBOL_GPL(usb_hcd_pci_remove);
187
188
189
190
191
192void usb_hcd_pci_shutdown(struct pci_dev *dev)
193{
194 struct usb_hcd *hcd;
195
196 hcd = pci_get_drvdata(dev);
197 if (!hcd)
198 return;
199
200 if (hcd->driver->shutdown)
201 hcd->driver->shutdown(hcd);
202}
203EXPORT_SYMBOL_GPL(usb_hcd_pci_shutdown);
204
205#ifdef CONFIG_PM_SLEEP
206
207static int check_root_hub_suspended(struct device *dev)
208{
209 struct pci_dev *pci_dev = to_pci_dev(dev);
210 struct usb_hcd *hcd = pci_get_drvdata(pci_dev);
211
212 if (!(hcd->state == HC_STATE_SUSPENDED ||
213 hcd->state == HC_STATE_HALT)) {
214 dev_warn(dev, "Root hub is not suspended\n");
215 return -EBUSY;
216 }
217 return 0;
218}
219
220static int hcd_pci_suspend(struct device *dev)
221{
222 struct pci_dev *pci_dev = to_pci_dev(dev);
223 struct usb_hcd *hcd = pci_get_drvdata(pci_dev);
224 int retval;
225
226
227
228
229
230
231 retval = check_root_hub_suspended(dev);
232 if (retval)
233 return retval;
234
235
236 if (pci_dev->current_state != PCI_D0)
237 return retval;
238
239 if (hcd->driver->pci_suspend) {
240 retval = hcd->driver->pci_suspend(hcd);
241 suspend_report_result(hcd->driver->pci_suspend, retval);
242 if (retval)
243 return retval;
244 }
245
246 synchronize_irq(pci_dev->irq);
247
248
249
250
251
252
253 pci_disable_device(pci_dev);
254 return retval;
255}
256
257static int hcd_pci_suspend_noirq(struct device *dev)
258{
259 struct pci_dev *pci_dev = to_pci_dev(dev);
260 struct usb_hcd *hcd = pci_get_drvdata(pci_dev);
261 int retval;
262
263 retval = check_root_hub_suspended(dev);
264 if (retval)
265 return retval;
266
267 pci_save_state(pci_dev);
268
269
270
271
272 if (hcd->state == HC_STATE_HALT)
273 device_set_wakeup_enable(dev, 0);
274 dev_dbg(dev, "wakeup: %d\n", device_may_wakeup(dev));
275
276
277
278
279 retval = pci_prepare_to_sleep(pci_dev);
280 if (retval == -EIO) {
281 dev_dbg(dev, "--> PCI D0 legacy\n");
282 retval = 0;
283 } else if (retval == 0) {
284 dev_dbg(dev, "--> PCI %s\n",
285 pci_power_name(pci_dev->current_state));
286 } else {
287 suspend_report_result(pci_prepare_to_sleep, retval);
288 return retval;
289 }
290
291#ifdef CONFIG_PPC_PMAC
292
293 if (machine_is(powermac)) {
294 struct device_node *of_node;
295
296 of_node = pci_device_to_OF_node(pci_dev);
297 if (of_node)
298 pmac_call_feature(PMAC_FTR_USB_ENABLE, of_node, 0, 0);
299 }
300#endif
301 return retval;
302}
303
304static int hcd_pci_resume_noirq(struct device *dev)
305{
306 struct pci_dev *pci_dev = to_pci_dev(dev);
307
308#ifdef CONFIG_PPC_PMAC
309
310 if (machine_is(powermac)) {
311 struct device_node *of_node;
312
313 of_node = pci_device_to_OF_node(pci_dev);
314 if (of_node)
315 pmac_call_feature(PMAC_FTR_USB_ENABLE,
316 of_node, 0, 1);
317 }
318#endif
319
320
321 pci_back_from_sleep(pci_dev);
322 return 0;
323}
324
325static int resume_common(struct device *dev, bool hibernated)
326{
327 struct pci_dev *pci_dev = to_pci_dev(dev);
328 struct usb_hcd *hcd = pci_get_drvdata(pci_dev);
329 int retval;
330
331 if (hcd->state != HC_STATE_SUSPENDED) {
332 dev_dbg(dev, "can't resume, not suspended!\n");
333 return 0;
334 }
335
336 retval = pci_enable_device(pci_dev);
337 if (retval < 0) {
338 dev_err(dev, "can't re-enable after resume, %d!\n", retval);
339 return retval;
340 }
341
342 pci_set_master(pci_dev);
343
344 clear_bit(HCD_FLAG_SAW_IRQ, &hcd->flags);
345
346 if (hcd->driver->pci_resume) {
347 retval = hcd->driver->pci_resume(hcd, hibernated);
348 if (retval) {
349 dev_err(dev, "PCI post-resume error %d!\n", retval);
350 usb_hc_died(hcd);
351 }
352 }
353 return retval;
354}
355
356static int hcd_pci_resume(struct device *dev)
357{
358 return resume_common(dev, false);
359}
360
361static int hcd_pci_restore(struct device *dev)
362{
363 return resume_common(dev, true);
364}
365
366struct dev_pm_ops usb_hcd_pci_pm_ops = {
367 .suspend = hcd_pci_suspend,
368 .suspend_noirq = hcd_pci_suspend_noirq,
369 .resume_noirq = hcd_pci_resume_noirq,
370 .resume = hcd_pci_resume,
371 .freeze = check_root_hub_suspended,
372 .freeze_noirq = check_root_hub_suspended,
373 .thaw_noirq = NULL,
374 .thaw = NULL,
375 .poweroff = hcd_pci_suspend,
376 .poweroff_noirq = hcd_pci_suspend_noirq,
377 .restore_noirq = hcd_pci_resume_noirq,
378 .restore = hcd_pci_restore,
379};
380EXPORT_SYMBOL_GPL(usb_hcd_pci_pm_ops);
381
382#endif
383