Merge branch 'master' into upstream
[pandora-kernel.git] / drivers / i2c / busses / i2c-amd8111.c
index 45ea24b..5bba3fb 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/pci.h>
 #include <linux/kernel.h>
 #include <linux/stddef.h>
-#include <linux/sched.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
 #include <linux/i2c.h>
@@ -30,6 +29,8 @@ struct amd_smbus {
        int size;
 };
 
+static struct pci_driver amd8111_driver;
+
 /*
  * AMD PCI control registers definitions.
  */
@@ -74,7 +75,8 @@ static unsigned int amd_ec_wait_write(struct amd_smbus *smbus)
                udelay(1);
 
        if (!timeout) {
-               dev_warn(&smbus->dev->dev, "Timeout while waiting for IBF to clear\n");
+               dev_warn(&smbus->dev->dev,
+                        "Timeout while waiting for IBF to clear\n");
                return -1;
        }
 
@@ -89,14 +91,16 @@ static unsigned int amd_ec_wait_read(struct amd_smbus *smbus)
                udelay(1);
 
        if (!timeout) {
-               dev_warn(&smbus->dev->dev, "Timeout while waiting for OBF to set\n");
+               dev_warn(&smbus->dev->dev,
+                        "Timeout while waiting for OBF to set\n");
                return -1;
        }
 
        return 0;
 }
 
