From 2eddc8a9bb5142e0debb8cd9e0a53aa88f25a60f Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Tue, 11 Jan 2011 17:43:27 -0500 Subject: [PATCH] - linux-2.6-ehci-check-port-status.patch - fix USB resume on some AMD systems --- kernel.spec | 5 +++ linux-2.6-ehci-check-port-status.patch | 54 ++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 linux-2.6-ehci-check-port-status.patch diff --git a/kernel.spec b/kernel.spec index 70a829329..7dca51129 100644 --- a/kernel.spec +++ b/kernel.spec @@ -729,6 +729,7 @@ Patch12200: acpi_reboot.patch Patch12210: efi_default_physical.patch # Runtime power management +Patch12202: linux-2.6-ehci-check-port-status.patch Patch12203: linux-2.6-usb-pci-autosuspend.patch Patch12204: linux-2.6-enable-more-pci-autosuspend.patch Patch12205: runtime_pm_fixups.patch @@ -1350,6 +1351,7 @@ ApplyPatch acpi_reboot.patch ApplyPatch efi_default_physical.patch # Runtime PM +ApplyPatch linux-2.6-ehci-check-port-status.patch ApplyPatch linux-2.6-usb-pci-autosuspend.patch ApplyPatch linux-2.6-enable-more-pci-autosuspend.patch ApplyPatch runtime_pm_fixups.patch @@ -1982,6 +1984,9 @@ fi # ||----w | # || || %changelog +* Tue Jan 11 2011 Matthew Garrett +- linux-2.6-ehci-check-port-status.patch - fix USB resume on some AMD systems + * Mon Jan 10 2011 Jarod Wilson - Add support for local rebuild config option overrides - Add missing --with/--without pae build flag support 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 +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 + +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)); + } +