diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/usb/core/hcd-pci.c | 27 | ||||
-rw-r--r-- | drivers/usb/core/hcd.c | 4 | ||||
-rw-r--r-- | drivers/usb/host/xhci-ring.c | 2 |
3 files changed, 29 insertions, 4 deletions
diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c index 88d9109b4b4..b992a886f05 100644 --- a/drivers/usb/core/hcd-pci.c +++ b/drivers/usb/core/hcd-pci.c | |||
@@ -367,6 +367,13 @@ static int check_root_hub_suspended(struct device *dev) | |||
367 | dev_warn(dev, "Root hub is not suspended\n"); | 367 | dev_warn(dev, "Root hub is not suspended\n"); |
368 | return -EBUSY; | 368 | return -EBUSY; |
369 | } | 369 | } |
370 | if (hcd->shared_hcd) { | ||
371 | hcd = hcd->shared_hcd; | ||
372 | if (HCD_RH_RUNNING(hcd)) { | ||
373 | dev_warn(dev, "Secondary root hub is not suspended\n"); | ||
374 | return -EBUSY; | ||
375 | } | ||
376 | } | ||
370 | return 0; | 377 | return 0; |
371 | } | 378 | } |
372 | 379 | ||
@@ -391,11 +398,16 @@ static int suspend_common(struct device *dev, bool do_wakeup) | |||
391 | */ | 398 | */ |
392 | if (do_wakeup && HCD_WAKEUP_PENDING(hcd)) | 399 | if (do_wakeup && HCD_WAKEUP_PENDING(hcd)) |
393 | return -EBUSY; | 400 | return -EBUSY; |
401 | if (do_wakeup && hcd->shared_hcd && | ||
402 | HCD_WAKEUP_PENDING(hcd->shared_hcd)) | ||
403 | return -EBUSY; | ||
394 | retval = hcd->driver->pci_suspend(hcd, do_wakeup); | 404 | retval = hcd->driver->pci_suspend(hcd, do_wakeup); |
395 | suspend_report_result(hcd->driver->pci_suspend, retval); | 405 | suspend_report_result(hcd->driver->pci_suspend, retval); |
396 | 406 | ||
397 | /* Check again in case wakeup raced with pci_suspend */ | 407 | /* Check again in case wakeup raced with pci_suspend */ |
398 | if (retval == 0 && do_wakeup && HCD_WAKEUP_PENDING(hcd)) { | 408 | if ((retval == 0 && do_wakeup && HCD_WAKEUP_PENDING(hcd)) || |
409 | (retval == 0 && do_wakeup && hcd->shared_hcd && | ||
410 | HCD_WAKEUP_PENDING(hcd->shared_hcd))) { | ||
399 | if (hcd->driver->pci_resume) | 411 | if (hcd->driver->pci_resume) |
400 | hcd->driver->pci_resume(hcd, false); | 412 | hcd->driver->pci_resume(hcd, false); |
401 | retval = -EBUSY; | 413 | retval = -EBUSY; |
@@ -426,7 +438,9 @@ static int resume_common(struct device *dev, int event) | |||
426 | struct usb_hcd *hcd = pci_get_drvdata(pci_dev); | 438 | struct usb_hcd *hcd = pci_get_drvdata(pci_dev); |
427 | int retval; | 439 | int retval; |
428 | 440 | ||
429 | if (HCD_RH_RUNNING(hcd)) { | 441 | if (HCD_RH_RUNNING(hcd) || |
442 | (hcd->shared_hcd && | ||
443 | HCD_RH_RUNNING(hcd->shared_hcd))) { | ||
430 | dev_dbg(dev, "can't resume, not suspended!\n"); | 444 | dev_dbg(dev, "can't resume, not suspended!\n"); |
431 | return 0; | 445 | return 0; |
432 | } | 446 | } |
@@ -440,6 +454,8 @@ static int resume_common(struct device *dev, int event) | |||
440 | pci_set_master(pci_dev); | 454 | pci_set_master(pci_dev); |
441 | 455 | ||
442 | clear_bit(HCD_FLAG_SAW_IRQ, &hcd->flags); | 456 | clear_bit(HCD_FLAG_SAW_IRQ, &hcd->flags); |
457 | if (hcd->shared_hcd) | ||
458 | clear_bit(HCD_FLAG_SAW_IRQ, &hcd->shared_hcd->flags); | ||
443 | 459 | ||
444 | if (hcd->driver->pci_resume && !HCD_DEAD(hcd)) { | 460 | if (hcd->driver->pci_resume && !HCD_DEAD(hcd)) { |
445 | if (event != PM_EVENT_AUTO_RESUME) | 461 | if (event != PM_EVENT_AUTO_RESUME) |
@@ -449,6 +465,8 @@ static int resume_common(struct device *dev, int event) | |||
449 | event == PM_EVENT_RESTORE); | 465 | event == PM_EVENT_RESTORE); |
450 | if (retval) { | 466 | if (retval) { |
451 | dev_err(dev, "PCI post-resume error %d!\n", retval); | 467 | dev_err(dev, "PCI post-resume error %d!\n", retval); |
468 | if (hcd->shared_hcd) | ||
469 | usb_hc_died(hcd->shared_hcd); | ||
452 | usb_hc_died(hcd); | 470 | usb_hc_died(hcd); |
453 | } | 471 | } |
454 | } | 472 | } |
@@ -474,8 +492,9 @@ static int hcd_pci_suspend_noirq(struct device *dev) | |||
474 | 492 | ||
475 | pci_save_state(pci_dev); | 493 | pci_save_state(pci_dev); |
476 | 494 | ||
477 | /* If the root hub is dead rather than suspended, | 495 | /* If the root hub is dead rather than suspended, disallow remote |
478 | * disallow remote wakeup. | 496 | * wakeup. usb_hc_died() should ensure that both hosts are marked as |
497 | * dying, so we only need to check the primary roothub. | ||
479 | */ | 498 | */ |
480 | if (HCD_DEAD(hcd)) | 499 | if (HCD_DEAD(hcd)) |
481 | device_set_wakeup_enable(dev, 0); | 500 | device_set_wakeup_enable(dev, 0); |
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index ba15eeab824..02b4dbfa488 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
@@ -1153,6 +1153,8 @@ int usb_hcd_check_unlink_urb(struct usb_hcd *hcd, struct urb *urb, | |||
1153 | dev_warn(hcd->self.controller, "Unlink after no-IRQ? " | 1153 | dev_warn(hcd->self.controller, "Unlink after no-IRQ? " |
1154 | "Controller is probably using the wrong IRQ.\n"); | 1154 | "Controller is probably using the wrong IRQ.\n"); |
1155 | set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags); | 1155 | set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags); |
1156 | if (hcd->shared_hcd) | ||
1157 | set_bit(HCD_FLAG_SAW_IRQ, &hcd->shared_hcd->flags); | ||
1156 | } | 1158 | } |
1157 | 1159 | ||
1158 | return 0; | 1160 | return 0; |
@@ -2124,6 +2126,8 @@ irqreturn_t usb_hcd_irq (int irq, void *__hcd) | |||
2124 | rc = IRQ_NONE; | 2126 | rc = IRQ_NONE; |
2125 | } else { | 2127 | } else { |
2126 | set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags); | 2128 | set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags); |
2129 | if (hcd->shared_hcd) | ||
2130 | set_bit(HCD_FLAG_SAW_IRQ, &hcd->shared_hcd->flags); | ||
2127 | 2131 | ||
2128 | if (unlikely(hcd->state == HC_STATE_HALT)) | 2132 | if (unlikely(hcd->state == HC_STATE_HALT)) |
2129 | usb_hc_died(hcd); | 2133 | usb_hc_died(hcd); |
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 9e2b26c3da4..47763bed378 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c | |||
@@ -2181,6 +2181,8 @@ irqreturn_t xhci_msi_irq(int irq, struct usb_hcd *hcd) | |||
2181 | irqreturn_t ret; | 2181 | irqreturn_t ret; |
2182 | 2182 | ||
2183 | set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags); | 2183 | set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags); |
2184 | if (hcd->shared_hcd) | ||
2185 | set_bit(HCD_FLAG_SAW_IRQ, &hcd->shared_hcd->flags); | ||
2184 | 2186 | ||
2185 | ret = xhci_irq(hcd); | 2187 | ret = xhci_irq(hcd); |
2186 | 2188 | ||