diff options
author | Greg Kroah-Hartman <gregkh@suse.de> | 2011-01-24 08:11:18 +0900 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-01-24 08:14:07 +0900 |
commit | fd96d0d8d8079b1ea7a7e8943a4da9dfc9621124 (patch) | |
tree | 1d1314722847d56e3b703ec721f9534e93fa5580 /drivers/usb/core | |
parent | 3c47eb06f08eb970ea9d696bcdb57a175d37b470 (diff) | |
parent | 50d64676d132a8a72a1a1657d7b3e6efa53da1ac (diff) | |
download | linux-fd96d0d8d8079b1ea7a7e8943a4da9dfc9621124.tar.gz linux-fd96d0d8d8079b1ea7a7e8943a4da9dfc9621124.tar.bz2 linux-fd96d0d8d8079b1ea7a7e8943a4da9dfc9621124.zip |
Merge branch 'for-usb-linus' of master.kernel.org:/pub/scm/linux/kernel/git/sarah/xhci into usb-linus
* 'for-usb-linus' of master.kernel.org:/pub/scm/linux/kernel/git/sarah/xhci:
xhci: Remove more doorbell-related reads
xHCI: fix printk_ratelimit() usage
xHCI: replace dev_dbg() with xhci_dbg()
xHCI: fix cycle bit set in giveback_first_trb()
xHCI: remove redundant parameter in giveback_first_trb()
xHCI: fix queue_trb in isoc transfer
xhci: Use GFP_NOIO during device reset.
usb: Realloc xHCI structures after a hub is verified.
xhci: Do not run xhci_cleanup_msix with irq disabled
xHCI: synchronize irq in xhci_suspend()
xhci: Resume bus on any port status change.
Diffstat (limited to 'drivers/usb/core')
-rw-r--r-- | drivers/usb/core/hcd-pci.c | 7 | ||||
-rw-r--r-- | drivers/usb/core/hub.c | 21 |
2 files changed, 27 insertions, 1 deletions
diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c index b55d46070a25..f71e8e307e0f 100644 --- a/drivers/usb/core/hcd-pci.c +++ b/drivers/usb/core/hcd-pci.c @@ -405,7 +405,12 @@ static int suspend_common(struct device *dev, bool do_wakeup) return retval; } - synchronize_irq(pci_dev->irq); + /* If MSI-X is enabled, the driver will have synchronized all vectors + * in pci_suspend(). If MSI or legacy PCI is enabled, that will be + * synchronized here. + */ + if (!hcd->msix_enabled) + synchronize_irq(pci_dev->irq); /* Downstream ports from this root hub should already be quiesced, so * there will be no DMA activity. Now we can shut down the upstream diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index b98efae6a1cf..4310cc4b1cb5 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -676,6 +676,8 @@ static void hub_init_func3(struct work_struct *ws); static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) { struct usb_device *hdev = hub->hdev; + struct usb_hcd *hcd; + int ret; int port1; int status; bool need_debounce_delay = false; @@ -714,6 +716,25 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) usb_autopm_get_interface_no_resume( to_usb_interface(hub->intfdev)); return; /* Continues at init2: below */ + } else if (type == HUB_RESET_RESUME) { + /* The internal host controller state for the hub device + * may be gone after a host power loss on system resume. + * Update the device's info so the HW knows it's a hub. + */ + hcd = bus_to_hcd(hdev->bus); + if (hcd->driver->update_hub_device) { + ret = hcd->driver->update_hub_device(hcd, hdev, + &hub->tt, GFP_NOIO); + if (ret < 0) { + dev_err(hub->intfdev, "Host not " + "accepting hub info " + "update.\n"); + dev_err(hub->intfdev, "LS/FS devices " + "and hubs may not work " + "under this hub\n."); + } + } + hub_power_on(hub, true); } else { hub_power_on(hub, true); } |