diff options
author | Kyle McMartin <kyle@redhat.com> | 2011-01-22 13:42:30 -0500 |
---|---|---|
committer | Kyle McMartin <kyle@redhat.com> | 2011-01-22 13:42:30 -0500 |
commit | b8f320f96d0de1aab0c6a39cb43bad99243a8bb8 (patch) | |
tree | efbfd1eb53f7e251c781742c608f862b48755a4e /linux-2.6-ehci-check-port-status.patch | |
parent | 91e1012aed060fa13824a80ed74dc3f0cc81f6d8 (diff) | |
download | kernel-b8f320f96d0de1aab0c6a39cb43bad99243a8bb8.tar.gz kernel-b8f320f96d0de1aab0c6a39cb43bad99243a8bb8.tar.xz kernel-b8f320f96d0de1aab0c6a39cb43bad99243a8bb8.zip |
- linux-2.6-ehci-check-port-status.patch - fix USB resume on some AMD systems
Conflicts:
kernel.spec
Diffstat (limited to 'linux-2.6-ehci-check-port-status.patch')
-rw-r--r-- | linux-2.6-ehci-check-port-status.patch | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/linux-2.6-ehci-check-port-status.patch b/linux-2.6-ehci-check-port-status.patch new file mode 100644 index 000000000..6182c77cf --- /dev/null +++ b/linux-2.6-ehci-check-port-status.patch @@ -0,0 +1,54 @@ +commit e17a07a9e0b62d5a5f0a5683ecbabad3aa95a4d5 +Author: Matthew Garrett <mjg@redhat.com> +Date: Tue Jan 11 12:19:40 2011 -0500 + + ehci: Check individual port status registers on resume + + If a device plug/unplug is detected on an ATI SB700 USB controller in D3, + it appears to set the port status register but not the controller status + register. As a result we'll fail to detect the plug event. Check the port + status register on resume as well in order to catch this case. + + Signed-off-by: Matthew Garrett <mjg@redhat.com> + +diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c +index 796ea0c..d9c0748 100644 +--- a/drivers/usb/host/ehci-hub.c ++++ b/drivers/usb/host/ehci-hub.c +@@ -106,6 +106,27 @@ static void ehci_handover_companion_ports(struct ehci_hcd *ehci) + ehci->owned_ports = 0; + } + ++static int ehci_port_change(struct ehci_hcd *ehci) ++{ ++ int i = HCS_N_PORTS(ehci->hcs_params); ++ ++ /* First check if the controller indicates a change event */ ++ ++ if (ehci_readl(ehci, &ehci->regs->status) & STS_PCD) ++ return 1; ++ ++ /* ++ * Not all controllers appear to update this while going from D3 to D0, ++ * so check the individual port status registers as well ++ */ ++ ++ while (i--) ++ if (ehci_readl(ehci, &ehci->regs->port_status[i]) & PORT_CSC) ++ return 1; ++ ++ return 0; ++} ++ + static void ehci_adjust_port_wakeup_flags(struct ehci_hcd *ehci, + bool suspending, bool do_wakeup) + { +@@ -168,7 +189,7 @@ static void ehci_adjust_port_wakeup_flags(struct ehci_hcd *ehci, + } + + /* Does the root hub have a port wakeup pending? */ +- if (!suspending && (ehci_readl(ehci, &ehci->regs->status) & STS_PCD)) ++ if (!suspending && ehci_port_change(ehci)) + usb_hcd_resume_root_hub(ehci_to_hcd(ehci)); + } + |