Merge branch 'bkl-removal' into next
[pandora-kernel.git] / drivers / i2c / busses / i2c-amd756.c
index 573abe4..1ea3925 100644 (file)
@@ -1,7 +1,4 @@
 /*
-    amd756.c - Part of lm_sensors, Linux kernel modules for hardware
-              monitoring
-
     Copyright (c) 1999-2002 Merlin Hughes <merlin@merlin.org>
 
     Shamelessly ripped from i2c-piix4.c:
@@ -45,6 +42,7 @@
 #include <linux/ioport.h>
 #include <linux/i2c.h>
 #include <linux/init.h>
+#include <linux/acpi.h>
 #include <asm/io.h>
 
 /* AMD756 SMBus address offsets */
@@ -151,17 +149,17 @@ static int amd756_transaction(struct i2c_adapter *adap)
        }
 
        if (temp & GS_PRERR_STS) {
-               result = -1;
+               result = -ENXIO;
                dev_dbg(&adap->dev, "SMBus Protocol error (no response)!\n");
        }
 
        if (temp & GS_COL_STS) {
-               result = -1;
+               result = -EIO;
                dev_warn(&adap->dev, "SMBus collision!\n");
        }
 
        if (temp & GS_TO_STS) {
-               result = -1;
+               result = -ETIMEDOUT;
                dev_dbg(&adap->dev, "SMBus protocol timeout!\n");
        }
 
@@ -189,22 +187,18 @@ static int amd756_transaction(struct i2c_adapter *adap)
        outw_p(inw(SMB_GLOBAL_ENABLE) | GE_ABORT, SMB_GLOBAL_ENABLE);
        msleep(100);
        outw_p(GS_CLEAR_STS, SMB_GLOBAL_STATUS);
-       return -1;
+       return -EIO;
 }
 
-/* Return -1 on error. */
+/* Return negative errno on error. */
 static s32 amd756_access(struct i2c_adapter * adap, u16 addr,
                  unsigned short flags, char read_write,
                  u8 command, int size, union i2c_smbus_data * data)
 {
        int i, len;
+       int status;
 
-       /** TODO: Should I supporte the 10-bit transfers? */
        switch (size) {
-       case I2C_SMBUS_PROC_CALL:
-               dev_dbg(&adap->dev, "I2C_SMBUS_PROC_CALL not supported!\n");
-               /* TODO: Well... It is supported, I'm just not sure what to do here... */
-               return -1;
        case I2C_SMBUS_QUICK:
                outw_p(((addr & 0x7f) << 1) | (read_write & 0x01),
                       SMB_HOST_ADDRESS);
@@ -251,13 +245,17 @@ static s32 amd756_access(struct i2c_adapter * adap, u16 addr,
                }
                size = AMD756_BLOCK_DATA;
                break;
+       default:
+               dev_warn(&adap->dev, "Unsupported transaction %d\n", size);
+               return -EOPNOTSUPP;
        }
 
        /* How about enabling interrupts... */
        outw_p(size & GE_CYC_TYPE_MASK, SMB_GLOBAL_ENABLE);
 
-       if (amd756_transaction(adap))   /* Error in transaction */
-               return -1;
+       status = amd756_transaction(adap);
+       if (status)
+               return status;
 
        if ((read_write == I2C_SMBUS_WRITE) || (size == AMD756_QUICK))
                return 0;
@@ -290,7 +288,7 @@ static u32 amd756_func(struct i2c_adapter *adapter)
 {
        return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
            I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
-           I2C_FUNC_SMBUS_BLOCK_DATA | I2C_FUNC_SMBUS_PROC_CALL;
+           I2C_FUNC_SMBUS_BLOCK_DATA;
 }
 
 static const struct i2c_algorithm smbus_algorithm = {
@@ -301,7 +299,7 @@ static const struct i2c_algorithm smbus_algorithm = {
 struct i2c_adapter amd756_smbus = {
        .owner          = THIS_MODULE,
        .id             = I2C_HW_SMBUS_AMD756,
-       .class          = I2C_CLASS_HWMON,
+       .class          = I2C_CLASS_HWMON | I2C_CLASS_SPD,
        .algo           = &smbus_algorithm,
 };
 
@@ -335,7 +333,7 @@ static int __devinit amd756_probe(struct pci_dev *pdev,
        u8 temp;
        
        /* driver_data might come from user-space, so check it */
-       if (id->driver_data > ARRAY_SIZE(chipname))
+       if (id->driver_data >= ARRAY_SIZE(chipname))
                return -EINVAL;
 
        if (amd756_ioport) {
@@ -368,6 +366,11 @@ static int __devinit amd756_probe(struct pci_dev *pdev,
                amd756_ioport += SMB_ADDR_OFFSET;
        }
 
+       error = acpi_check_region(amd756_ioport, SMB_IOSIZE,
+                                 amd756_driver.name);
+       if (error)
+               return error;
+
        if (!request_region(amd756_ioport, SMB_IOSIZE, amd756_driver.name)) {
                dev_err(&pdev->dev, "SMB region 0x%x already in use!\n",
                        amd756_ioport);