Merge trivial low-risk suspend hotkey bugzilla-5918 into release
[sfrench/cifs-2.6.git] / drivers / pci / quirks.c
index d1d7333bb71bf17502c0ffd9f0aa2491f2f504ec..04618d4d7d74a2becb82d597ba936f3baa9bbb30 100644 (file)
@@ -400,6 +400,7 @@ static void __devinit quirk_piix4_acpi(struct pci_dev *dev)
        piix4_io_quirk(dev, "PIIX4 devres J", 0x7c, 1 << 20);
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_82371AB_3,  quirk_piix4_acpi );
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_82443MX_3,  quirk_piix4_acpi );
 
 /*
  * ICH4, ICH4-M, ICH5, ICH5-M ACPI: Three IO regions pointed to by longwords at
@@ -682,6 +683,33 @@ static void __devinit quirk_vt82c598_id(struct pci_dev *dev)
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA,    PCI_DEVICE_ID_VIA_82C597_0,     quirk_vt82c598_id );
 
+#ifdef CONFIG_ACPI_SLEEP
+
+/*
+ * Some VIA systems boot with the abnormal status flag set. This can cause
+ * the BIOS to re-POST the system on resume rather than passing control
+ * back to the OS.  Clear the flag on boot
+ */
+static void __devinit quirk_via_abnormal_poweroff(struct pci_dev *dev)
+{
+       u32 reg;
+
+       acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1_STATUS,
+                               &reg);
+
+       if (reg & 0x800) {
+               printk("Clearing abnormal poweroff flag\n");
+               acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
+                                       ACPI_REGISTER_PM1_STATUS,
+                                       (u16)0x800);
+       }
+}
+
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, quirk_via_abnormal_poweroff);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, quirk_via_abnormal_poweroff);
+
+#endif
+
 /*
  * CardBus controllers have a legacy base address that enables them
  * to respond as i82365 pcmcia controllers.  We don't want them to
@@ -962,6 +990,11 @@ static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev)
                        case 0x8070: /* P4G8X Deluxe */
                                asus_hides_smbus = 1;
                        }
+               if (dev->device == PCI_DEVICE_ID_INTEL_E7501_MCH)
+                       switch (dev->subsystem_device) {
+                       case 0x80c9: /* PU-DLS */
+                               asus_hides_smbus = 1;
+                       }
                if (dev->device == PCI_DEVICE_ID_INTEL_82855GM_HB)
                        switch (dev->subsystem_device) {
                        case 0x1751: /* M2N notebook */
@@ -1030,6 +1063,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,     PCI_DEVICE_ID_INTEL_82845G_HB,  asu
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_82850_HB,   asus_hides_smbus_hostbridge );
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_82865_HB,   asus_hides_smbus_hostbridge );
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_7205_0,     asus_hides_smbus_hostbridge );
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_E7501_MCH,  asus_hides_smbus_hostbridge );
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_82855PM_HB, asus_hides_smbus_hostbridge );
 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 );
@@ -1053,6 +1087,7 @@ static void __init asus_hides_smbus_lpc(struct pci_dev *dev)
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_82801DB_0,  asus_hides_smbus_lpc );
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_82801BA_0,  asus_hides_smbus_lpc );
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_82801CA_0,  asus_hides_smbus_lpc );
 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 );
@@ -1174,6 +1209,55 @@ 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 );
 
+#if defined(CONFIG_SCSI_SATA) || defined(CONFIG_SCSI_SATA_MODULE)
+
+/*
+ *     If we are using libata we can drive this chip properly but must
+ *     do this early on to make the additional device appear during
+ *     the PCI scanning.
+ */
+
+static void __devinit quirk_jmicron_dualfn(struct pci_dev *pdev)
+{
+       u32 conf;
+       u8 hdr;
+
+       /* Only poke fn 0 */
+       if (PCI_FUNC(pdev->devfn))
+               return;
+
+       switch(pdev->device) {
+               case PCI_DEVICE_ID_JMICRON_JMB365:
+               case PCI_DEVICE_ID_JMICRON_JMB366:
+                       /* Redirect IDE second PATA port to the right spot */
+                       pci_read_config_dword(pdev, 0x80, &conf);
+                       conf |= (1 << 24);
+                       /* Fall through */
+                       pci_write_config_dword(pdev, 0x80, conf);
+               case PCI_DEVICE_ID_JMICRON_JMB361:
+               case PCI_DEVICE_ID_JMICRON_JMB363:
+                       pci_read_config_dword(pdev, 0x40, &conf);
+                       /* Enable dual function mode, AHCI on fn 0, IDE fn1 */
+                       /* Set the class codes correctly and then direct IDE 0 */
+                       conf &= ~0x000F0200;    /* Clear bit 9 and 16-19 */
+                       conf |=  0x00C20002;    /* Set bit 1, 17, 22, 23 */
+                       pci_write_config_dword(pdev, 0x40, conf);
+
+                       /* Reconfigure so that the PCI scanner discovers the
+                          device is now multifunction */
+
+                       pci_read_config_byte(pdev, PCI_HEADER_TYPE, &hdr);
+                       pdev->hdr_type = hdr & 0x7f;
+                       pdev->multifunction = !!(hdr & 0x80);
+
+                       break;
+       }
+}
+
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, quirk_jmicron_dualfn);
+
+#endif
+
 #ifdef CONFIG_X86_IO_APIC
 static void __init quirk_alder_ioapic(struct pci_dev *pdev)
 {
@@ -1341,6 +1425,37 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL,     PCI_DEVICE_ID_INTEL_PXH_0,      quirk_pc
 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_PXH_1,      quirk_pcie_pxh);
 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_PXHV,       quirk_pcie_pxh);
 
