]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/i2c/chips/max6875.c
Merge branches 'pxa' and 'orion-fixes1'
[linux-2.6-omap-h63xx.git] / drivers / i2c / chips / max6875.c
index 88d2ddee449065f7db62578e41255d8a54f3ffb6..fb7ea5637ecaef03f3ccdf0338232431da118087 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,
@@ -199,8 +200,7 @@ static int max6875_detect(struct i2c_adapter *adapter, int address, int kind)
        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;
@@ -214,13 +214,17 @@ static int max6875_detect(struct i2c_adapter *adapter, int address, int kind)
                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 +233,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;
 }