0001
0002
0003
0004
0005
0006 #include <linux/kernel.h>
0007 #include <linux/module.h>
0008 #include <linux/pci.h>
0009 #include <linux/usb.h>
0010 #include <linux/usb/hcd.h>
0011
0012 #include <asm/io.h>
0013 #include <asm/irq.h>
0014
0015 #ifdef CONFIG_PPC_PMAC
0016 #include <asm/machdep.h>
0017 #include <asm/pmac_feature.h>
0018 #endif
0019
0020 #include "usb.h"
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030 static DECLARE_RWSEM(companions_rwsem);
0031
0032 #define CL_UHCI PCI_CLASS_SERIAL_USB_UHCI
0033 #define CL_OHCI PCI_CLASS_SERIAL_USB_OHCI
0034 #define CL_EHCI PCI_CLASS_SERIAL_USB_EHCI
0035
0036 static inline int is_ohci_or_uhci(struct pci_dev *pdev)
0037 {
0038 return pdev->class == CL_OHCI || pdev->class == CL_UHCI;
0039 }
0040
0041 typedef void (*companion_fn)(struct pci_dev *pdev, struct usb_hcd *hcd,
0042 struct pci_dev *companion, struct usb_hcd *companion_hcd);
0043
0044
0045 static void for_each_companion(struct pci_dev *pdev, struct usb_hcd *hcd,
0046 companion_fn fn)
0047 {
0048 struct pci_dev *companion;
0049 struct usb_hcd *companion_hcd;
0050 unsigned int slot = PCI_SLOT(pdev->devfn);
0051
0052
0053
0054
0055
0056
0057 companion = NULL;
0058 for_each_pci_dev(companion) {
0059 if (companion->bus != pdev->bus ||
0060 PCI_SLOT(companion->devfn) != slot)
0061 continue;
0062
0063
0064
0065
0066
0067 if (companion->class != CL_UHCI && companion->class != CL_OHCI &&
0068 companion->class != CL_EHCI)
0069 continue;
0070
0071 companion_hcd = pci_get_drvdata(companion);
0072 if (!companion_hcd || !companion_hcd->self.root_hub)
0073 continue;
0074 fn(pdev, hcd, companion, companion_hcd);
0075 }
0076 }
0077
0078
0079
0080
0081
0082
0083
0084 static void ehci_pre_add(struct pci_dev *pdev, struct usb_hcd *hcd,
0085 struct pci_dev *companion, struct usb_hcd *companion_hcd)
0086 {
0087 struct usb_device *udev;
0088
0089 if (is_ohci_or_uhci(companion)) {
0090 udev = companion_hcd->self.root_hub;
0091 usb_lock_device(udev);
0092 usb_set_configuration(udev, 0);
0093 }
0094 }
0095
0096
0097
0098
0099
0100
0101 static void ehci_post_add(struct pci_dev *pdev, struct usb_hcd *hcd,
0102 struct pci_dev *companion, struct usb_hcd *companion_hcd)
0103 {
0104 struct usb_device *udev;
0105
0106 if (is_ohci_or_uhci(companion)) {
0107 if (dev_get_drvdata(&pdev->dev)) {
0108 dev_dbg(&pdev->dev, "HS companion for %s\n",
0109 dev_name(&companion->dev));
0110 companion_hcd->self.hs_companion = &hcd->self;
0111 }
0112 udev = companion_hcd->self.root_hub;
0113 usb_set_configuration(udev, 1);
0114 usb_unlock_device(udev);
0115 }
0116 }
0117
0118
0119
0120
0121
0122 static void non_ehci_add(struct pci_dev *pdev, struct usb_hcd *hcd,
0123 struct pci_dev *companion, struct usb_hcd *companion_hcd)
0124 {
0125 if (is_ohci_or_uhci(pdev) && companion->class == CL_EHCI) {
0126 dev_dbg(&pdev->dev, "FS/LS companion for %s\n",
0127 dev_name(&companion->dev));
0128 hcd->self.hs_companion = &companion_hcd->self;
0129 }
0130 }
0131
0132
0133 static void ehci_remove(struct pci_dev *pdev, struct usb_hcd *hcd,
0134 struct pci_dev *companion, struct usb_hcd *companion_hcd)
0135 {
0136 if (is_ohci_or_uhci(companion))
0137 companion_hcd->self.hs_companion = NULL;
0138 }
0139
0140 #ifdef CONFIG_PM
0141
0142
0143 static void ehci_wait_for_companions(struct pci_dev *pdev, struct usb_hcd *hcd,
0144 struct pci_dev *companion, struct usb_hcd *companion_hcd)
0145 {
0146 if (is_ohci_or_uhci(companion))
0147 device_pm_wait_for_dev(&pdev->dev, &companion->dev);
0148 }
0149
0150 #endif
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173 int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id,
0174 const struct hc_driver *driver)
0175 {
0176 struct usb_hcd *hcd;
0177 int retval;
0178 int hcd_irq = 0;
0179
0180 if (usb_disabled())
0181 return -ENODEV;
0182
0183 if (!id)
0184 return -EINVAL;
0185
0186 if (!driver)
0187 return -EINVAL;
0188
0189 if (pci_enable_device(dev) < 0)
0190 return -ENODEV;
0191
0192
0193
0194
0195
0196 if ((driver->flags & HCD_MASK) < HCD_USB3) {
0197 retval = pci_alloc_irq_vectors(dev, 1, 1, PCI_IRQ_LEGACY | PCI_IRQ_MSI);
0198 if (retval < 0) {
0199 dev_err(&dev->dev,
0200 "Found HC with no IRQ. Check BIOS/PCI %s setup!\n",
0201 pci_name(dev));
0202 retval = -ENODEV;
0203 goto disable_pci;
0204 }
0205 hcd_irq = pci_irq_vector(dev, 0);
0206 }
0207
0208 hcd = usb_create_hcd(driver, &dev->dev, pci_name(dev));
0209 if (!hcd) {
0210 retval = -ENOMEM;
0211 goto free_irq_vectors;
0212 }
0213
0214 hcd->amd_resume_bug = (usb_hcd_amd_remote_wakeup_quirk(dev) &&
0215 driver->flags & (HCD_USB11 | HCD_USB3)) ? 1 : 0;
0216
0217 if (driver->flags & HCD_MEMORY) {
0218
0219 hcd->rsrc_start = pci_resource_start(dev, 0);
0220 hcd->rsrc_len = pci_resource_len(dev, 0);
0221 if (!devm_request_mem_region(&dev->dev, hcd->rsrc_start,
0222 hcd->rsrc_len, driver->description)) {
0223 dev_dbg(&dev->dev, "controller already in use\n");
0224 retval = -EBUSY;
0225 goto put_hcd;
0226 }
0227 hcd->regs = devm_ioremap(&dev->dev, hcd->rsrc_start,
0228 hcd->rsrc_len);
0229 if (hcd->regs == NULL) {
0230 dev_dbg(&dev->dev, "error mapping memory\n");
0231 retval = -EFAULT;
0232 goto put_hcd;
0233 }
0234
0235 } else {
0236
0237 int region;
0238
0239 for (region = 0; region < PCI_STD_NUM_BARS; region++) {
0240 if (!(pci_resource_flags(dev, region) &
0241 IORESOURCE_IO))
0242 continue;
0243
0244 hcd->rsrc_start = pci_resource_start(dev, region);
0245 hcd->rsrc_len = pci_resource_len(dev, region);
0246 if (devm_request_region(&dev->dev, hcd->rsrc_start,
0247 hcd->rsrc_len, driver->description))
0248 break;
0249 }
0250 if (region == PCI_STD_NUM_BARS) {
0251 dev_dbg(&dev->dev, "no i/o regions available\n");
0252 retval = -EBUSY;
0253 goto put_hcd;
0254 }
0255 }
0256
0257 pci_set_master(dev);
0258
0259
0260 if (dev->class == CL_EHCI) {
0261 down_write(&companions_rwsem);
0262 dev_set_drvdata(&dev->dev, hcd);
0263 for_each_companion(dev, hcd, ehci_pre_add);
0264 retval = usb_add_hcd(hcd, hcd_irq, IRQF_SHARED);
0265 if (retval != 0)
0266 dev_set_drvdata(&dev->dev, NULL);
0267 for_each_companion(dev, hcd, ehci_post_add);
0268 up_write(&companions_rwsem);
0269 } else {
0270 down_read(&companions_rwsem);
0271 dev_set_drvdata(&dev->dev, hcd);
0272 retval = usb_add_hcd(hcd, hcd_irq, IRQF_SHARED);
0273 if (retval != 0)
0274 dev_set_drvdata(&dev->dev, NULL);
0275 else
0276 for_each_companion(dev, hcd, non_ehci_add);
0277 up_read(&companions_rwsem);
0278 }
0279
0280 if (retval != 0)
0281 goto put_hcd;
0282 device_wakeup_enable(hcd->self.controller);
0283
0284 if (pci_dev_run_wake(dev))
0285 pm_runtime_put_noidle(&dev->dev);
0286 return retval;
0287
0288 put_hcd:
0289 usb_put_hcd(hcd);
0290 free_irq_vectors:
0291 if ((driver->flags & HCD_MASK) < HCD_USB3)
0292 pci_free_irq_vectors(dev);
0293 disable_pci:
0294 pci_disable_device(dev);
0295 dev_err(&dev->dev, "init %s fail, %d\n", pci_name(dev), retval);
0296 return retval;
0297 }
0298 EXPORT_SYMBOL_GPL(usb_hcd_pci_probe);
0299
0300
0301
0302
0303
0304
0305
0306
0307
0308
0309
0310
0311
0312
0313
0314
0315
0316 void usb_hcd_pci_remove(struct pci_dev *dev)
0317 {
0318 struct usb_hcd *hcd;
0319 int hcd_driver_flags;
0320
0321 hcd = pci_get_drvdata(dev);
0322 if (!hcd)
0323 return;
0324
0325 hcd_driver_flags = hcd->driver->flags;
0326
0327 if (pci_dev_run_wake(dev))
0328 pm_runtime_get_noresume(&dev->dev);
0329
0330
0331
0332
0333
0334 local_irq_disable();
0335 usb_hcd_irq(0, hcd);
0336 local_irq_enable();
0337
0338
0339 if (dev->class == CL_EHCI) {
0340 down_write(&companions_rwsem);
0341 for_each_companion(dev, hcd, ehci_remove);
0342 usb_remove_hcd(hcd);
0343 dev_set_drvdata(&dev->dev, NULL);
0344 up_write(&companions_rwsem);
0345 } else {
0346
0347 down_read(&companions_rwsem);
0348 hcd->self.hs_companion = NULL;
0349 usb_remove_hcd(hcd);
0350 dev_set_drvdata(&dev->dev, NULL);
0351 up_read(&companions_rwsem);
0352 }
0353 usb_put_hcd(hcd);
0354 if ((hcd_driver_flags & HCD_MASK) < HCD_USB3)
0355 pci_free_irq_vectors(dev);
0356 pci_disable_device(dev);
0357 }
0358 EXPORT_SYMBOL_GPL(usb_hcd_pci_remove);
0359
0360
0361
0362
0363
0364 void usb_hcd_pci_shutdown(struct pci_dev *dev)
0365 {
0366 struct usb_hcd *hcd;
0367
0368 hcd = pci_get_drvdata(dev);
0369 if (!hcd)
0370 return;
0371
0372 if (test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags) &&
0373 hcd->driver->shutdown) {
0374 hcd->driver->shutdown(hcd);
0375 if (usb_hcd_is_primary_hcd(hcd) && hcd->irq > 0)
0376 free_irq(hcd->irq, hcd);
0377 pci_disable_device(dev);
0378 }
0379 }
0380 EXPORT_SYMBOL_GPL(usb_hcd_pci_shutdown);
0381
0382 #ifdef CONFIG_PM
0383
0384 #ifdef CONFIG_PPC_PMAC
0385 static void powermac_set_asic(struct pci_dev *pci_dev, int enable)
0386 {
0387
0388 if (machine_is(powermac)) {
0389 struct device_node *of_node;
0390
0391 of_node = pci_device_to_OF_node(pci_dev);
0392 if (of_node)
0393 pmac_call_feature(PMAC_FTR_USB_ENABLE,
0394 of_node, 0, enable);
0395 }
0396 }
0397
0398 #else
0399
0400 static inline void powermac_set_asic(struct pci_dev *pci_dev, int enable)
0401 {}
0402
0403 #endif
0404
0405 static int check_root_hub_suspended(struct device *dev)
0406 {
0407 struct usb_hcd *hcd = dev_get_drvdata(dev);
0408
0409 if (HCD_RH_RUNNING(hcd)) {
0410 dev_warn(dev, "Root hub is not suspended\n");
0411 return -EBUSY;
0412 }
0413 if (hcd->shared_hcd) {
0414 hcd = hcd->shared_hcd;
0415 if (HCD_RH_RUNNING(hcd)) {
0416 dev_warn(dev, "Secondary root hub is not suspended\n");
0417 return -EBUSY;
0418 }
0419 }
0420 return 0;
0421 }
0422
0423 static int suspend_common(struct device *dev, bool do_wakeup)
0424 {
0425 struct pci_dev *pci_dev = to_pci_dev(dev);
0426 struct usb_hcd *hcd = pci_get_drvdata(pci_dev);
0427 int retval;
0428
0429
0430
0431
0432
0433
0434 retval = check_root_hub_suspended(dev);
0435 if (retval)
0436 return retval;
0437
0438 if (hcd->driver->pci_suspend && !HCD_DEAD(hcd)) {
0439
0440
0441
0442 if (do_wakeup && HCD_WAKEUP_PENDING(hcd))
0443 return -EBUSY;
0444 if (do_wakeup && hcd->shared_hcd &&
0445 HCD_WAKEUP_PENDING(hcd->shared_hcd))
0446 return -EBUSY;
0447 retval = hcd->driver->pci_suspend(hcd, do_wakeup);
0448 suspend_report_result(dev, hcd->driver->pci_suspend, retval);
0449
0450
0451 if ((retval == 0 && do_wakeup && HCD_WAKEUP_PENDING(hcd)) ||
0452 (retval == 0 && do_wakeup && hcd->shared_hcd &&
0453 HCD_WAKEUP_PENDING(hcd->shared_hcd))) {
0454 if (hcd->driver->pci_resume)
0455 hcd->driver->pci_resume(hcd, false);
0456 retval = -EBUSY;
0457 }
0458 if (retval)
0459 return retval;
0460 }
0461
0462
0463
0464
0465
0466 if (!hcd->msix_enabled)
0467 synchronize_irq(pci_irq_vector(pci_dev, 0));
0468
0469
0470
0471
0472
0473
0474 pci_disable_device(pci_dev);
0475 return retval;
0476 }
0477
0478 static int resume_common(struct device *dev, int event)
0479 {
0480 struct pci_dev *pci_dev = to_pci_dev(dev);
0481 struct usb_hcd *hcd = pci_get_drvdata(pci_dev);
0482 int retval;
0483
0484 if (HCD_RH_RUNNING(hcd) ||
0485 (hcd->shared_hcd &&
0486 HCD_RH_RUNNING(hcd->shared_hcd))) {
0487 dev_dbg(dev, "can't resume, not suspended!\n");
0488 return 0;
0489 }
0490
0491 retval = pci_enable_device(pci_dev);
0492 if (retval < 0) {
0493 dev_err(dev, "can't re-enable after resume, %d!\n", retval);
0494 return retval;
0495 }
0496
0497 pci_set_master(pci_dev);
0498
0499 if (hcd->driver->pci_resume && !HCD_DEAD(hcd)) {
0500
0501
0502
0503
0504
0505
0506 if (pci_dev->class == CL_EHCI && event != PM_EVENT_AUTO_RESUME)
0507 for_each_companion(pci_dev, hcd,
0508 ehci_wait_for_companions);
0509
0510 retval = hcd->driver->pci_resume(hcd,
0511 event == PM_EVENT_RESTORE);
0512 if (retval) {
0513 dev_err(dev, "PCI post-resume error %d!\n", retval);
0514 usb_hc_died(hcd);
0515 }
0516 }
0517 return retval;
0518 }
0519
0520 #ifdef CONFIG_PM_SLEEP
0521
0522 static int hcd_pci_suspend(struct device *dev)
0523 {
0524 return suspend_common(dev, device_may_wakeup(dev));
0525 }
0526
0527 static int hcd_pci_suspend_noirq(struct device *dev)
0528 {
0529 struct pci_dev *pci_dev = to_pci_dev(dev);
0530 struct usb_hcd *hcd = pci_get_drvdata(pci_dev);
0531 int retval;
0532
0533 retval = check_root_hub_suspended(dev);
0534 if (retval)
0535 return retval;
0536
0537 pci_save_state(pci_dev);
0538
0539
0540
0541
0542
0543 if (HCD_DEAD(hcd))
0544 device_set_wakeup_enable(dev, 0);
0545 dev_dbg(dev, "wakeup: %d\n", device_may_wakeup(dev));
0546
0547
0548
0549
0550 retval = pci_prepare_to_sleep(pci_dev);
0551 if (retval == -EIO) {
0552 dev_dbg(dev, "--> PCI D0 legacy\n");
0553 retval = 0;
0554 } else if (retval == 0) {
0555 dev_dbg(dev, "--> PCI %s\n",
0556 pci_power_name(pci_dev->current_state));
0557 } else {
0558 suspend_report_result(dev, pci_prepare_to_sleep, retval);
0559 return retval;
0560 }
0561
0562 powermac_set_asic(pci_dev, 0);
0563 return retval;
0564 }
0565
0566 static int hcd_pci_resume_noirq(struct device *dev)
0567 {
0568 powermac_set_asic(to_pci_dev(dev), 1);
0569 return 0;
0570 }
0571
0572 static int hcd_pci_resume(struct device *dev)
0573 {
0574 return resume_common(dev, PM_EVENT_RESUME);
0575 }
0576
0577 static int hcd_pci_restore(struct device *dev)
0578 {
0579 return resume_common(dev, PM_EVENT_RESTORE);
0580 }
0581
0582 #else
0583
0584 #define hcd_pci_suspend NULL
0585 #define hcd_pci_suspend_noirq NULL
0586 #define hcd_pci_resume_noirq NULL
0587 #define hcd_pci_resume NULL
0588 #define hcd_pci_restore NULL
0589
0590 #endif
0591
0592 static int hcd_pci_runtime_suspend(struct device *dev)
0593 {
0594 int retval;
0595
0596 retval = suspend_common(dev, true);
0597 if (retval == 0)
0598 powermac_set_asic(to_pci_dev(dev), 0);
0599 dev_dbg(dev, "hcd_pci_runtime_suspend: %d\n", retval);
0600 return retval;
0601 }
0602
0603 static int hcd_pci_runtime_resume(struct device *dev)
0604 {
0605 int retval;
0606
0607 powermac_set_asic(to_pci_dev(dev), 1);
0608 retval = resume_common(dev, PM_EVENT_AUTO_RESUME);
0609 dev_dbg(dev, "hcd_pci_runtime_resume: %d\n", retval);
0610 return retval;
0611 }
0612
0613 const struct dev_pm_ops usb_hcd_pci_pm_ops = {
0614 .suspend = hcd_pci_suspend,
0615 .suspend_noirq = hcd_pci_suspend_noirq,
0616 .resume_noirq = hcd_pci_resume_noirq,
0617 .resume = hcd_pci_resume,
0618 .freeze = hcd_pci_suspend,
0619 .freeze_noirq = check_root_hub_suspended,
0620 .thaw_noirq = NULL,
0621 .thaw = hcd_pci_resume,
0622 .poweroff = hcd_pci_suspend,
0623 .poweroff_noirq = hcd_pci_suspend_noirq,
0624 .restore_noirq = hcd_pci_resume_noirq,
0625 .restore = hcd_pci_restore,
0626 .runtime_suspend = hcd_pci_runtime_suspend,
0627 .runtime_resume = hcd_pci_runtime_resume,
0628 };
0629 EXPORT_SYMBOL_GPL(usb_hcd_pci_pm_ops);
0630
0631 #endif