summaryrefslogtreecommitdiffstats
path: root/linux-2.6-ehci-check-port-status.patch
diff options
context:
space:
mode:
authorKyle McMartin <kyle@redhat.com>2011-01-22 13:42:30 -0500
committerKyle McMartin <kyle@redhat.com>2011-01-22 13:42:30 -0500
commitb8f320f96d0de1aab0c6a39cb43bad99243a8bb8 (patch)
treeefbfd1eb53f7e251c781742c608f862b48755a4e /linux-2.6-ehci-check-port-status.patch
parent91e1012aed060fa13824a80ed74dc3f0cc81f6d8 (diff)
downloadkernel-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.patch54
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));
+ }
+