diff options
Diffstat (limited to 'drivers/pci/quirks.c')
-rw-r--r-- | drivers/pci/quirks.c | 294 |
1 files changed, 42 insertions, 252 deletions
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 7992bc8cc6a4..5627ce1d2b32 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -7,6 +7,9 @@ | |||
7 | * | 7 | * |
8 | * Copyright (c) 1999 Martin Mares <mj@ucw.cz> | 8 | * Copyright (c) 1999 Martin Mares <mj@ucw.cz> |
9 | * | 9 | * |
10 | * Init/reset quirks for USB host controllers should be in the | ||
11 | * USB quirks file, where their drivers can access reuse it. | ||
12 | * | ||
10 | * The bridge optimization stuff has been removed. If you really | 13 | * The bridge optimization stuff has been removed. If you really |
11 | * have a silly BIOS which is unable to set your host bridge right, | 14 | * have a silly BIOS which is unable to set your host bridge right, |
12 | * use the PowerTweak utility (see http://powertweak.sourceforge.net). | 15 | * use the PowerTweak utility (see http://powertweak.sourceforge.net). |
@@ -353,7 +356,7 @@ static void piix4_mem_quirk(struct pci_dev *dev, const char *name, unsigned int | |||
353 | /* | 356 | /* |
354 | * PIIX4 ACPI: Two IO regions pointed to by longwords at | 357 | * PIIX4 ACPI: Two IO regions pointed to by longwords at |
355 | * 0x40 (64 bytes of ACPI registers) | 358 | * 0x40 (64 bytes of ACPI registers) |
356 | * 0x90 (32 bytes of SMB registers) | 359 | * 0x90 (16 bytes of SMB registers) |
357 | * and a few strange programmable PIIX4 device resources. | 360 | * and a few strange programmable PIIX4 device resources. |
358 | */ | 361 | */ |
359 | static void __devinit quirk_piix4_acpi(struct pci_dev *dev) | 362 | static void __devinit quirk_piix4_acpi(struct pci_dev *dev) |
@@ -363,7 +366,7 @@ static void __devinit quirk_piix4_acpi(struct pci_dev *dev) | |||
363 | pci_read_config_dword(dev, 0x40, ®ion); | 366 | pci_read_config_dword(dev, 0x40, ®ion); |
364 | quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES, "PIIX4 ACPI"); | 367 | quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES, "PIIX4 ACPI"); |
365 | pci_read_config_dword(dev, 0x90, ®ion); | 368 | pci_read_config_dword(dev, 0x90, ®ion); |
366 | quirk_io_region(dev, region, 32, PCI_BRIDGE_RESOURCES+1, "PIIX4 SMB"); | 369 | quirk_io_region(dev, region, 16, PCI_BRIDGE_RESOURCES+1, "PIIX4 SMB"); |
367 | 370 | ||
368 | /* Device resource A has enables for some of the other ones */ | 371 | /* Device resource A has enables for some of the other ones */ |
369 | pci_read_config_dword(dev, 0x5c, &res_a); | 372 | pci_read_config_dword(dev, 0x5c, &res_a); |
@@ -414,6 +417,18 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, | |||
414 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, quirk_ich4_lpc_acpi ); | 417 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, quirk_ich4_lpc_acpi ); |
415 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_1, quirk_ich4_lpc_acpi ); | 418 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_1, quirk_ich4_lpc_acpi ); |
416 | 419 | ||
420 | static void __devinit quirk_ich6_lpc_acpi(struct pci_dev *dev) | ||
421 | { | ||
422 | u32 region; | ||
423 | |||
424 | pci_read_config_dword(dev, 0x40, ®ion); | ||
425 | quirk_io_region(dev, region, 128, PCI_BRIDGE_RESOURCES, "ICH6 ACPI/GPIO/TCO"); | ||
426 | |||
427 | pci_read_config_dword(dev, 0x48, ®ion); | ||
428 | quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES+1, "ICH6 GPIO"); | ||
429 | } | ||
430 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, quirk_ich6_lpc_acpi ); | ||
431 | |||
417 | /* | 432 | /* |
418 | * VIA ACPI: One IO region pointed to by longword at | 433 | * VIA ACPI: One IO region pointed to by longword at |
419 | * 0x48 or 0x20 (256 bytes of ACPI registers) | 434 | * 0x48 or 0x20 (256 bytes of ACPI registers) |
@@ -633,28 +648,6 @@ static void quirk_via_irq(struct pci_dev *dev) | |||
633 | DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_ANY_ID, quirk_via_irq); | 648 | DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_ANY_ID, quirk_via_irq); |
634 | 649 | ||
635 | /* | 650 | /* |
636 | * PIIX3 USB: We have to disable USB interrupts that are | ||
637 | * hardwired to PIRQD# and may be shared with an | ||
638 | * external device. | ||
639 | * | ||
640 | * Legacy Support Register (LEGSUP): | ||
641 | * bit13: USB PIRQ Enable (USBPIRQDEN), | ||
642 | * bit4: Trap/SMI On IRQ Enable (USBSMIEN). | ||
643 | * | ||
644 | * We mask out all r/wc bits, too. | ||
645 | */ | ||
646 | static void __devinit quirk_piix3_usb(struct pci_dev *dev) | ||
647 | { | ||
648 | u16 legsup; | ||
649 | |||
650 | pci_read_config_word(dev, 0xc0, &legsup); | ||
651 | legsup &= 0x50ef; | ||
652 | pci_write_config_word(dev, 0xc0, legsup); | ||
653 | } | ||
654 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_2, quirk_piix3_usb ); | ||
655 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_2, quirk_piix3_usb ); | ||
656 | |||
657 | /* | ||
658 | * VIA VT82C598 has its device ID settable and many BIOSes | 651 | * VIA VT82C598 has its device ID settable and many BIOSes |
659 | * set it to the ID of VT82C597 for backward compatibility. | 652 | * set it to the ID of VT82C597 for backward compatibility. |
660 | * We need to switch it off to be able to recognize the real | 653 | * We need to switch it off to be able to recognize the real |
@@ -922,6 +915,12 @@ static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev) | |||
922 | case 0x186a: /* M6Ne notebook */ | 915 | case 0x186a: /* M6Ne notebook */ |
923 | asus_hides_smbus = 1; | 916 | asus_hides_smbus = 1; |
924 | } | 917 | } |
918 | if (dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB) { | ||
919 | switch (dev->subsystem_device) { | ||
920 | case 0x1882: /* M6V notebook */ | ||
921 | asus_hides_smbus = 1; | ||
922 | } | ||
923 | } | ||
925 | } else if (unlikely(dev->subsystem_vendor == PCI_VENDOR_ID_HP)) { | 924 | } else if (unlikely(dev->subsystem_vendor == PCI_VENDOR_ID_HP)) { |
926 | if (dev->device == PCI_DEVICE_ID_INTEL_82855PM_HB) | 925 | if (dev->device == PCI_DEVICE_ID_INTEL_82855PM_HB) |
927 | switch(dev->subsystem_device) { | 926 | switch(dev->subsystem_device) { |
@@ -932,6 +931,7 @@ static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev) | |||
932 | if (dev->device == PCI_DEVICE_ID_INTEL_82865_HB) | 931 | if (dev->device == PCI_DEVICE_ID_INTEL_82865_HB) |
933 | switch (dev->subsystem_device) { | 932 | switch (dev->subsystem_device) { |
934 | case 0x12bc: /* HP D330L */ | 933 | case 0x12bc: /* HP D330L */ |
934 | case 0x12bd: /* HP D530 */ | ||
935 | asus_hides_smbus = 1; | 935 | asus_hides_smbus = 1; |
936 | } | 936 | } |
937 | } else if (unlikely(dev->subsystem_vendor == PCI_VENDOR_ID_TOSHIBA)) { | 937 | } else if (unlikely(dev->subsystem_vendor == PCI_VENDOR_ID_TOSHIBA)) { |
@@ -966,6 +966,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82865_HB, asus | |||
966 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_7205_0, asus_hides_smbus_hostbridge ); | 966 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_7205_0, asus_hides_smbus_hostbridge ); |
967 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82855PM_HB, asus_hides_smbus_hostbridge ); | 967 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82855PM_HB, asus_hides_smbus_hostbridge ); |
968 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82855GM_HB, asus_hides_smbus_hostbridge ); | 968 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82855GM_HB, asus_hides_smbus_hostbridge ); |
969 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82915GM_HB, asus_hides_smbus_hostbridge ); | ||
969 | 970 | ||
970 | static void __init asus_hides_smbus_lpc(struct pci_dev *dev) | 971 | static void __init asus_hides_smbus_lpc(struct pci_dev *dev) |
971 | { | 972 | { |
@@ -990,6 +991,23 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, as | |||
990 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, asus_hides_smbus_lpc ); | 991 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, asus_hides_smbus_lpc ); |
991 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, asus_hides_smbus_lpc ); | 992 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, asus_hides_smbus_lpc ); |
992 | 993 | ||
994 | static void __init asus_hides_smbus_lpc_ich6(struct pci_dev *dev) | ||
995 | { | ||
996 | u32 val, rcba; | ||
997 | void __iomem *base; | ||
998 | |||
999 | if (likely(!asus_hides_smbus)) | ||
1000 | return; | ||
1001 | pci_read_config_dword(dev, 0xF0, &rcba); | ||
1002 | base = ioremap_nocache(rcba & 0xFFFFC000, 0x4000); /* use bits 31:14, 16 kB aligned */ | ||
1003 | if (base == NULL) return; | ||
1004 | val=readl(base + 0x3418); /* read the Function Disable register, dword mode only */ | ||
1005 | writel(val & 0xFFFFFFF7, base + 0x3418); /* enable the SMBus device */ | ||
1006 | iounmap(base); | ||
1007 | printk(KERN_INFO "PCI: Enabled ICH6/i801 SMBus device\n"); | ||
1008 | } | ||
1009 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, asus_hides_smbus_lpc_ich6 ); | ||
1010 | |||
993 | /* | 1011 | /* |
994 | * SiS 96x south bridge: BIOS typically hides SMBus device... | 1012 | * SiS 96x south bridge: BIOS typically hides SMBus device... |
995 | */ | 1013 | */ |
@@ -1002,234 +1020,6 @@ static void __init quirk_sis_96x_smbus(struct pci_dev *dev) | |||
1002 | pci_read_config_byte(dev, 0x77, &val); | 1020 | pci_read_config_byte(dev, 0x77, &val); |
1003 | } | 1021 | } |
1004 | 1022 | ||
1005 | |||
1006 | #define UHCI_USBLEGSUP 0xc0 /* legacy support */ | ||
1007 | #define UHCI_USBCMD 0 /* command register */ | ||
1008 | #define UHCI_USBSTS 2 /* status register */ | ||
1009 | #define UHCI_USBINTR 4 /* interrupt register */ | ||
1010 | #define UHCI_USBLEGSUP_DEFAULT 0x2000 /* only PIRQ enable set */ | ||
1011 | #define UHCI_USBCMD_RUN (1 << 0) /* RUN/STOP bit */ | ||
1012 | #define UHCI_USBCMD_GRESET (1 << 2) /* Global reset */ | ||
1013 | #define UHCI_USBCMD_CONFIGURE (1 << 6) /* config semaphore */ | ||
1014 | #define UHCI_USBSTS_HALTED (1 << 5) /* HCHalted bit */ | ||
1015 | |||
1016 | #define OHCI_CONTROL 0x04 | ||
1017 | #define OHCI_CMDSTATUS 0x08 | ||
1018 | #define OHCI_INTRSTATUS 0x0c | ||
1019 | #define OHCI_INTRENABLE 0x10 | ||
1020 | #define OHCI_INTRDISABLE 0x14 | ||
1021 | #define OHCI_OCR (1 << 3) /* ownership change request */ | ||
1022 | #define OHCI_CTRL_IR (1 << 8) /* interrupt routing */ | ||
1023 | #define OHCI_INTR_OC (1 << 30) /* ownership change */ | ||
1024 | |||
1025 | #define EHCI_HCC_PARAMS 0x08 /* extended capabilities */ | ||
1026 | #define EHCI_USBCMD 0 /* command register */ | ||
1027 | #define EHCI_USBCMD_RUN (1 << 0) /* RUN/STOP bit */ | ||
1028 | #define EHCI_USBSTS 4 /* status register */ | ||
1029 | #define EHCI_USBSTS_HALTED (1 << 12) /* HCHalted bit */ | ||
1030 | #define EHCI_USBINTR 8 /* interrupt register */ | ||
1031 | #define EHCI_USBLEGSUP 0 /* legacy support register */ | ||
1032 | #define EHCI_USBLEGSUP_BIOS (1 << 16) /* BIOS semaphore */ | ||
1033 | #define EHCI_USBLEGSUP_OS (1 << 24) /* OS semaphore */ | ||
1034 | #define EHCI_USBLEGCTLSTS 4 /* legacy control/status */ | ||
1035 | #define EHCI_USBLEGCTLSTS_SOOE (1 << 13) /* SMI on ownership change */ | ||
1036 | |||
1037 | int usb_early_handoff __devinitdata = 0; | ||
1038 | static int __init usb_handoff_early(char *str) | ||
1039 | { | ||
1040 | usb_early_handoff = 1; | ||
1041 | return 0; | ||
1042 | } | ||
1043 | __setup("usb-handoff", usb_handoff_early); | ||
1044 | |||
1045 | static void __devinit quirk_usb_handoff_uhci(struct pci_dev *pdev) | ||
1046 | { | ||
1047 | unsigned long base = 0; | ||
1048 | int wait_time, delta; | ||
1049 | u16 val, sts; | ||
1050 | int i; | ||
1051 | |||
1052 | for (i = 0; i < PCI_ROM_RESOURCE; i++) | ||
1053 | if ((pci_resource_flags(pdev, i) & IORESOURCE_IO)) { | ||
1054 | base = pci_resource_start(pdev, i); | ||
1055 | break; | ||
1056 | } | ||
1057 | |||
1058 | if (!base) | ||
1059 | return; | ||
1060 | |||
1061 | /* | ||
1062 | * stop controller | ||
1063 | */ | ||
1064 | sts = inw(base + UHCI_USBSTS); | ||
1065 | val = inw(base + UHCI_USBCMD); | ||
1066 | val &= ~(u16)(UHCI_USBCMD_RUN | UHCI_USBCMD_CONFIGURE); | ||
1067 | outw(val, base + UHCI_USBCMD); | ||
1068 | |||
1069 | /* | ||
1070 | * wait while it stops if it was running | ||
1071 | */ | ||
1072 | if ((sts & UHCI_USBSTS_HALTED) == 0) | ||
1073 | { | ||
1074 | wait_time = 1000; | ||
1075 | delta = 100; | ||
1076 | |||
1077 | do { | ||
1078 | outw(0x1f, base + UHCI_USBSTS); | ||
1079 | udelay(delta); | ||
1080 | wait_time -= delta; | ||
1081 | val = inw(base + UHCI_USBSTS); | ||
1082 | if (val & UHCI_USBSTS_HALTED) | ||
1083 | break; | ||
1084 | } while (wait_time > 0); | ||
1085 | } | ||
1086 | |||
1087 | /* | ||
1088 | * disable interrupts & legacy support | ||
1089 | */ | ||
1090 | outw(0, base + UHCI_USBINTR); | ||
1091 | outw(0x1f, base + UHCI_USBSTS); | ||
1092 | pci_read_config_word(pdev, UHCI_USBLEGSUP, &val); | ||
1093 | if (val & 0xbf) | ||
1094 | pci_write_config_word(pdev, UHCI_USBLEGSUP, UHCI_USBLEGSUP_DEFAULT); | ||
1095 | |||
1096 | } | ||
1097 | |||
1098 | static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev) | ||
1099 | { | ||
1100 | void __iomem *base; | ||
1101 | int wait_time; | ||
1102 | |||
1103 | base = ioremap_nocache(pci_resource_start(pdev, 0), | ||
1104 | pci_resource_len(pdev, 0)); | ||
1105 | if (base == NULL) return; | ||
1106 | |||
1107 | if (readl(base + OHCI_CONTROL) & OHCI_CTRL_IR) { | ||
1108 | wait_time = 500; /* 0.5 seconds */ | ||
1109 | writel(OHCI_INTR_OC, base + OHCI_INTRENABLE); | ||
1110 | writel(OHCI_OCR, base + OHCI_CMDSTATUS); | ||
1111 | while (wait_time > 0 && | ||
1112 | readl(base + OHCI_CONTROL) & OHCI_CTRL_IR) { | ||
1113 | wait_time -= 10; | ||
1114 | msleep(10); | ||
1115 | } | ||
1116 | } | ||
1117 | |||
1118 | /* | ||
1119 | * disable interrupts | ||
1120 | */ | ||
1121 | writel(~(u32)0, base + OHCI_INTRDISABLE); | ||
1122 | writel(~(u32)0, base + OHCI_INTRSTATUS); | ||
1123 | |||
1124 | iounmap(base); | ||
1125 | } | ||
1126 | |||
1127 | static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev) | ||
1128 | { | ||
1129 | int wait_time, delta; | ||
1130 | void __iomem *base, *op_reg_base; | ||
1131 | u32 hcc_params, val, temp; | ||
1132 | u8 cap_length; | ||
1133 | |||
1134 | base = ioremap_nocache(pci_resource_start(pdev, 0), | ||
1135 | pci_resource_len(pdev, 0)); | ||
1136 | if (base == NULL) return; | ||
1137 | |||
1138 | cap_length = readb(base); | ||
1139 | op_reg_base = base + cap_length; | ||
1140 | hcc_params = readl(base + EHCI_HCC_PARAMS); | ||
1141 | hcc_params = (hcc_params >> 8) & 0xff; | ||
1142 | if (hcc_params) { | ||
1143 | pci_read_config_dword(pdev, | ||
1144 | hcc_params + EHCI_USBLEGSUP, | ||
1145 | &val); | ||
1146 | if (((val & 0xff) == 1) && (val & EHCI_USBLEGSUP_BIOS)) { | ||
1147 | /* | ||
1148 | * Ok, BIOS is in smm mode, try to hand off... | ||
1149 | */ | ||
1150 | pci_read_config_dword(pdev, | ||
1151 | hcc_params + EHCI_USBLEGCTLSTS, | ||
1152 | &temp); | ||
1153 | pci_write_config_dword(pdev, | ||
1154 | hcc_params + EHCI_USBLEGCTLSTS, | ||
1155 | temp | EHCI_USBLEGCTLSTS_SOOE); | ||
1156 | val |= EHCI_USBLEGSUP_OS; | ||
1157 | pci_write_config_dword(pdev, | ||
1158 | hcc_params + EHCI_USBLEGSUP, | ||
1159 | val); | ||
1160 | |||
1161 | wait_time = 500; | ||
1162 | do { | ||
1163 | msleep(10); | ||
1164 | wait_time -= 10; | ||
1165 | pci_read_config_dword(pdev, | ||
1166 | hcc_params + EHCI_USBLEGSUP, | ||
1167 | &val); | ||
1168 | } while (wait_time && (val & EHCI_USBLEGSUP_BIOS)); | ||
1169 | if (!wait_time) { | ||
1170 | /* | ||
1171 | * well, possibly buggy BIOS... | ||
1172 | */ | ||
1173 | printk(KERN_WARNING "EHCI early BIOS handoff " | ||
1174 | "failed (BIOS bug ?)\n"); | ||
1175 | pci_write_config_dword(pdev, | ||
1176 | hcc_params + EHCI_USBLEGSUP, | ||
1177 | EHCI_USBLEGSUP_OS); | ||
1178 | pci_write_config_dword(pdev, | ||
1179 | hcc_params + EHCI_USBLEGCTLSTS, | ||
1180 | 0); | ||
1181 | } | ||
1182 | } | ||
1183 | } | ||
1184 | |||
1185 | /* | ||
1186 | * halt EHCI & disable its interrupts in any case | ||
1187 | */ | ||
1188 | val = readl(op_reg_base + EHCI_USBSTS); | ||
1189 | if ((val & EHCI_USBSTS_HALTED) == 0) { | ||
1190 | val = readl(op_reg_base + EHCI_USBCMD); | ||
1191 | val &= ~EHCI_USBCMD_RUN; | ||
1192 | writel(val, op_reg_base + EHCI_USBCMD); | ||
1193 | |||
1194 | wait_time = 2000; | ||
1195 | delta = 100; | ||
1196 | do { | ||
1197 | writel(0x3f, op_reg_base + EHCI_USBSTS); | ||
1198 | udelay(delta); | ||
1199 | wait_time -= delta; | ||
1200 | val = readl(op_reg_base + EHCI_USBSTS); | ||
1201 | if ((val == ~(u32)0) || (val & EHCI_USBSTS_HALTED)) { | ||
1202 | break; | ||
1203 | } | ||
1204 | } while (wait_time > 0); | ||
1205 | } | ||
1206 | writel(0, op_reg_base + EHCI_USBINTR); | ||
1207 | writel(0x3f, op_reg_base + EHCI_USBSTS); | ||
1208 | |||
1209 | iounmap(base); | ||
1210 | |||
1211 | return; | ||
1212 | } | ||
1213 | |||
1214 | |||
1215 | |||
1216 | static void __devinit quirk_usb_early_handoff(struct pci_dev *pdev) | ||
1217 | { | ||
1218 | if (!usb_early_handoff) | ||
1219 | return; | ||
1220 | |||
1221 | if (pdev->class == ((PCI_CLASS_SERIAL_USB << 8) | 0x00)) { /* UHCI */ | ||
1222 | quirk_usb_handoff_uhci(pdev); | ||
1223 | } else if (pdev->class == ((PCI_CLASS_SERIAL_USB << 8) | 0x10)) { /* OHCI */ | ||
1224 | quirk_usb_handoff_ohci(pdev); | ||
1225 | } else if (pdev->class == ((PCI_CLASS_SERIAL_USB << 8) | 0x20)) { /* EHCI */ | ||
1226 | quirk_usb_disable_ehci(pdev); | ||
1227 | } | ||
1228 | |||
1229 | return; | ||
1230 | } | ||
1231 | DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, quirk_usb_early_handoff); | ||
1232 | |||
1233 | /* | 1023 | /* |
1234 | * ... This is further complicated by the fact that some SiS96x south | 1024 | * ... This is further complicated by the fact that some SiS96x south |
1235 | * bridges pretend to be 85C503/5513 instead. In that case see if we | 1025 | * bridges pretend to be 85C503/5513 instead. In that case see if we |