diff options
Diffstat (limited to 'drivers/usb/host/ehci-pci.c')
| -rw-r--r-- | drivers/usb/host/ehci-pci.c | 24 | 
1 files changed, 24 insertions, 0 deletions
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index c46a58f9181..36864f95844 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c @@ -66,6 +66,8 @@ 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; @@ -166,6 +168,28 @@ static int ehci_pci_setup(struct usb_hcd *hcd)  			pci_write_config_byte(pdev, 0x4b, tmp | 0x20);  		}  		break; +	case PCI_VENDOR_ID_ATI: +		/* 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); +		} +		break;  	}  	ehci_reset(ehci);  |