]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/i2c/busses/i2c-nforce2.c
i2c-bfin-twi: Update the dependencies
[linux-2.6-omap-h63xx.git] / drivers / i2c / busses / i2c-nforce2.c
index 1bf590c741660a752d6f69e5592a20b5c94eadf9..f95efff9b3d1900d4c00744919021cf2da2e0202 100644 (file)
@@ -50,6 +50,7 @@
 #include <linux/init.h>
 #include <linux/i2c.h>
 #include <linux/delay.h>
+#include <linux/dmi.h>
 #include <asm/io.h>
 
 MODULE_LICENSE("GPL");
@@ -109,8 +110,34 @@ struct nforce2_smbus {
 /* Misc definitions */
 #define MAX_TIMEOUT    100
 
+/* We disable the second SMBus channel on these boards */
+static struct dmi_system_id __devinitdata nforce2_dmi_blacklist2[] = {
+       {
+               .ident = "DFI Lanparty NF4 Expert",
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "DFI Corp,LTD"),
+                       DMI_MATCH(DMI_BOARD_NAME, "LP UT NF4 Expert"),
+               },
+       },
+       { }
+};
+
 static struct pci_driver nforce2_driver;
 
+/* For multiplexing support, we need a global reference to the 1st
+   SMBus channel */
+#if defined CONFIG_I2C_NFORCE2_S4985 || defined CONFIG_I2C_NFORCE2_S4985_MODULE
+struct i2c_adapter *nforce2_smbus;
+EXPORT_SYMBOL_GPL(nforce2_smbus);
+
+static void nforce2_set_reference(struct i2c_adapter *adap)
+{
+       nforce2_smbus = adap;
+}
+#else
+static inline void nforce2_set_reference(struct i2c_adapter *adap) { }
+#endif
+
 static void nforce2_abort(struct i2c_adapter *adap)
 {
        struct nforce2_smbus *smbus = adap->algo_data;
@@ -351,6 +378,7 @@ static int __devinit nforce2_probe(struct pci_dev *dev, const struct pci_device_
        pci_set_drvdata(dev, smbuses);
 
        switch(dev->device) {
+       case PCI_DEVICE_ID_NVIDIA_NFORCE2_SMBUS:
        case PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SMBUS:
        case PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SMBUS:
                smbuses[0].blockops = 1;
@@ -366,10 +394,17 @@ static int __devinit nforce2_probe(struct pci_dev *dev, const struct pci_device_
                smbuses[0].base = 0;    /* to have a check value */
        }
        /* SMBus adapter 2 */
-       res2 = nforce2_probe_smb(dev, 5, NFORCE_PCI_SMB2, &smbuses[1], "SMB2");
-       if (res2 < 0) {
-               dev_err(&dev->dev, "Error probing SMB2.\n");
-               smbuses[1].base = 0;    /* to have a check value */
+       if (dmi_check_system(nforce2_dmi_blacklist2)) {
+               dev_err(&dev->dev, "Disabling SMB2 for safety reasons.\n");
+               res2 = -EPERM;
+               smbuses[1].base = 0;
+       } else {
+               res2 = nforce2_probe_smb(dev, 5, NFORCE_PCI_SMB2, &smbuses[1],
+                                        "SMB2");
+               if (res2 < 0) {
+                       dev_err(&dev->dev, "Error probing SMB2.\n");
+                       smbuses[1].base = 0;    /* to have a check value */
+               }
        }
        if ((res1 < 0) && (res2 < 0)) {
                /* we did not find even one of the SMBuses, so we give up */
@@ -377,6 +412,7 @@ static int __devinit nforce2_probe(struct pci_dev *dev, const struct pci_device_
                return -ENODEV;
        }
 
+       nforce2_set_reference(&smbuses[0].adapter);
        return 0;
 }
 
@@ -385,6 +421,7 @@ static void __devexit nforce2_remove(struct pci_dev *dev)
 {
        struct nforce2_smbus *smbuses = (void*) pci_get_drvdata(dev);
 
+       nforce2_set_reference(NULL);
        if (smbuses[0].base) {
                i2c_del_adapter(&smbuses[0].adapter);
                release_region(smbuses[0].base, smbuses[0].size);