.. | .. |
---|
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, |
---|