+/*
+ * Some Intel PCI Express chipsets have trouble with downstream
+ * device power management.
+ */
+static void quirk_intel_pcie_pm(struct pci_dev * dev)
+{
+       pci_pm_d3_delay = 120;
+       dev->no_d1d2 = 1;
+}
+
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,   0x25e2, quirk_intel_pcie_pm);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,   0x25e3, quirk_intel_pcie_pm);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,   0x25e4, quirk_intel_pcie_pm);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,   0x25e5, quirk_intel_pcie_pm);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,   0x25e6, quirk_intel_pcie_pm);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,   0x25e7, quirk_intel_pcie_pm);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,   0x25f7, quirk_intel_pcie_pm);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,   0x25f8, quirk_intel_pcie_pm);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,   0x25f9, quirk_intel_pcie_pm);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,   0x25fa, quirk_intel_pcie_pm);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,   0x2601, quirk_intel_pcie_pm);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,   0x2602, quirk_intel_pcie_pm);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,   0x2603, quirk_intel_pcie_pm);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,   0x2604, quirk_intel_pcie_pm);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,   0x2605, quirk_intel_pcie_pm);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,   0x2606, quirk_intel_pcie_pm);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,   0x2607, quirk_intel_pcie_pm);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,   0x2608, quirk_intel_pcie_pm);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,   0x2609, quirk_intel_pcie_pm);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,   0x260a, quirk_intel_pcie_pm);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,   0x260b, quirk_intel_pcie_pm);
 
 /*
  * Fixup the cardbus bridges on the IBM Dock II docking station
@@ -1403,6 +1518,63 @@ static void __devinit quirk_netmos(struct pci_dev *dev)
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NETMOS, PCI_ANY_ID, quirk_netmos);
 
+static void __devinit quirk_e100_interrupt(struct pci_dev *dev)
+{
+       u16 command;
+       u32 bar;
+       u8 __iomem *csr;
+       u8 cmd_hi;
+
+       switch (dev->device) {
+       /* PCI IDs taken from drivers/net/e100.c */
+       case 0x1029:
+       case 0x1030 ... 0x1034:
+       case 0x1038 ... 0x103E:
+       case 0x1050 ... 0x1057:
+       case 0x1059:
+       case 0x1064 ... 0x106B:
+       case 0x1091 ... 0x1095:
+       case 0x1209:
+       case 0x1229:
+       case 0x2449:
+       case 0x2459:
+       case 0x245D:
+       case 0x27DC:
+               break;
+       default:
+               return;
+       }
+
+       /*
+        * Some firmware hands off the e100 with interrupts enabled,
+        * which can cause a flood of interrupts if packets are
+        * received before the driver attaches to the device.  So
+        * disable all e100 interrupts here.  The driver will
+        * re-enable them when it's ready.
+        */
+       pci_read_config_word(dev, PCI_COMMAND, &command);
+       pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &bar);
+
+       if (!(command & PCI_COMMAND_MEMORY) || !bar)
+               return;
+
+       csr = ioremap(bar, 8);
+       if (!csr) {
+               printk(KERN_WARNING "PCI: Can't map %s e100 registers\n",
+                       pci_name(dev));
+               return;
+       }
+
+       cmd_hi = readb(csr + 3);
+       if (cmd_hi == 0) {
+               printk(KERN_WARNING "PCI: Firmware left %s e100 interrupts "
+                       "enabled, disabling\n", pci_name(dev));
+               writeb(1, csr + 3);
+       }
+
+       iounmap(csr);
+}
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, quirk_e100_interrupt);
 
 static void __devinit fixup_rev1_53c810(struct pci_dev* dev)
 {