]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - drivers/pci/quirks.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/x86/linux...
[mv-sheeva.git] / drivers / pci / quirks.c
index 0a953d43b9a207961a6d41dbb1872d105f978982..afd914ebe2153aeca5bb78be50dcfed26c7d2603 100644 (file)
@@ -867,13 +867,13 @@ static void 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)
+static void __devinit quirk_amd_ide_mode(struct pci_dev *pdev)
 {
-       /* set sb600 sata to ahci mode */
-       if ((pdev->class >> 8) == PCI_CLASS_STORAGE_IDE) {
-               u8 tmp;
+       /* set sb600/sb700/sb800 sata to ahci mode */
+       u8 tmp;
 
+       pci_read_config_byte(pdev, PCI_CLASS_DEVICE, &tmp);
+       if (tmp == 0x01) {
                pci_read_config_byte(pdev, 0x40, &tmp);
                pci_write_config_byte(pdev, 0x40, tmp|1);
                pci_write_config_byte(pdev, 0x9, 1);
@@ -881,10 +881,13 @@ static void __devinit quirk_sb600_sata(struct pci_dev *pdev)
                pci_write_config_byte(pdev, 0x40, tmp);
 
                pdev->class = PCI_CLASS_STORAGE_SATA_AHCI;
+               dev_info(&pdev->dev, "set SATA to AHCI mode\n");
        }
 }
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SATA, quirk_sb600_sata);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP700_SATA, quirk_sb600_sata);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SATA, quirk_amd_ide_mode);
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SATA, quirk_amd_ide_mode);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP700_SATA, quirk_amd_ide_mode);
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP700_SATA, quirk_amd_ide_mode);
 
 /*
  *     Serverworks CSB5 IDE does not fully support native mode
@@ -948,6 +951,12 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,      PCI_DEVICE_ID_INTEL_82375,      quirk_e
  * accesses to the SMBus registers, with potentially bad effects. Thus you
  * should be very careful when adding new entries: if SMM is accessing the
  * Intel SMBus, this is a very good reason to leave it hidden.
+ *
+ * Likewise, many recent laptops use ACPI for thermal management. If the
+ * ACPI DSDT code accesses the SMBus, then Linux should not access it
+ * natively, and keeping the SMBus hidden is the right thing to do. If you
+ * are about to add an entry in the table below, please first disassemble
+ * the DSDT and double-check that there is no code accessing the SMBus.
  */
 static int asus_hides_smbus;
 
@@ -1025,11 +1034,6 @@ static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev)
                        case 0x12bf: /* HP xw4100 */
                                asus_hides_smbus = 1;
                        }
-               else if (dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB)
-                       switch (dev->subsystem_device) {
-                       case 0x099c: /* HP Compaq nx6110 */
-                               asus_hides_smbus = 1;
-                       }
        } else if (unlikely(dev->subsystem_vendor == PCI_VENDOR_ID_SAMSUNG)) {
                if (dev->device ==  PCI_DEVICE_ID_INTEL_82855PM_HB)
                        switch(dev->subsystem_device) {
@@ -1498,8 +1502,8 @@ static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, struct pci_f
                if ((f->vendor == dev->vendor || f->vendor == (u16) PCI_ANY_ID) &&
                    (f->device == dev->device || f->device == (u16) PCI_ANY_ID)) {
 #ifdef DEBUG
-                       dev_dbg(&dev->dev, "calling quirk 0x%p", f->hook);
-                       print_fn_descriptor_symbol("%s()\n",
+                       dev_dbg(&dev->dev, "calling ");
+                       print_fn_descriptor_symbol("%s()\n",
                                (unsigned long) f->hook);
 #endif
                        f->hook(dev);
@@ -1644,14 +1648,24 @@ static void __devinit quirk_via_cx700_pci_parking_caching(struct pci_dev *dev)
                        /* Turn off PCI Bus Parking */
                        pci_write_config_byte(dev, 0x76, b ^ 0x40);
 
+                       dev_info(&dev->dev,
+                               "Disabling VIA CX700 PCI parking\n");
+               }
+       }
+
+       if (pci_read_config_byte(dev, 0x72, &b) == 0) {
+               if (b != 0) {
                        /* Turn off PCI Master read caching */
                        pci_write_config_byte(dev, 0x72, 0x0);
+
+                       /* Set PCI Master Bus time-out to "1x16 PCLK" */
                        pci_write_config_byte(dev, 0x75, 0x1);
+
+                       /* Disable "Read FIFO Timer" */
                        pci_write_config_byte(dev, 0x77, 0x0);
 
-                       printk(KERN_INFO
-                               "PCI: VIA CX700 PCI parking/caching fixup on %s\n",
-                               pci_name(dev));
+                       dev_info(&dev->dev,
+                               "Disabling VIA CX700 PCI caching\n");
                }
        }
 }
@@ -1723,10 +1737,34 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT2
                        quirk_msi_ht_cap);
 
 
