| .. | .. |
|---|
| 159 | 159 | * usb_hcd_pci_probe - initialize PCI-based HCDs |
|---|
| 160 | 160 | * @dev: USB Host Controller being probed |
|---|
| 161 | 161 | * @id: pci hotplug id connecting controller to HCD framework |
|---|
| 162 | + * @driver: USB HC driver handle |
|---|
| 162 | 163 | * Context: !in_interrupt() |
|---|
| 163 | 164 | * |
|---|
| 164 | 165 | * Allocates basic PCI resources for this USB host controller, and |
|---|
| .. | .. |
|---|
| 169 | 170 | * |
|---|
| 170 | 171 | * Return: 0 if successful. |
|---|
| 171 | 172 | */ |
|---|
| 172 | | -int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) |
|---|
| 173 | +int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id, |
|---|
| 174 | + const struct hc_driver *driver) |
|---|
| 173 | 175 | { |
|---|
| 174 | | - struct hc_driver *driver; |
|---|
| 175 | 176 | struct usb_hcd *hcd; |
|---|
| 176 | 177 | int retval; |
|---|
| 177 | 178 | int hcd_irq = 0; |
|---|
| .. | .. |
|---|
| 181 | 182 | |
|---|
| 182 | 183 | if (!id) |
|---|
| 183 | 184 | return -EINVAL; |
|---|
| 184 | | - driver = (struct hc_driver *)id->driver_data; |
|---|
| 185 | + |
|---|
| 185 | 186 | if (!driver) |
|---|
| 186 | 187 | return -EINVAL; |
|---|
| 187 | 188 | |
|---|
| .. | .. |
|---|
| 193 | 194 | * make sure irq setup is not touched for xhci in generic hcd code |
|---|
| 194 | 195 | */ |
|---|
| 195 | 196 | if ((driver->flags & HCD_MASK) < HCD_USB3) { |
|---|
| 196 | | - if (!dev->irq) { |
|---|
| 197 | + retval = pci_alloc_irq_vectors(dev, 1, 1, PCI_IRQ_LEGACY | PCI_IRQ_MSI); |
|---|
| 198 | + if (retval < 0) { |
|---|
| 197 | 199 | dev_err(&dev->dev, |
|---|
| 198 | 200 | "Found HC with no IRQ. Check BIOS/PCI %s setup!\n", |
|---|
| 199 | 201 | pci_name(dev)); |
|---|
| 200 | 202 | retval = -ENODEV; |
|---|
| 201 | 203 | goto disable_pci; |
|---|
| 202 | 204 | } |
|---|
| 203 | | - hcd_irq = dev->irq; |
|---|
| 205 | + hcd_irq = pci_irq_vector(dev, 0); |
|---|
| 204 | 206 | } |
|---|
| 205 | 207 | |
|---|
| 206 | 208 | hcd = usb_create_hcd(driver, &dev->dev, pci_name(dev)); |
|---|
| 207 | 209 | if (!hcd) { |
|---|
| 208 | 210 | retval = -ENOMEM; |
|---|
| 209 | | - goto disable_pci; |
|---|
| 211 | + goto free_irq_vectors; |
|---|
| 210 | 212 | } |
|---|
| 211 | 213 | |
|---|
| 212 | 214 | hcd->amd_resume_bug = (usb_hcd_amd_remote_wakeup_quirk(dev) && |
|---|
| .. | .. |
|---|
| 222 | 224 | retval = -EBUSY; |
|---|
| 223 | 225 | goto put_hcd; |
|---|
| 224 | 226 | } |
|---|
| 225 | | - hcd->regs = devm_ioremap_nocache(&dev->dev, hcd->rsrc_start, |
|---|
| 227 | + hcd->regs = devm_ioremap(&dev->dev, hcd->rsrc_start, |
|---|
| 226 | 228 | hcd->rsrc_len); |
|---|
| 227 | 229 | if (hcd->regs == NULL) { |
|---|
| 228 | 230 | dev_dbg(&dev->dev, "error mapping memory\n"); |
|---|
| .. | .. |
|---|
| 234 | 236 | /* UHCI */ |
|---|
| 235 | 237 | int region; |
|---|
| 236 | 238 | |
|---|
| 237 | | - for (region = 0; region < PCI_ROM_RESOURCE; region++) { |
|---|
| 239 | + for (region = 0; region < PCI_STD_NUM_BARS; region++) { |
|---|
| 238 | 240 | if (!(pci_resource_flags(dev, region) & |
|---|
| 239 | 241 | IORESOURCE_IO)) |
|---|
| 240 | 242 | continue; |
|---|
| .. | .. |
|---|
| 285 | 287 | |
|---|
| 286 | 288 | put_hcd: |
|---|
| 287 | 289 | usb_put_hcd(hcd); |
|---|
| 290 | +free_irq_vectors: |
|---|
| 291 | + if ((driver->flags & HCD_MASK) < HCD_USB3) |
|---|
| 292 | + pci_free_irq_vectors(dev); |
|---|
| 288 | 293 | disable_pci: |
|---|
| 289 | 294 | pci_disable_device(dev); |
|---|
| 290 | 295 | dev_err(&dev->dev, "init %s fail, %d\n", pci_name(dev), retval); |
|---|
| .. | .. |
|---|
| 310 | 315 | void usb_hcd_pci_remove(struct pci_dev *dev) |
|---|
| 311 | 316 | { |
|---|
| 312 | 317 | struct usb_hcd *hcd; |
|---|
| 318 | + int hcd_driver_flags; |
|---|
| 313 | 319 | |
|---|
| 314 | 320 | hcd = pci_get_drvdata(dev); |
|---|
| 315 | 321 | if (!hcd) |
|---|
| 316 | 322 | return; |
|---|
| 323 | + |
|---|
| 324 | + hcd_driver_flags = hcd->driver->flags; |
|---|
| 317 | 325 | |
|---|
| 318 | 326 | if (pci_dev_run_wake(dev)) |
|---|
| 319 | 327 | pm_runtime_get_noresume(&dev->dev); |
|---|
| .. | .. |
|---|
| 342 | 350 | up_read(&companions_rwsem); |
|---|
| 343 | 351 | } |
|---|
| 344 | 352 | usb_put_hcd(hcd); |
|---|
| 353 | + if ((hcd_driver_flags & HCD_MASK) < HCD_USB3) |
|---|
| 354 | + pci_free_irq_vectors(dev); |
|---|
| 345 | 355 | pci_disable_device(dev); |
|---|
| 346 | 356 | } |
|---|
| 347 | 357 | EXPORT_SYMBOL_GPL(usb_hcd_pci_remove); |
|---|
| .. | .. |
|---|
| 393 | 403 | |
|---|
| 394 | 404 | static int check_root_hub_suspended(struct device *dev) |
|---|
| 395 | 405 | { |
|---|
| 396 | | - struct pci_dev *pci_dev = to_pci_dev(dev); |
|---|
| 397 | | - struct usb_hcd *hcd = pci_get_drvdata(pci_dev); |
|---|
| 406 | + struct usb_hcd *hcd = dev_get_drvdata(dev); |
|---|
| 398 | 407 | |
|---|
| 399 | 408 | if (HCD_RH_RUNNING(hcd)) { |
|---|
| 400 | 409 | dev_warn(dev, "Root hub is not suspended\n"); |
|---|
| .. | .. |
|---|
| 454 | 463 | * synchronized here. |
|---|
| 455 | 464 | */ |
|---|
| 456 | 465 | if (!hcd->msix_enabled) |
|---|
| 457 | | - synchronize_irq(pci_dev->irq); |
|---|
| 466 | + synchronize_irq(pci_irq_vector(pci_dev, 0)); |
|---|
| 458 | 467 | |
|---|
| 459 | 468 | /* Downstream ports from this root hub should already be quiesced, so |
|---|
| 460 | 469 | * there will be no DMA activity. Now we can shut down the upstream |
|---|
| .. | .. |
|---|
| 605 | 614 | .suspend_noirq = hcd_pci_suspend_noirq, |
|---|
| 606 | 615 | .resume_noirq = hcd_pci_resume_noirq, |
|---|
| 607 | 616 | .resume = hcd_pci_resume, |
|---|
| 608 | | - .freeze = check_root_hub_suspended, |
|---|
| 617 | + .freeze = hcd_pci_suspend, |
|---|
| 609 | 618 | .freeze_noirq = check_root_hub_suspended, |
|---|
| 610 | 619 | .thaw_noirq = NULL, |
|---|
| 611 | | - .thaw = NULL, |
|---|
| 620 | + .thaw = hcd_pci_resume, |
|---|
| 612 | 621 | .poweroff = hcd_pci_suspend, |
|---|
| 613 | 622 | .poweroff_noirq = hcd_pci_suspend_noirq, |
|---|
| 614 | 623 | .restore_noirq = hcd_pci_resume_noirq, |
|---|