]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/pci/quirks.c
PCI: quirks: switch quirks code offender to use pci_get API
[linux-2.6-omap-h63xx.git] / drivers / pci / quirks.c
index 08cd86a6dd6696585dc5937d1b056a55e898d6a0..e8a7f1b1b2bc4289546066375d1ef4b2e5792217 100644 (file)
@@ -93,8 +93,21 @@ static void __devinit quirk_nopcipci(struct pci_dev *dev)
                pci_pci_problems |= PCIPCI_FAIL;
        }
 }
+
+static void __devinit quirk_nopciamd(struct pci_dev *dev)
+{
+       u8 rev;
+       pci_read_config_byte(dev, 0x08, &rev);
+       if (rev == 0x13) {
+               /* Erratum 24 */
+               printk(KERN_INFO "Chipset erratum: Disabling direct PCI/AGP transfers.\n");
+               pci_pci_problems |= PCIAGP_FAIL;
+       }
+}
+
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SI,      PCI_DEVICE_ID_SI_5597,          quirk_nopcipci );
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SI,      PCI_DEVICE_ID_SI_496,           quirk_nopcipci );
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD,     PCI_DEVICE_ID_AMD_8151_0,       quirk_nopciamd );
 
 /*
  *     Triton requires workarounds to be used by the drivers
@@ -440,6 +453,12 @@ static void __devinit quirk_ich6_lpc_acpi(struct pci_dev *dev)
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_ICH6_0, quirk_ich6_lpc_acpi );
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_ICH6_1, quirk_ich6_lpc_acpi );
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_ICH7_0, quirk_ich6_lpc_acpi );
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_ICH7_1, quirk_ich6_lpc_acpi );
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_ICH7_31, quirk_ich6_lpc_acpi );
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_ICH8_0, quirk_ich6_lpc_acpi );
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_ICH8_2, quirk_ich6_lpc_acpi );
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_ICH8_3, quirk_ich6_lpc_acpi );
 
 /*
  * VIA ACPI: One IO region pointed to by longword at
@@ -555,7 +574,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA,  PCI_DEVICE_ID_VIA_8237,         quirk_via_vt
  * is currently marked NoFix
  *
  * We have multiple reports of hangs with this chipset that went away with
- * noapic specified. For the moment we assume its the errata. We may be wrong
+ * noapic specified. For the moment we assume it's the erratum. We may be wrong
  * of course. However the advice is demonstrably good even if so..
  */
 static void __devinit quirk_amd_ioapic(struct pci_dev *dev)
@@ -564,7 +583,7 @@ static void __devinit quirk_amd_ioapic(struct pci_dev *dev)
 
        pci_read_config_byte(dev, PCI_REVISION_ID, &rev);
        if (rev >= 0x02) {
-               printk(KERN_WARNING "I/O APIC: AMD Errata #22 may be present. In the event of instability try\n");
+               printk(KERN_WARNING "I/O APIC: AMD Erratum #22 may be present. In the event of instability try\n");
                printk(KERN_WARNING "        : booting with the \"noapic\" option.\n");
        }
 }
@@ -635,11 +654,43 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA,       PCI_DEVICE_ID_VIA_82C686_4,     quirk_vi
  * 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.
+ */
+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,
+       },
+       { 0, },
+};
+
 static void quirk_via_irq(struct pci_dev *dev)
 {
        u8 irq, new_irq;
 
-       new_irq = dev->irq & 0xf;
+       if (via_irq_fixup_needed == -1)
+               via_irq_fixup_needed = pci_dev_present(via_irq_fixup_tbl);
+
+       if (!via_irq_fixup_needed)
+               return;
+
+       new_irq = dev->irq;
+
+       /* Don't quirk interrupts outside the legacy IRQ range */
+       if (!new_irq || new_irq > 15)
+               return;
+
        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",
@@ -648,14 +699,7 @@ static void quirk_via_irq(struct pci_dev *dev)
                pci_write_config_byte(dev, PCI_INTERRUPT_LINE, new_irq);
        }
 }
-DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_0, quirk_via_irq);
-DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, quirk_via_irq);
-DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_2, quirk_via_irq);
-DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3, quirk_via_irq);
-DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235_USB_2, quirk_via_irq);
-DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, quirk_via_irq);
-DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_via_irq);
-DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_5, quirk_via_irq);
+DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_ANY_ID, quirk_via_irq);
 
 /*
  * VIA VT82C598 has its device ID settable and many BIOSes
@@ -1575,6 +1619,51 @@ static void __devinit fixup_rev1_53c810(struct pci_dev* dev)
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C810, fixup_rev1_53c810);
 
+/*
+ * Fixup to mark boot BIOS video selected by BIOS before it changes
+ *
+ * From information provided by "Jon Smirl" <jonsmirl@gmail.com>
+ *
+ * The standard boot ROM sequence for an x86 machine uses the BIOS
+ * to select an initial video card for boot display. This boot video
+ * card will have it's BIOS copied to C0000 in system RAM.
+ * IORESOURCE_ROM_SHADOW is used to associate the boot video
+ * card with this copy. On laptops this copy has to be used since
+ * the main ROM may be compressed or combined with another image.
+ * See pci_map_rom() for use of this flag. IORESOURCE_ROM_SHADOW
+ * is marked here since the boot video device will be the only enabled
+ * video device at this point.
+ */
+
+static void __devinit fixup_video(struct pci_dev *pdev)
+{
+       struct pci_dev *bridge;
+       struct pci_bus *bus;
+       u16 config;
+
+       if ((pdev->class >> 8) != PCI_CLASS_DISPLAY_VGA)
+               return;
+
+       /* Is VGA routed to us? */
+       bus = pdev->bus;
+       while (bus) {
+               bridge = bus->self;
+               if (bridge) {
+                       pci_read_config_word(bridge, PCI_BRIDGE_CONTROL,
+                                               &config);
+                       if (!(config & PCI_BRIDGE_CTL_VGA))
+                               return;
+               }
+               bus = bus->parent;
+       }
+       pci_read_config_word(pdev, PCI_COMMAND, &config);
+       if (config & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) {
+               pdev->resource[PCI_ROM_RESOURCE].flags |= IORESOURCE_ROM_SHADOW;
+               printk(KERN_DEBUG "Boot video device is %s\n", pci_name(pdev));
+       }
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, fixup_video);
+
 
 static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, struct pci_fixup *end)
 {
@@ -1751,7 +1840,7 @@ static void __devinit quirk_nvidia_ck804_msi_ht_cap(struct pci_dev *dev)
        /* check HT MSI cap on this chipset and the root one.
         * a single one having MSI is enough to be sure that MSI are supported.
         */
-       pdev = pci_find_slot(dev->bus->number, 0);
+       pdev = pci_get_slot(dev->bus, 0);
        if (dev->subordinate && !msi_ht_cap_enabled(dev)
            && !msi_ht_cap_enabled(pdev)) {
                printk(KERN_WARNING "PCI: MSI quirk detected. "
@@ -1759,6 +1848,7 @@ static void __devinit quirk_nvidia_ck804_msi_ht_cap(struct pci_dev *dev)
                       pci_name(dev));
                dev->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MSI;
        }
+       pci_dev_put(pdev);
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE,
                        quirk_nvidia_ck804_msi_ht_cap);