]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/i2c/busses/i2c-i801.c
[S390] noexec protection
[linux-2.6-omap-h63xx.git] / drivers / i2c / busses / i2c-i801.c
index 3e0d04d5a800b574579bbd2cecf06c6b24fc66a5..ae625b85447074ee958e734ece3c3761bc4022a2 100644 (file)
@@ -33,6 +33,7 @@
     ICH7               27DA
     ESB2               269B
     ICH8               283E
+    ICH9               2930
     This driver supports several versions of Intel's I/O Controller Hubs (ICH).
     For SMBus support, they are similar to the PIIX4 and are part
     of Intel's '810' and other chipsets.
@@ -434,7 +435,7 @@ static u32 i801_func(struct i2c_adapter *adapter)
             | (isich4 ? I2C_FUNC_SMBUS_HWPEC_CALC : 0);
 }
 
-static struct i2c_algorithm smbus_algorithm = {
+static const struct i2c_algorithm smbus_algorithm = {
        .smbus_xfer     = i801_access,
        .functionality  = i801_func,
 };
@@ -457,6 +458,7 @@ static struct pci_device_id i801_ids[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_17) },
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB2_17) },
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_5) },
+       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_6) },
        { 0, }
 };
 
@@ -468,12 +470,20 @@ static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id
        int err;
 
        I801_dev = dev;
-       if ((dev->device == PCI_DEVICE_ID_INTEL_82801DB_3) ||
-           (dev->device == PCI_DEVICE_ID_INTEL_82801EB_3) ||
-           (dev->device == PCI_DEVICE_ID_INTEL_ESB_4))
+       switch (dev->device) {
+       case PCI_DEVICE_ID_INTEL_82801DB_3:
+       case PCI_DEVICE_ID_INTEL_82801EB_3:
+       case PCI_DEVICE_ID_INTEL_ESB_4:
+       case PCI_DEVICE_ID_INTEL_ICH6_16:
+       case PCI_DEVICE_ID_INTEL_ICH7_17:
+       case PCI_DEVICE_ID_INTEL_ESB2_17:
+       case PCI_DEVICE_ID_INTEL_ICH8_5:
+       case PCI_DEVICE_ID_INTEL_ICH9_6:
                isich4 = 1;
-       else
+               break;
+       default:
                isich4 = 0;
+       }
 
        err = pci_enable_device(dev);
        if (err) {
@@ -488,15 +498,15 @@ static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id
                dev_err(&dev->dev, "SMBus base address uninitialized, "
                        "upgrade BIOS\n");
                err = -ENODEV;
-               goto exit_disable;
+               goto exit;
        }
 
        err = pci_request_region(dev, SMBBAR, i801_driver.name);
        if (err) {
                dev_err(&dev->dev, "Failed to request SMBus region "
-                       "0x%lx-0x%lx\n", i801_smba,
-                       pci_resource_end(dev, SMBBAR));
-               goto exit_disable;
+                       "0x%lx-0x%Lx\n", i801_smba,
+                       (unsigned long long)pci_resource_end(dev, SMBBAR));
+               goto exit;
        }
 
        pci_read_config_byte(I801_dev, SMBHSTCFG, &temp);
@@ -520,11 +530,12 @@ static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id
        err = i2c_add_adapter(&i801_adapter);
        if (err) {
                dev_err(&dev->dev, "Failed to add SMBus adapter\n");
-               goto exit_disable;
+               goto exit_release;
        }
+       return 0;
 
-exit_disable:
-       pci_disable_device(dev);
+exit_release:
+       pci_release_region(dev, SMBBAR);
 exit:
        return err;
 }
@@ -533,7 +544,10 @@ static void __devexit i801_remove(struct pci_dev *dev)
 {
        i2c_del_adapter(&i801_adapter);
        pci_release_region(dev, SMBBAR);
-       pci_disable_device(dev);
+       /*
+        * do not call pci_disable_device(dev) since it can cause hard hangs on
+        * some systems during power-off (eg. Fujitsu-Siemens Lifebook E8010)
+        */
 }
 
 static struct pci_driver i801_driver = {