-static unsigned int amd_ec_read(struct amd_smbus *smbus, unsigned char address, unsigned char *data)
+static unsigned int amd_ec_read(struct amd_smbus *smbus, unsigned char address,
+               unsigned char *data)
 {
        if (amd_ec_wait_write(smbus))
                return -1;
@@ -113,7 +117,8 @@ static unsigned int amd_ec_read(struct amd_smbus *smbus, unsigned char address,
        return 0;
 }
 
-static unsigned int amd_ec_write(struct amd_smbus *smbus, unsigned char address, unsigned char data)
+static unsigned int amd_ec_write(struct amd_smbus *smbus, unsigned char address,
+               unsigned char data)
 {
        if (amd_ec_wait_write(smbus))
                return -1;
@@ -173,18 +178,19 @@ static unsigned int amd_ec_write(struct amd_smbus *smbus, unsigned char address,
 #define AMD_SMB_PRTCL_PEC              0x80
 
 
-static s32 amd8111_access(struct i2c_adapter * adap, u16 addr, unsigned short flags,
-               char read_write, u8 command, int size, union i2c_smbus_data * data)
+static s32 amd8111_access(struct i2c_adapter * adap, u16 addr,
+               unsigned short flags, char read_write, u8 command, int size,
+               union i2c_smbus_data * data)
 {
        struct amd_smbus *smbus = adap->algo_data;
        unsigned char protocol, len, pec, temp[2];
        int i;
 
-       protocol = (read_write == I2C_SMBUS_READ) ? AMD_SMB_PRTCL_READ : AMD_SMB_PRTCL_WRITE;
+       protocol = (read_write == I2C_SMBUS_READ) ? AMD_SMB_PRTCL_READ
+                                                 : AMD_SMB_PRTCL_WRITE;
        pec = (flags & I2C_CLIENT_PEC) ? AMD_SMB_PRTCL_PEC : 0;
 
        switch (size) {
-
                case I2C_SMBUS_QUICK:
                        protocol |= AMD_SMB_PRTCL_QUICK;
                        read_write = I2C_SMBUS_WRITE;
@@ -206,8 +212,10 @@ static s32 amd8111_access(struct i2c_adapter * adap, u16 addr, unsigned short fl
                case I2C_SMBUS_WORD_DATA:
                        amd_ec_write(smbus, AMD_SMB_CMD, command);
                        if (read_write == I2C_SMBUS_WRITE) {
-                               amd_ec_write(smbus, AMD_SMB_DATA, data->word);
-                               amd_ec_write(smbus, AMD_SMB_DATA + 1, data->word >> 8);
+                               amd_ec_write(smbus, AMD_SMB_DATA,
+                                            data->word & 0xff);
+                               amd_ec_write(smbus, AMD_SMB_DATA + 1,
+                                            data->word >> 8);
                        }
                        protocol |= AMD_SMB_PRTCL_WORD_DATA | pec;
                        break;
@@ -215,50 +223,47 @@ static s32 amd8111_access(struct i2c_adapter * adap, u16 addr, unsigned short fl
                case I2C_SMBUS_BLOCK_DATA:
                        amd_ec_write(smbus, AMD_SMB_CMD, command);
                        if (read_write == I2C_SMBUS_WRITE) {
-                               len = min_t(u8, data->block[0], 32);
+                               len = min_t(u8, data->block[0],
+                                           I2C_SMBUS_BLOCK_MAX);
                                amd_ec_write(smbus, AMD_SMB_BCNT, len);
                                for (i = 0; i < len; i++)
-                                       amd_ec_write(smbus, AMD_SMB_DATA + i, data->block[i + 1]);
+                                       amd_ec_write(smbus, AMD_SMB_DATA + i,
+                                                    data->block[i + 1]);
                        }
                        protocol |= AMD_SMB_PRTCL_BLOCK_DATA | pec;
                        break;
 
                case I2C_SMBUS_I2C_BLOCK_DATA:
-                       len = min_t(u8, data->block[0], 32);
+                       len = min_t(u8, data->block[0],
+                                   I2C_SMBUS_BLOCK_MAX);
                        amd_ec_write(smbus, AMD_SMB_CMD, command);
                        amd_ec_write(smbus, AMD_SMB_BCNT, len);
                        if (read_write == I2C_SMBUS_WRITE)
                                for (i = 0; i < len; i++)
-                                       amd_ec_write(smbus, AMD_SMB_DATA + i, data->block[i + 1]);
+                                       amd_ec_write(smbus, AMD_SMB_DATA + i,
+                                                    data->block[i + 1]);
                        protocol |= AMD_SMB_PRTCL_I2C_BLOCK_DATA;
                        break;
 
                case I2C_SMBUS_PROC_CALL:
                        amd_ec_write(smbus, AMD_SMB_CMD, command);
-                       amd_ec_write(smbus, AMD_SMB_DATA, data->word);
+                       amd_ec_write(smbus, AMD_SMB_DATA, data->word & 0xff);
                        amd_ec_write(smbus, AMD_SMB_DATA + 1, data->word >> 8);
                        protocol = AMD_SMB_PRTCL_PROC_CALL | pec;
                        read_write = I2C_SMBUS_READ;
                        break;
 
                case I2C_SMBUS_BLOCK_PROC_CALL:
-                       protocol |= pec;
                        len = min_t(u8, data->block[0], 31);
                        amd_ec_write(smbus, AMD_SMB_CMD, command);
                        amd_ec_write(smbus, AMD_SMB_BCNT, len);
                        for (i = 0; i < len; i++)
-                               amd_ec_write(smbus, AMD_SMB_DATA + i, data->block[i + 1]);
+                               amd_ec_write(smbus, AMD_SMB_DATA + i,
+                                            data->block[i + 1]);
                        protocol = AMD_SMB_PRTCL_BLOCK_PROC_CALL | pec;
                        read_write = I2C_SMBUS_READ;
                        break;
 
-               case I2C_SMBUS_WORD_DATA_PEC:
-               case I2C_SMBUS_BLOCK_DATA_PEC:
-               case I2C_SMBUS_PROC_CALL_PEC:
-               case I2C_SMBUS_BLOCK_PROC_CALL_PEC:
-                       dev_warn(&adap->dev, "Unexpected software PEC transaction %d\n.", size);
-                       return -1;
-
                default:
                        dev_warn(&adap->dev, "Unsupported transaction %d\n", size);
                        return -1;
@@ -286,7 +291,6 @@ static s32 amd8111_access(struct i2c_adapter * adap, u16 addr, unsigned short fl
                return 0;
 
        switch (size) {
-
                case I2C_SMBUS_BYTE:
                case I2C_SMBUS_BYTE_DATA:
                        amd_ec_read(smbus, AMD_SMB_DATA, &data->byte);
@@ -302,10 +306,11 @@ static s32 amd8111_access(struct i2c_adapter * adap, u16 addr, unsigned short fl
                case I2C_SMBUS_BLOCK_DATA:
                case I2C_SMBUS_BLOCK_PROC_CALL:
                        amd_ec_read(smbus, AMD_SMB_BCNT, &len);
-                       len = min_t(u8, len, 32);
+                       len = min_t(u8, len, I2C_SMBUS_BLOCK_MAX);
                case I2C_SMBUS_I2C_BLOCK_DATA:
                        for (i = 0; i < len; i++)
-                               amd_ec_read(smbus, AMD_SMB_DATA + i, data->block + i + 1);
+                               amd_ec_read(smbus, AMD_SMB_DATA + i,
+                                           data->block + i + 1);
                        data->block[0] = len;
                        break;
        }
@@ -316,13 +321,14 @@ static s32 amd8111_access(struct i2c_adapter * adap, u16 addr, unsigned short fl
 
 static u32 amd8111_func(struct i2c_adapter *adapter)
 {
-       return  I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | I2C_FUNC_SMBUS_BYTE_DATA |
+       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_PROC_CALL |
                I2C_FUNC_SMBUS_I2C_BLOCK | I2C_FUNC_SMBUS_HWPEC_CALC;
 }
 
-static struct i2c_algorithm smbus_algorithm = {
+static const struct i2c_algorithm smbus_algorithm = {
        .smbus_xfer = amd8111_access,
        .functionality = amd8111_func,
 };
@@ -335,29 +341,32 @@ static struct pci_device_id amd8111_ids[] = {
 
 MODULE_DEVICE_TABLE (pci, amd8111_ids);
 
-static int __devinit amd8111_probe(struct pci_dev *dev, const struct pci_device_id *id)
+static int __devinit amd8111_probe(struct pci_dev *dev,
+               const struct pci_device_id *id)
 {
        struct amd_smbus *smbus;
-       int error = -ENODEV;
+       int error;
 
-       if (~pci_resource_flags(dev, 0) & IORESOURCE_IO)
+       if (!(pci_resource_flags(dev, 0) & IORESOURCE_IO))
                return -ENODEV;
 
-       smbus = kmalloc(sizeof(struct amd_smbus), GFP_KERNEL);
+       smbus = kzalloc(sizeof(struct amd_smbus), GFP_KERNEL);
        if (!smbus)
                return -ENOMEM;
-       memset(smbus, 0, sizeof(struct amd_smbus));
 
        smbus->dev = dev;
        smbus->base = pci_resource_start(dev, 0);
        smbus->size = pci_resource_len(dev, 0);
 
-       if (!request_region(smbus->base, smbus->size, "amd8111 SMBus 2.0"))
+       if (!request_region(smbus->base, smbus->size, amd8111_driver.name)) {
+               error = -EBUSY;
                goto out_kfree;
+       }
 
        smbus->adapter.owner = THIS_MODULE;
        snprintf(smbus->adapter.name, I2C_NAME_SIZE,
                "SMBus2 AMD8111 adapter at %04x", smbus->base);
+       smbus->adapter.id = I2C_HW_SMBUS_AMD8111;
        smbus->adapter.class = I2C_CLASS_HWMON;
        smbus->adapter.algo = &smbus_algorithm;
        smbus->adapter.algo_data = smbus;
@@ -365,11 +374,11 @@ static int __devinit amd8111_probe(struct pci_dev *dev, const struct pci_device_
        /* set up the driverfs linkage to our parent device */
        smbus->adapter.dev.parent = &dev->dev;
 
+       pci_write_config_dword(smbus->dev, AMD_PCI_MISC, 0);
        error = i2c_add_adapter(&smbus->adapter);
        if (error)
                goto out_release_region;
 
-       pci_write_config_dword(smbus->dev, AMD_PCI_MISC, 0);
        pci_set_drvdata(dev, smbus);
        return 0;
 
@@ -377,10 +386,9 @@ static int __devinit amd8111_probe(struct pci_dev *dev, const struct pci_device_
        release_region(smbus->base, smbus->size);
  out_kfree:
        kfree(smbus);
-       return -1;
+       return error;
 }
 
-
 static void __devexit amd8111_remove(struct pci_dev *dev)
 {
        struct amd_smbus *smbus = pci_get_drvdata(dev);
@@ -402,7 +410,6 @@ static int __init i2c_amd8111_init(void)
        return pci_register_driver(&amd8111_driver);
 }
 
-
 static void __exit i2c_amd8111_exit(void)
 {
        pci_unregister_driver(&amd8111_driver);