diff options
Diffstat (limited to 'drivers/pci/quirks.c')
-rw-r--r-- | drivers/pci/quirks.c | 292 |
1 files changed, 157 insertions, 135 deletions
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 5b448381169..0a70943f8bb 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -36,7 +36,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_MELLANOX,PCI_DEVICE_ID_MELLANOX_TAVOR_BRID /* Deal with broken BIOS'es that neglect to enable passive release, which can cause problems in combination with the 82441FX/PPro MTRRs */ -static void __devinit quirk_passive_release(struct pci_dev *dev) +static void quirk_passive_release(struct pci_dev *dev) { struct pci_dev *d = NULL; unsigned char dlc; @@ -53,6 +53,7 @@ static void __devinit quirk_passive_release(struct pci_dev *dev) } } DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82441, quirk_passive_release ); +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82441, quirk_passive_release ); /* The VIA VP2/VP3/MVP3 seem to have some 'features'. There may be a workaround but VIA don't answer queries. If you happen to have good contacts at VIA @@ -134,7 +135,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82439TX, quir * Updated based on further information from the site and also on * information provided by VIA */ -static void __devinit quirk_vialatency(struct pci_dev *dev) +static void quirk_vialatency(struct pci_dev *dev) { struct pci_dev *p; u8 rev; @@ -185,6 +186,10 @@ exit: DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8363_0, quirk_vialatency ); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8371_1, quirk_vialatency ); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8361, quirk_vialatency ); +/* Must restore this on a resume from RAM */ +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8363_0, quirk_vialatency ); +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8371_1, quirk_vialatency ); +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8361, quirk_vialatency ); /* * VIA Apollo VP3 needs ETBF on BT848/878 @@ -532,7 +537,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, quirk_vt8235 * TODO: When we have device-specific interrupt routers, * this code will go away from quirks. */ -static void __devinit quirk_via_ioapic(struct pci_dev *dev) +static void quirk_via_ioapic(struct pci_dev *dev) { u8 tmp; @@ -548,6 +553,7 @@ static void __devinit quirk_via_ioapic(struct pci_dev *dev) pci_write_config_byte (dev, 0x58, tmp); } DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, quirk_via_ioapic ); +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, quirk_via_ioapic ); /* * VIA 8237: Some BIOSs don't set the 'Bypass APIC De-Assert Message' Bit. @@ -555,7 +561,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, quirk_via_i * Set this bit to get rid of cycle wastage. * Otherwise uncritical. */ -static void __devinit quirk_via_vt8237_bypass_apic_deassert(struct pci_dev *dev) +static void quirk_via_vt8237_bypass_apic_deassert(struct pci_dev *dev) { u8 misc_control2; #define BYPASS_APIC_DEASSERT 8 @@ -567,6 +573,7 @@ static void __devinit quirk_via_vt8237_bypass_apic_deassert(struct pci_dev *dev) } } DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, quirk_via_vt8237_bypass_apic_deassert); +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, quirk_via_vt8237_bypass_apic_deassert); /* * The AMD io apic can hang the box when an apic irq is masked. @@ -600,7 +607,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SI, PCI_ANY_ID, quirk_ioapic_rmw ); #define AMD8131_revB0 0x11 #define AMD8131_MISC 0x40 #define AMD8131_NIOAMODE_BIT 0 -static void __init quirk_amd_8131_ioapic(struct pci_dev *dev) +static void quirk_amd_8131_ioapic(struct pci_dev *dev) { unsigned char revid, tmp; @@ -616,6 +623,7 @@ static void __init quirk_amd_8131_ioapic(struct pci_dev *dev) } } DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_amd_8131_ioapic); +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_amd_8131_ioapic); #endif /* CONFIG_X86_IO_APIC */ @@ -641,65 +649,84 @@ static void __devinit quirk_via_acpi(struct pci_dev *d) DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3, quirk_via_acpi ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_via_acpi ); -/* - * Via 686A/B: The PCI_INTERRUPT_LINE register for the on-chip - * devices, USB0/1, AC97, MC97, and ACPI, has an unusual feature: - * when written, it makes an internal connection to the PIC. - * For these devices, this register is defined to be 4 bits wide. - * Normally this is fine. However for IO-APIC motherboards, or - * non-x86 architectures (yes Via exists on PPC among other places), - * we must mask the PCI_INTERRUPT_LINE value versus 0xf to get - * interrupts delivered properly. - * - * Some of the on-chip devices are actually '586 devices' so they are - * listed here. - */ - -static int via_irq_fixup_needed = -1; /* - * As some VIA hardware is available in PCI-card form, we need to restrict - * this quirk to VIA PCI hardware built onto VIA-based motherboards only. - * We try to locate a VIA southbridge before deciding whether the quirk - * should be applied. + * VIA bridges which have VLink */ -static const struct pci_device_id via_irq_fixup_tbl[] = { - { - .vendor = PCI_VENDOR_ID_VIA, - .device = PCI_ANY_ID, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - .class = PCI_CLASS_BRIDGE_ISA << 8, - .class_mask = 0xffff00, - }, + +static const struct pci_device_id via_vlink_fixup_tbl[] = { + /* Internal devices need IRQ line routing, pre VLink */ + { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C686), 0 }, + { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8231), 17 }, + /* Devices with VLink */ + { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8233_0), 17}, + { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8233A), 17 }, + { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8233C_0), 17 }, + { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8235), 16 }, + { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8237), 15 }, + { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8237A), 15 }, { 0, }, }; -static void quirk_via_irq(struct pci_dev *dev) +/** + * quirk_via_vlink - VIA VLink IRQ number update + * @dev: PCI device + * + * If the device we are dealing with is on a PIC IRQ we need to + * ensure that the IRQ line register which usually is not relevant + * for PCI cards, is actually written so that interrupts get sent + * to the right place + */ + +static void quirk_via_vlink(struct pci_dev *dev) { + const struct pci_device_id *via_vlink_fixup; + static int dev_lo = -1, dev_hi = 18; u8 irq, new_irq; - if (via_irq_fixup_needed == -1) - via_irq_fixup_needed = pci_dev_present(via_irq_fixup_tbl); + /* Check if we have VLink and cache the result */ - if (!via_irq_fixup_needed) + /* Checked already - no */ + if (dev_lo == -2) return; + /* Not checked - see what bridge we have and find the device + ranges */ + + if (dev_lo == -1) { + via_vlink_fixup = pci_find_present(via_vlink_fixup_tbl); + if (via_vlink_fixup == NULL) { + dev_lo = -2; + return; + } + dev_lo = via_vlink_fixup->driver_data; + /* 82C686 is special - 0/0 */ + if (dev_lo == 0) + dev_hi = 0; + } new_irq = dev->irq; /* Don't quirk interrupts outside the legacy IRQ range */ if (!new_irq || new_irq > 15) return; + /* Internal device ? */ + if (dev->bus->number != 0 || PCI_SLOT(dev->devfn) > dev_hi || + PCI_SLOT(dev->devfn) < dev_lo) + return; + + /* This is an internal VLink device on a PIC interrupt. The BIOS + ought to have set this but may not have, so we redo it */ + pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq); if (new_irq != irq) { - printk(KERN_INFO "PCI: VIA IRQ fixup for %s, from %d to %d\n", + printk(KERN_INFO "PCI: VIA VLink IRQ fixup for %s, from %d to %d\n", pci_name(dev), irq, new_irq); udelay(15); /* unknown if delay really needed */ pci_write_config_byte(dev, PCI_INTERRUPT_LINE, new_irq); } } -DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_ANY_ID, quirk_via_irq); +DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_ANY_ID, quirk_via_vlink); /* * VIA VT82C598 has its device ID settable and many BIOSes @@ -720,13 +747,14 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C597_0, quirk_vt * do this even if the Linux CardBus driver is not loaded, because * the Linux i82365 driver does not (and should not) handle CardBus. */ -static void __devinit quirk_cardbus_legacy(struct pci_dev *dev) +static void quirk_cardbus_legacy(struct pci_dev *dev) { if ((PCI_CLASS_BRIDGE_CARDBUS << 8) ^ dev->class) return; pci_write_config_dword(dev, PCI_CB_LEGACY_MODE_BASE, 0); } DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, quirk_cardbus_legacy); +DECLARE_PCI_FIXUP_RESUME(PCI_ANY_ID, PCI_ANY_ID, quirk_cardbus_legacy); /* * Following the PCI ordering rules is optional on the AMD762. I'm not @@ -735,7 +763,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, quirk_cardbus_legacy); * To be fair to AMD, it follows the spec by default, its BIOS people * who turn it off! */ -static void __devinit quirk_amd_ordering(struct pci_dev *dev) +static void quirk_amd_ordering(struct pci_dev *dev) { u32 pcic; pci_read_config_dword(dev, 0x4C, &pcic); @@ -749,6 +777,7 @@ static void __devinit quirk_amd_ordering(struct pci_dev *dev) } } DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_700C, quirk_amd_ordering ); +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_700C, quirk_amd_ordering ); /* * DreamWorks provided workaround for Dunord I-3000 problem @@ -784,7 +813,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TOSHIBA, 0x605, quirk_transparent_bridge * datasheets found at http://www.national.com/ds/GX for info on what * these bits do. <christer@weinigel.se> */ -static void __init quirk_mediagx_master(struct pci_dev *dev) +static void quirk_mediagx_master(struct pci_dev *dev) { u8 reg; pci_read_config_byte(dev, 0x41, ®); @@ -795,63 +824,14 @@ static void __init quirk_mediagx_master(struct pci_dev *dev) } } DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_PCI_MASTER, quirk_mediagx_master ); - -/* - * As per PCI spec, ignore base address registers 0-3 of the IDE controllers - * running in Compatible mode (bits 0 and 2 in the ProgIf for primary and - * secondary channels respectively). If the device reports Compatible mode - * but does use BAR0-3 for address decoding, we assume that firmware has - * programmed these BARs with standard values (0x1f0,0x3f4 and 0x170,0x374). - * Exceptions (if they exist) must be handled in chip/architecture specific - * fixups. - * - * Note: for non x86 people. You may need an arch specific quirk to handle - * moving IDE devices to native mode as well. Some plug in card devices power - * up in compatible mode and assume the BIOS will adjust them. - * - * Q: should we load the 0x1f0,0x3f4 into the registers or zap them as - * we do now ? We don't want is pci_enable_device to come along - * and assign new resources. Both approaches work for that. - */ -static void __devinit quirk_ide_bases(struct pci_dev *dev) -{ - struct resource *res; - int first_bar = 2, last_bar = 0; - - if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE) - return; - - res = &dev->resource[0]; - - /* primary channel: ProgIf bit 0, BAR0, BAR1 */ - if (!(dev->class & 1) && (res[0].flags || res[1].flags)) { - res[0].start = res[0].end = res[0].flags = 0; - res[1].start = res[1].end = res[1].flags = 0; - first_bar = 0; - last_bar = 1; - } - - /* secondary channel: ProgIf bit 2, BAR2, BAR3 */ - if (!(dev->class & 4) && (res[2].flags || res[3].flags)) { - res[2].start = res[2].end = res[2].flags = 0; - res[3].start = res[3].end = res[3].flags = 0; - last_bar = 3; - } - - if (!last_bar) - return; - - printk(KERN_INFO "PCI: Ignoring BAR%d-%d of IDE controller %s\n", - first_bar, last_bar, pci_name(dev)); -} -DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, quirk_ide_bases); +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_PCI_MASTER, quirk_mediagx_master ); /* * Ensure C0 rev restreaming is off. This is normally done by * the BIOS but in the odd case it is not the results are corruption * hence the presence of a Linux check */ -static void __init quirk_disable_pxb(struct pci_dev *pdev) +static void quirk_disable_pxb(struct pci_dev *pdev) { u16 config; u8 rev; @@ -867,7 +847,25 @@ static void __init quirk_disable_pxb(struct pci_dev *pdev) } } DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, quirk_disable_pxb ); +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, quirk_disable_pxb ); + + +static void __devinit quirk_sb600_sata(struct pci_dev *pdev) +{ + /* set sb600 sata to ahci mode */ + if ((pdev->class >> 8) == PCI_CLASS_STORAGE_IDE) { + u8 tmp; + + pci_read_config_byte(pdev, 0x40, &tmp); + pci_write_config_byte(pdev, 0x40, tmp|1); + pci_write_config_byte(pdev, 0x9, 1); + pci_write_config_byte(pdev, 0xa, 6); + pci_write_config_byte(pdev, 0x40, tmp); + pdev->class = 0x010601; + } +} +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SATA, quirk_sb600_sata); /* * Serverworks CSB5 IDE does not fully support native mode @@ -880,11 +878,10 @@ static void __devinit quirk_svwks_csb5ide(struct pci_dev *pdev) prog &= ~5; pdev->class &= ~5; pci_write_config_byte(pdev, PCI_CLASS_PROG, prog); - /* need to re-assign BARs for compat mode */ - quirk_ide_bases(pdev); + /* PCI layer will sort out resources */ } } -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5IDE, quirk_svwks_csb5ide ); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5IDE, quirk_svwks_csb5ide ); /* * Intel 82801CAM ICH3-M datasheet says IDE modes must be the same @@ -900,11 +897,9 @@ static void __init quirk_ide_samemode(struct pci_dev *pdev) prog &= ~5; pdev->class &= ~5; pci_write_config_byte(pdev, PCI_CLASS_PROG, prog); - /* need to re-assign BARs for compat mode */ - quirk_ide_bases(pdev); } } -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_10, quirk_ide_samemode); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_10, quirk_ide_samemode); /* This was originally an Alpha specific thing, but it really fits here. * The i82375 PCI/EISA bridge appears as non-classified. Fix that. @@ -927,7 +922,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82375, quirk_e * runs everywhere at present we suppress the printk output in most * irrelevant cases. */ -static void __init k8t_sound_hostbridge(struct pci_dev *dev) +static void k8t_sound_hostbridge(struct pci_dev *dev) { unsigned char val; @@ -946,8 +941,8 @@ static void __init k8t_sound_hostbridge(struct pci_dev *dev) } } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, k8t_sound_hostbridge); +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, k8t_sound_hostbridge); -#ifndef CONFIG_ACPI_SLEEP /* * On ASUS P4B boards, the SMBus PCI Device within the ICH2/4 southbridge * is not activated. The myth is that Asus said that they do not want the @@ -959,12 +954,8 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, k8t_sound_ho * bridge. Unfortunately, this device has no subvendor/subdevice ID. So it * becomes necessary to do this tweak in two steps -- I've chosen the Host * bridge as trigger. - * - * Actually, leaving it unhidden and not redoing the quirk over suspend2ram - * will cause thermal management to break down, and causing machine to - * overheat. */ -static int __initdata asus_hides_smbus; +static int asus_hides_smbus; static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev) { @@ -1072,7 +1063,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82855PM_HB, as DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82855GM_HB, asus_hides_smbus_hostbridge ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82915GM_HB, asus_hides_smbus_hostbridge ); -static void __init asus_hides_smbus_lpc(struct pci_dev *dev) +static void asus_hides_smbus_lpc(struct pci_dev *dev) { u16 val; @@ -1095,8 +1086,14 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, asu DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, asus_hides_smbus_lpc ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, asus_hides_smbus_lpc ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, asus_hides_smbus_lpc ); +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0, asus_hides_smbus_lpc ); +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0, asus_hides_smbus_lpc ); +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, asus_hides_smbus_lpc ); +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, asus_hides_smbus_lpc ); +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, asus_hides_smbus_lpc ); +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, asus_hides_smbus_lpc ); -static void __init asus_hides_smbus_lpc_ich6(struct pci_dev *dev) +static void asus_hides_smbus_lpc_ich6(struct pci_dev *dev) { u32 val, rcba; void __iomem *base; @@ -1112,19 +1109,19 @@ static void __init asus_hides_smbus_lpc_ich6(struct pci_dev *dev) printk(KERN_INFO "PCI: Enabled ICH6/i801 SMBus device\n"); } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, asus_hides_smbus_lpc_ich6 ); - -#endif +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, asus_hides_smbus_lpc_ich6 ); /* * SiS 96x south bridge: BIOS typically hides SMBus device... */ -static void __init quirk_sis_96x_smbus(struct pci_dev *dev) +static void quirk_sis_96x_smbus(struct pci_dev *dev) { u8 val = 0; - printk(KERN_INFO "Enabling SiS 96x SMBus.\n"); - pci_read_config_byte(dev, 0x77, &val); - pci_write_config_byte(dev, 0x77, val & ~0x10); pci_read_config_byte(dev, 0x77, &val); + if (val & 0x10) { + printk(KERN_INFO "Enabling SiS 96x SMBus.\n"); + pci_write_config_byte(dev, 0x77, val & ~0x10); + } } /* @@ -1139,7 +1136,7 @@ static int __devinitdata sis_96x_compatible = 0; #define SIS_DETECT_REGISTER 0x40 -static void __init quirk_sis_503(struct pci_dev *dev) +static void quirk_sis_503(struct pci_dev *dev) { u8 reg; u16 devid; @@ -1156,11 +1153,12 @@ static void __init quirk_sis_503(struct pci_dev *dev) printk(KERN_WARNING "Uncovering SIS%x that hid as a SIS503 (compatible=%d)\n", devid, sis_96x_compatible); /* - * Ok, it now shows up as a 96x.. The 96x quirks are after - * the 503 quirk in the quirk table, so they'll automatically - * run and enable things like the SMBus device + * Ok, it now shows up as a 96x.. run the 96x quirk by + * hand in case it has already been processed. + * (depends on link order, which is apparently not guaranteed) */ dev->device = devid; + quirk_sis_96x_smbus(dev); } static void __init quirk_sis_96x_compatible(struct pci_dev *dev) @@ -1175,13 +1173,14 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_651, quirk_sis_96x_ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_735, quirk_sis_96x_compatible ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, quirk_sis_503 ); +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, quirk_sis_503 ); /* * On ASUS A8V and A8V Deluxe boards, the onboard AC97 audio controller * and MC97 modem controller are disabled when a second PCI soundcard is * present. This patch, tweaking the VT8237 ISA bridge, enables them. * -- bjd */ -static void __init asus_hides_ac97_lpc(struct pci_dev *dev) +static void asus_hides_ac97_lpc(struct pci_dev *dev) { u8 val; int asus_hides_ac97 = 0; @@ -1212,6 +1211,14 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_962, quirk_sis_96x_ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_963, quirk_sis_96x_smbus ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC, quirk_sis_96x_smbus ); +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, asus_hides_ac97_lpc ); + + +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_961, quirk_sis_96x_smbus ); +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_962, quirk_sis_96x_smbus ); +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_963, quirk_sis_96x_smbus ); +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC, quirk_sis_96x_smbus ); + #if defined(CONFIG_ATA) || defined(CONFIG_ATA_MODULE) /* @@ -1220,7 +1227,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC, quirk_sis_96x_ * the PCI scanning. */ -static void __devinit quirk_jmicron_dualfn(struct pci_dev *pdev) +static void quirk_jmicron_dualfn(struct pci_dev *pdev) { u32 conf; u8 hdr; @@ -1258,6 +1265,7 @@ static void __devinit quirk_jmicron_dualfn(struct pci_dev *pdev) } DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, quirk_jmicron_dualfn); +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, quirk_jmicron_dualfn); #endif @@ -1585,6 +1593,8 @@ extern struct pci_fixup __start_pci_fixups_final[]; extern struct pci_fixup __end_pci_fixups_final[]; extern struct pci_fixup __start_pci_fixups_enable[]; extern struct pci_fixup __end_pci_fixups_enable[]; +extern struct pci_fixup __start_pci_fixups_resume[]; +extern struct pci_fixup __end_pci_fixups_resume[]; void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev) @@ -1612,6 +1622,11 @@ void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev) end = __end_pci_fixups_enable; break; + case pci_fixup_resume: + start = __start_pci_fixups_resume; + end = __end_pci_fixups_resume; + break; + default: /* stupid compiler warning, you would think with an enum... */ return; @@ -1649,7 +1664,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1460, quirk_p64h2_1k_io); * Force it to be linked by setting the corresponding control bit in the * config space. */ -static void __devinit quirk_nvidia_ck804_pcie_aer_ext_cap(struct pci_dev *dev) +static void quirk_nvidia_ck804_pcie_aer_ext_cap(struct pci_dev *dev) { uint8_t b; if (pci_read_config_byte(dev, 0xf41, &b) == 0) { @@ -1663,6 +1678,8 @@ static void __devinit quirk_nvidia_ck804_pcie_aer_ext_cap(struct pci_dev *dev) } DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE, quirk_nvidia_ck804_pcie_aer_ext_cap); +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE, + quirk_nvidia_ck804_pcie_aer_ext_cap); #ifdef CONFIG_PCI_MSI /* To disable MSI globally */ @@ -1697,19 +1714,23 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_ * return 1 if a HT MSI capability is found and enabled */ static int __devinit msi_ht_cap_enabled(struct pci_dev *dev) { - u8 pos; - int ttl; - for (pos = pci_find_capability(dev, PCI_CAP_ID_HT), ttl = 48; - pos && ttl; - pos = pci_find_next_capability(dev, pos, PCI_CAP_ID_HT), ttl--) { - u32 cap_hdr; - /* MSI mapping section according to Hypertransport spec */ - if (pci_read_config_dword(dev, pos, &cap_hdr) == 0 - && (cap_hdr & 0xf8000000) == 0xa8000000 /* MSI mapping */) { - printk(KERN_INFO "PCI: Found HT MSI mapping on %s with capability %s\n", - pci_name(dev), cap_hdr & 0x10000 ? "enabled" : "disabled"); - return (cap_hdr & 0x10000) != 0; /* MSI mapping cap enabled */ + int pos, ttl = 48; + + pos = pci_find_ht_capability(dev, HT_CAPTYPE_MSI_MAPPING); + while (pos && ttl--) { + u8 flags; + + if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS, + &flags) == 0) + { + printk(KERN_INFO "PCI: Found %s HT MSI Mapping on %s\n", + flags & HT_MSI_FLAGS_ENABLE ? + "enabled" : "disabled", pci_name(dev)); + return (flags & HT_MSI_FLAGS_ENABLE) != 0; } + + pos = pci_find_next_ht_capability(dev, pos, + HT_CAPTYPE_MSI_MAPPING); } return 0; } @@ -1741,8 +1762,9 @@ static void __devinit quirk_nvidia_ck804_msi_ht_cap(struct pci_dev *dev) * a single one having MSI is enough to be sure that MSI are supported. */ pdev = pci_get_slot(dev->bus, 0); - if (dev->subordinate && !msi_ht_cap_enabled(dev) - && !msi_ht_cap_enabled(pdev)) { + if (!pdev) + return; + if (!msi_ht_cap_enabled(dev) && !msi_ht_cap_enabled(pdev)) { printk(KERN_WARNING "PCI: MSI quirk detected. " "MSI disabled on chipset %s.\n", pci_name(dev)); |