-/*
- *  Force enable MSI mapping capability on HT bridges
+/* The nVidia CK804 chipset may have 2 HT MSI mappings.
+ * MSI are supported if the MSI capability set in any of these mappings.
  */
-static void __devinit quirk_msi_ht_cap_enable(struct pci_dev *dev)
+static void __devinit quirk_nvidia_ck804_msi_ht_cap(struct pci_dev *dev)
+{
+       struct pci_dev *pdev;
+
+       if (!dev->subordinate)
+               return;
+
+       /* 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_get_slot(dev->bus, 0);
+       if (!pdev)
+               return;
+       if (!msi_ht_cap_enabled(dev) && !msi_ht_cap_enabled(pdev)) {
+               dev_warn(&dev->dev, "MSI quirk detected; "
+                       "subordinate MSI disabled\n");
+               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);
+
+/* Force enable MSI mapping capability on HT bridges */
+static void __devinit ht_enable_msi_mapping(struct pci_dev *dev)
 {
        int pos, ttl = 48;
 
@@ -1734,9 +1772,9 @@ static void __devinit quirk_msi_ht_cap_enable(struct pci_dev *dev)
        while (pos && ttl--) {
                u8 flags;
 
-               if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS, &flags) == 0) {
-                       printk(KERN_INFO "PCI: Enabling HT MSI Mapping on %s\n",
-                              pci_name(dev));
+               if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS,
+                                        &flags) == 0) {
+                       dev_info(&dev->dev, "Enabling HT MSI Mapping\n");
 
                        pci_write_config_byte(dev, pos + HT_MSI_FLAGS,
                                              flags | HT_MSI_FLAGS_ENABLE);
@@ -1747,33 +1785,47 @@ static void __devinit quirk_msi_ht_cap_enable(struct pci_dev *dev)
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SERVERWORKS,
                         PCI_DEVICE_ID_SERVERWORKS_HT1000_PXB,
-                        quirk_msi_ht_cap_enable);
+                        ht_enable_msi_mapping);
 
-/* The nVidia CK804 chipset may have 2 HT MSI mappings.
- * MSI are supported if the MSI capability set in any of these mappings.
- */
-static void __devinit quirk_nvidia_ck804_msi_ht_cap(struct pci_dev *dev)
+static void __devinit nv_msi_ht_cap_quirk(struct pci_dev *dev)
 {
-       struct pci_dev *pdev;
+       struct pci_dev *host_bridge;
+       int pos, ttl = 48;
 
-       if (!dev->subordinate)
+       /*
+        * HT MSI mapping should be disabled on devices that are below
+        * a non-Hypertransport host bridge. Locate the host bridge...
+        */
+       host_bridge = pci_get_bus_and_slot(0, PCI_DEVFN(0, 0));
+       if (host_bridge == NULL) {
+               dev_warn(&dev->dev,
+                        "nv_msi_ht_cap_quirk didn't locate host bridge\n");
                return;
+       }
 
-       /* 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_get_slot(dev->bus, 0);
-       if (!pdev)
+       pos = pci_find_ht_capability(host_bridge, HT_CAPTYPE_SLAVE);
+       if (pos != 0) {
+               /* Host bridge is to HT */
+               ht_enable_msi_mapping(dev);
                return;
-       if (!msi_ht_cap_enabled(dev) && !msi_ht_cap_enabled(pdev)) {
-               dev_warn(&dev->dev, "MSI quirk detected; "
-                       "subordinate MSI disabled\n");
-               dev->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MSI;
        }
-       pci_dev_put(pdev);
+
+       /* Host bridge is not to HT, disable HT MSI mapping on this device */
+       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) {
+                       dev_info(&dev->dev, "Disabling HT MSI mapping");
+                       pci_write_config_byte(dev, pos + HT_MSI_FLAGS,
+                                             flags & ~HT_MSI_FLAGS_ENABLE);
+               }
+               pos = pci_find_next_ht_capability(dev, pos,
+                                                 HT_CAPTYPE_MSI_MAPPING);
+       }
 }
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE,
-                       quirk_nvidia_ck804_msi_ht_cap);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, nv_msi_ht_cap_quirk);
 
 static void __devinit quirk_msi_intx_disable_bug(struct pci_dev *dev)
 {