}
 
        /* create the sysfs eeprom file */
-       sysfs_create_bin_file(&new_client->dev.kobj, &eeprom_attr);
+       err = sysfs_create_bin_file(&new_client->dev.kobj, &eeprom_attr);
+       if (err)
+               goto exit_detach;
 
        return 0;
 
+exit_detach:
+       i2c_detach_client(new_client);
 exit_kfree:
        kfree(data);
 exit:
 {
        int err;
 
+       sysfs_remove_bin_file(&client->dev.kobj, &eeprom_attr);
+
        err = i2c_detach_client(client);
        if (err)
                return err;
 
        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;
                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);
        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;
 }
 
 
        if ((err = i2c_attach_client(new_client)))
                goto exit_kfree;
 
-       /* Register sysfs hooks (don't care about failure) */
-       sysfs_create_group(&new_client->dev.kobj, &pca9539_defattr_group);
+       /* Register sysfs hooks */
+       err = sysfs_create_group(&new_client->dev.kobj,
+                                &pca9539_defattr_group);
+       if (err)
+               goto exit_detach;
 
        return 0;
 
+exit_detach:
+       i2c_detach_client(new_client);
 exit_kfree:
        kfree(data);
 exit:
 {
        int err;
 
+       sysfs_remove_group(&client->dev.kobj, &pca9539_defattr_group);
+
        if ((err = i2c_detach_client(client)))
                return err;
 
 
 
 static DEVICE_ATTR(write, S_IWUSR | S_IRUGO, show_write, set_write);
 
+static struct attribute *pcf8574_attributes[] = {
+       &dev_attr_read.attr,
+       &dev_attr_write.attr,
+       NULL
+};
+
+static const struct attribute_group pcf8574_attr_group = {
+       .attrs = pcf8574_attributes,
+};
+
 /*
  * Real code
  */
        pcf8574_init_client(new_client);
 
        /* Register sysfs hooks */
-       device_create_file(&new_client->dev, &dev_attr_read);
-       device_create_file(&new_client->dev, &dev_attr_write);
+       err = sysfs_create_group(&new_client->dev.kobj, &pcf8574_attr_group);
+       if (err)
+               goto exit_detach;
        return 0;
 
-/* OK, this is not exactly good programming practice, usually. But it is
-   very code-efficient in this case. */
-
+      exit_detach:
+       i2c_detach_client(new_client);
       exit_free:
        kfree(data);
       exit:
 {
        int err;
 
+       sysfs_remove_group(&client->dev.kobj, &pcf8574_attr_group);
+
        if ((err = i2c_detach_client(client)))
                return err;
 
 
 static DEVICE_ATTR(out0_enable, S_IWUSR | S_IRUGO, 
                   show_out0_enable, set_out0_enable);
 
+static struct attribute *pcf8591_attributes[] = {
+       &dev_attr_out0_enable.attr,
+       &dev_attr_out0_output.attr,
+       &dev_attr_in0_input.attr,
+       &dev_attr_in1_input.attr,
+       NULL
+};
+
+static const struct attribute_group pcf8591_attr_group = {
+       .attrs = pcf8591_attributes,
+};
+
+static struct attribute *pcf8591_attributes_opt[] = {
+       &dev_attr_in2_input.attr,
+       &dev_attr_in3_input.attr,
+       NULL
+};
+
+static const struct attribute_group pcf8591_attr_group_opt = {
+       .attrs = pcf8591_attributes_opt,
+};
+
 /*
  * Real code
  */
        pcf8591_init_client(new_client);
 
        /* Register sysfs hooks */
-       device_create_file(&new_client->dev, &dev_attr_out0_enable);
-       device_create_file(&new_client->dev, &dev_attr_out0_output);
-       device_create_file(&new_client->dev, &dev_attr_in0_input);
-       device_create_file(&new_client->dev, &dev_attr_in1_input);
+       err = sysfs_create_group(&new_client->dev.kobj, &pcf8591_attr_group);
+       if (err)
+               goto exit_detach;
 
        /* Register input2 if not in "two differential inputs" mode */
-       if (input_mode != 3 )
-               device_create_file(&new_client->dev, &dev_attr_in2_input);
-               
+       if (input_mode != 3) {
+               if ((err = device_create_file(&new_client->dev,
+                                             &dev_attr_in2_input)))
+                       goto exit_sysfs_remove;
+       }
+
        /* Register input3 only in "four single ended inputs" mode */
-       if (input_mode == 0)
-               device_create_file(&new_client->dev, &dev_attr_in3_input);
-       
+       if (input_mode == 0) {
+               if ((err = device_create_file(&new_client->dev,
+                                             &dev_attr_in3_input)))
+                       goto exit_sysfs_remove;
+       }
+
        return 0;
-       
-       /* OK, this is not exactly good programming practice, usually. But it is
-          very code-efficient in this case. */
 
+exit_sysfs_remove:
+       sysfs_remove_group(&new_client->dev.kobj, &pcf8591_attr_group_opt);
+       sysfs_remove_group(&new_client->dev.kobj, &pcf8591_attr_group);
+exit_detach:
+       i2c_detach_client(new_client);
 exit_kfree:
        kfree(data);
 exit:
 {
        int err;
 
+       sysfs_remove_group(&client->dev.kobj, &pcf8591_attr_group_opt);
+       sysfs_remove_group(&client->dev.kobj, &pcf8591_attr_group);
+
        if ((err = i2c_detach_client(client)))
                return err;