Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394...
[pandora-kernel.git] / drivers / i2c / chips / max6875.c
index 88d2dde..5a0285d 100644 (file)
@@ -34,7 +34,7 @@
 #include <linux/mutex.h>
 
 /* Do not scan - the MAX6875 access method will write to some EEPROM chips */
-static unsigned short normal_i2c[] = {I2C_CLIENT_END};
+static const unsigned short normal_i2c[] = { I2C_CLIENT_END };
 
 /* Insmod parameters */
 I2C_CLIENT_INSMOD_1(max6875);
@@ -106,6 +106,7 @@ static void max6875_update_slice(struct i2c_client *client, int slice)
                                            I2C_FUNC_SMBUS_READ_I2C_BLOCK)) {
                        if (i2c_smbus_read_i2c_block_data(client,
                                                          MAX6875_CMD_BLK_READ,
+                                                         SLICE_SIZE,
                                                          buf) != SLICE_SIZE) {
                                goto exit_up;
                        }
@@ -125,8 +126,9 @@ exit_up:
        mutex_unlock(&data->update_lock);
 }
 
-static ssize_t max6875_read(struct kobject *kobj, char *buf, loff_t off,
-                           size_t count)
+static ssize_t max6875_read(struct kobject *kobj,
+                           struct bin_attribute *bin_attr,
+                           char *buf, loff_t off, size_t count)
 {
        struct i2c_client *client = kobj_to_i2c_client(kobj);
        struct max6875_data *data = i2c_get_clientdata(client);
@@ -152,7 +154,6 @@ static struct bin_attribute user_eeprom_attr = {
        .attr = {
                .name = "eeprom",
                .mode = S_IRUGO,
-               .owner = THIS_MODULE,
        },
        .size = USER_EEPROM_SIZE,
        .read = max6875_read,
@@ -169,7 +170,7 @@ static int max6875_detect(struct i2c_adapter *adapter, int address, int kind)
        struct i2c_client *real_client;
        struct i2c_client *fake_client;
        struct max6875_data *data;
-       int err = 0;
+       int err;
 
        if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE_DATA
                                     | I2C_FUNC_SMBUS_READ_BYTE))
@@ -194,33 +195,31 @@ static int max6875_detect(struct i2c_adapter *adapter, int address, int kind)
        real_client->addr = address;
        real_client->adapter = adapter;
        real_client->driver = &max6875_driver;
-       real_client->flags = 0;
        strlcpy(real_client->name, "max6875", I2C_NAME_SIZE);
        mutex_init(&data->update_lock);
 
        /* Init fake client data */
-       /* set the client data to the i2c_client so that it will get freed */
-       i2c_set_clientdata(fake_client, fake_client);
+       i2c_set_clientdata(fake_client, NULL);
        fake_client->addr = address | 1;
        fake_client->adapter = adapter;
        fake_client->driver = &max6875_driver;
-       fake_client->flags = 0;
        strlcpy(fake_client->name, "max6875 subclient", I2C_NAME_SIZE);
 
-       /* Prevent 24RF08 corruption (in case of user error) */
-       i2c_smbus_write_quick(real_client, 0);
-
        if ((err = i2c_attach_client(real_client)) != 0)
                goto exit_kfree2;
 
        if ((err = i2c_attach_client(fake_client)) != 0)
-               goto exit_detach;
+               goto exit_detach1;
 
-       sysfs_create_bin_file(&real_client->dev.kobj, &user_eeprom_attr);
+       err = sysfs_create_bin_file(&real_client->dev.kobj, &user_eeprom_attr);
+       if (err)
+               goto exit_detach2;
 
        return 0;
 
-exit_detach:
+exit_detach2:
+       i2c_detach_client(fake_client);
+exit_detach1:
        i2c_detach_client(real_client);
 exit_kfree2:
        kfree(fake_client);
@@ -229,14 +228,24 @@ exit_kfree1:
        return err;
 }
 
+/* Will be called for both the real client and the fake client */
 static int max6875_detach_client(struct i2c_client *client)
 {
        int err;
+       struct max6875_data *data = i2c_get_clientdata(client);
+
+       /* data is NULL for the fake client */
+       if (data)
+               sysfs_remove_bin_file(&client->dev.kobj, &user_eeprom_attr);
 
        err = i2c_detach_client(client);
        if (err)
                return err;
-       kfree(i2c_get_clientdata(client));
+
+       if (data)               /* real client */
+               kfree(data);
+       else                    /* fake client */
+               kfree(client);
        return 0;
 }