mirror of https://gitee.com/openkylin/linux.git
EHCI: fix problem with BIOS handoff
This patch (as882) fixes a problem with the EHCI BIOS handoff. On my machine, the BIOS configures the controller and the handoff fails, leaving the controller configured. During resume-from-disk, this confuses ehci-hcd into thinking that the controller has not been tampered with. The problem is fixed by turning off the Configured Flag whenever a BIOS handoff is attempted, whether it succeeds or not. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
36433127ae
commit
4fe5354f61
|
@ -44,6 +44,7 @@
|
||||||
#define EHCI_USBSTS 4 /* status register */
|
#define EHCI_USBSTS 4 /* status register */
|
||||||
#define EHCI_USBSTS_HALTED (1 << 12) /* HCHalted bit */
|
#define EHCI_USBSTS_HALTED (1 << 12) /* HCHalted bit */
|
||||||
#define EHCI_USBINTR 8 /* interrupt register */
|
#define EHCI_USBINTR 8 /* interrupt register */
|
||||||
|
#define EHCI_CONFIGFLAG 0x40 /* configured flag register */
|
||||||
#define EHCI_USBLEGSUP 0 /* legacy support register */
|
#define EHCI_USBLEGSUP 0 /* legacy support register */
|
||||||
#define EHCI_USBLEGSUP_BIOS (1 << 16) /* BIOS semaphore */
|
#define EHCI_USBLEGSUP_BIOS (1 << 16) /* BIOS semaphore */
|
||||||
#define EHCI_USBLEGSUP_OS (1 << 24) /* OS semaphore */
|
#define EHCI_USBLEGSUP_OS (1 << 24) /* OS semaphore */
|
||||||
|
@ -216,6 +217,7 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev)
|
||||||
u32 hcc_params, val;
|
u32 hcc_params, val;
|
||||||
u8 offset, cap_length;
|
u8 offset, cap_length;
|
||||||
int count = 256/4;
|
int count = 256/4;
|
||||||
|
int tried_handoff = 0;
|
||||||
|
|
||||||
if (!mmio_resource_enabled(pdev, 0))
|
if (!mmio_resource_enabled(pdev, 0))
|
||||||
return;
|
return;
|
||||||
|
@ -273,6 +275,7 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev)
|
||||||
*/
|
*/
|
||||||
msec = 5000;
|
msec = 5000;
|
||||||
while ((cap & EHCI_USBLEGSUP_BIOS) && (msec > 0)) {
|
while ((cap & EHCI_USBLEGSUP_BIOS) && (msec > 0)) {
|
||||||
|
tried_handoff = 1;
|
||||||
msleep(10);
|
msleep(10);
|
||||||
msec -= 10;
|
msec -= 10;
|
||||||
pci_read_config_dword(pdev, offset, &cap);
|
pci_read_config_dword(pdev, offset, &cap);
|
||||||
|
@ -292,6 +295,12 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev)
|
||||||
pci_write_config_dword(pdev,
|
pci_write_config_dword(pdev,
|
||||||
offset + EHCI_USBLEGCTLSTS,
|
offset + EHCI_USBLEGCTLSTS,
|
||||||
0);
|
0);
|
||||||
|
|
||||||
|
/* If the BIOS ever owned the controller then we
|
||||||
|
* can't expect any power sessions to remain intact.
|
||||||
|
*/
|
||||||
|
if (tried_handoff)
|
||||||
|
writel(0, op_reg_base + EHCI_CONFIGFLAG);
|
||||||
break;
|
break;
|
||||||
case 0: /* illegal reserved capability */
|
case 0: /* illegal reserved capability */
|
||||||
cap = 0;
|
cap = 0;
|
||||||
|
|
Loading…
Reference in New Issue