]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
usb: ehci: use amd_chipset_type to filter for usb subsystem hang bug
authorHuang Rui <ray.huang@amd.com>
Thu, 3 Oct 2013 15:37:12 +0000 (23:37 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 3 Oct 2013 22:44:50 +0000 (15:44 -0700)
Commit "usb: pci-quirks: refactor AMD quirk to abstract AMD chipset types"
introduced a new AMD chipset type to filter AMD platforms with different
chipsets.

According to a recent thread [1], this patch updates USB subsystem hang
symptom quirk which is observed on AMD all SB600 and SB700 revision
0x3a/0x3b. And make it use the new chipset type to represent.

[1] http://marc.info/?l=linux-usb&m=138012321616452&w=2

Signed-off-by: Huang Rui <ray.huang@amd.com>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/host/ehci-pci.c
drivers/usb/host/pci-quirks.c
drivers/usb/host/pci-quirks.h

index 854c2ec7b699d4effe2c9ca6ae4ab264e1a73cd8..3e86bf4371b3901de76ed7e5db8e8a8de5a72cd3 100644 (file)
@@ -58,8 +58,6 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
 {
        struct ehci_hcd         *ehci = hcd_to_ehci(hcd);
        struct pci_dev          *pdev = to_pci_dev(hcd->self.controller);
-       struct pci_dev          *p_smbus;
-       u8                      rev;
        u32                     temp;
        int                     retval;
 
@@ -175,22 +173,12 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
                /* SB600 and old version of SB700 have a bug in EHCI controller,
                 * which causes usb devices lose response in some cases.
                 */
-               if ((pdev->device == 0x4386) || (pdev->device == 0x4396)) {
-                       p_smbus = pci_get_device(PCI_VENDOR_ID_ATI,
-                                                PCI_DEVICE_ID_ATI_SBX00_SMBUS,
-                                                NULL);
-                       if (!p_smbus)
-                               break;
-                       rev = p_smbus->revision;
-                       if ((pdev->device == 0x4386) || (rev == 0x3a)
-                           || (rev == 0x3b)) {
-                               u8 tmp;
-                               ehci_info(ehci, "applying AMD SB600/SB700 USB "
-                                       "freeze workaround\n");
-                               pci_read_config_byte(pdev, 0x53, &tmp);
-                               pci_write_config_byte(pdev, 0x53, tmp | (1<<3));
-                       }
-                       pci_dev_put(p_smbus);
+               if ((pdev->device == 0x4386 || pdev->device == 0x4396) &&
+                               usb_amd_hang_symptom_quirk()) {
+                       u8 tmp;
+                       ehci_info(ehci, "applying AMD SB600/SB700 USB freeze workaround\n");
+                       pci_read_config_byte(pdev, 0x53, &tmp);
+                       pci_write_config_byte(pdev, 0x53, tmp | (1<<3));
                }
                break;
        case PCI_VENDOR_ID_NETMOS:
index 9eec463c73c50e9fdf426cbb59cf8e16dab414ee..138a55536d97699a22ed0076e261f13ff5761ae9 100644 (file)
@@ -262,6 +262,19 @@ int usb_hcd_amd_remote_wakeup_quirk(struct pci_dev *pdev)
 }
 EXPORT_SYMBOL_GPL(usb_hcd_amd_remote_wakeup_quirk);
 
+bool usb_amd_hang_symptom_quirk(void)
+{
+       u8 rev;
+
+       usb_amd_find_chipset_info();
+       rev = amd_chipset.sb_type.rev;
+       /* SB600 and old version of SB700 have hang symptom bug */
+       return amd_chipset.sb_type.gen == AMD_CHIPSET_SB600 ||
+                       (amd_chipset.sb_type.gen == AMD_CHIPSET_SB700 &&
+                        rev >= 0x3a && rev <= 0x3b);
+}
+EXPORT_SYMBOL_GPL(usb_amd_hang_symptom_quirk);
+
 /*
  * The hardware normally enables the A-link power management feature, which
  * lets the system lower the power consumption in idle states.
index ed6700d00fe6fd372f62b575b49075b5ede392f1..820f532f7c1ccb3f5178f29298b9b840c311aee6 100644 (file)
@@ -5,6 +5,7 @@
 void uhci_reset_hc(struct pci_dev *pdev, unsigned long base);
 int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base);
 int usb_amd_find_chipset_info(void);
+bool usb_amd_hang_symptom_quirk(void);
 void usb_amd_dev_put(void);
 void usb_amd_quirk_pll_disable(void);
 void usb_amd_quirk_pll_enable(void);