Merge branch 'core-iommu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[safe/jmp/linux-2.6] / drivers / i2c / busses / i2c-amd756.c
index 6347ebc..8f0b90e 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:
 #include <linux/kernel.h>
 #include <linux/delay.h>
 #include <linux/stddef.h>
-#include <linux/sched.h>
 #include <linux/ioport.h>
 #include <linux/i2c.h>
 #include <linux/init.h>
+#include <linux/acpi.h>
 #include <asm/io.h>
 
 /* AMD756 SMBus address offsets */
@@ -85,8 +82,8 @@
 #define AMD756_PROCESS_CALL    0x04
 #define AMD756_BLOCK_DATA      0x05
 
-
-static unsigned short amd756_ioport = 0;
+static struct pci_driver amd756_driver;
+static unsigned short amd756_ioport;
 
 /* 
   SMBUS event = I/O 28-29 bit 11
@@ -129,7 +126,7 @@ static int amd756_transaction(struct i2c_adapter *adap)
                } while ((temp & (GS_HST_STS | GS_SMB_STS)) &&
                         (timeout++ < MAX_TIMEOUT));
                /* If the SMBus is still busy, we give up */
-               if (timeout >= MAX_TIMEOUT) {
+               if (timeout > MAX_TIMEOUT) {
                        dev_dbg(&adap->dev, "Busy wait timeout (%04x)\n", temp);
                        goto abort;
                }
@@ -146,23 +143,23 @@ static int amd756_transaction(struct i2c_adapter *adap)
        } while ((temp & GS_HST_STS) && (timeout++ < MAX_TIMEOUT));
 
        /* If the SMBus is still busy, we give up */
-       if (timeout >= MAX_TIMEOUT) {
+       if (timeout > MAX_TIMEOUT) {
                dev_dbg(&adap->dev, "Completion timeout!\n");
                goto abort;
        }
 
        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");
        }
 
@@ -190,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);
@@ -252,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;
@@ -291,21 +288,18 @@ 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 struct i2c_algorithm smbus_algorithm = {
-       .name           = "Non-I2C SMBus adapter",
-       .id             = I2C_ALGO_SMBUS,
+static const struct i2c_algorithm smbus_algorithm = {
        .smbus_xfer     = amd756_access,
        .functionality  = amd756_func,
 };
 
 struct i2c_adapter amd756_smbus = {
        .owner          = THIS_MODULE,
-       .class          = I2C_CLASS_HWMON,
+       .class          = I2C_CLASS_HWMON | I2C_CLASS_SPD,
        .algo           = &smbus_algorithm,
-       .name           = "unset",
 };
 
 enum chiptype { AMD756, AMD766, AMD768, NFORCE, AMD8111 };
@@ -367,7 +361,12 @@ static int __devinit amd756_probe(struct pci_dev *pdev,
                amd756_ioport += SMB_ADDR_OFFSET;
        }
 
-       if (!request_region(amd756_ioport, SMB_IOSIZE, "amd756-smbus")) {
+       error = acpi_check_region(amd756_ioport, SMB_IOSIZE,
+                                 amd756_driver.name);
+       if (error)
+               return -ENODEV;
+
+       if (!request_region(amd756_ioport, SMB_IOSIZE, amd756_driver.name)) {
                dev_err(&pdev->dev, "SMB region 0x%x already in use!\n",
                        amd756_ioport);
                return -ENODEV;
@@ -377,11 +376,12 @@ static int __devinit amd756_probe(struct pci_dev *pdev,
        dev_dbg(&pdev->dev, "SMBREV = 0x%X\n", temp);
        dev_dbg(&pdev->dev, "AMD756_smba = 0x%X\n", amd756_ioport);
 
-       /* set up the driverfs linkage to our parent device */
+       /* set up the sysfs linkage to our parent device */
        amd756_smbus.dev.parent = &pdev->dev;
 
-       sprintf(amd756_smbus.name, "SMBus %s adapter at %04x",
-               chipname[id->driver_data], amd756_ioport);
+       snprintf(amd756_smbus.name, sizeof(amd756_smbus.name),
+                "SMBus %s adapter at %04x", chipname[id->driver_data],
+                amd756_ioport);
 
        error = i2c_add_adapter(&amd756_smbus);
        if (error) {