[i2c] patch i2c-chips-__must_check-fixes.patch added to gregkh-2.6 tree

gregkh at suse.de gregkh at suse.de
Wed Sep 6 23:54:45 CEST 2006


This is a note to let you know that I've just added the patch titled

     Subject: [PATCH 02/13] i2c: __must_check fixes (chip drivers)

to my gregkh-2.6 tree.  Its filename is

     i2c-chips-__must_check-fixes.patch

This tree can be found at 
    http://www.kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/patches/


>From khali at linux-fr.org Sun Sep  3 13:20:33 2006
Date: Sun, 3 Sep 2006 22:20:24 +0200
From: Jean Delvare <khali at linux-fr.org>
To: Greg KH <greg at kroah.com>
Cc: Linux I2C <i2c at lm-sensors.org>
Subject: [PATCH 02/13] i2c: __must_check fixes (chip drivers)
Message-Id: <20060903222024.beb5add3.khali at linux-fr.org>
Content-Disposition: inline; filename=i2c-chips-__must_check-fixes.patch

i2c: __must_check fixes (chip drivers)

Check for error on sysfs file creation.
Delete sysfs files on device removal.

The approach taken for the most complex case (pcf8591) is similar to
what Mark M. Hoffman proposed for hardware monitoring chip drivers.

Signed-off-by: Jean Delvare <khali at linux-fr.org>
Cc: Ben Gardner <bgardner at wabtec.com>
Cc: Aurelien Jarno <aurelien at aurel32.net>
Signed-off-by: Greg Kroah-Hartman <gregkh at suse.de>

---
 drivers/i2c/chips/eeprom.c  |    8 +++++-
 drivers/i2c/chips/max6875.c |   25 ++++++++++++++----
 drivers/i2c/chips/pca9539.c |   11 ++++++--
 drivers/i2c/chips/pcf8574.c |   22 ++++++++++++----
 drivers/i2c/chips/pcf8591.c |   58 ++++++++++++++++++++++++++++++++++----------
 5 files changed, 97 insertions(+), 27 deletions(-)

--- gregkh-2.6.orig/drivers/i2c/chips/eeprom.c
+++ gregkh-2.6/drivers/i2c/chips/eeprom.c
@@ -209,10 +209,14 @@ static int eeprom_detect(struct i2c_adap
 	}
 
 	/* 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:
@@ -223,6 +227,8 @@ static int eeprom_detach_client(struct i
 {
 	int err;
 
+	sysfs_remove_bin_file(&client->dev.kobj, &eeprom_attr);
+
 	err = i2c_detach_client(client);
 	if (err)
 		return err;
--- gregkh-2.6.orig/drivers/i2c/chips/max6875.c
+++ gregkh-2.6/drivers/i2c/chips/max6875.c
@@ -199,8 +199,7 @@ static int max6875_detect(struct i2c_ada
 	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 +213,17 @@ static int max6875_detect(struct i2c_ada
 		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 +232,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;
 }
 
--- gregkh-2.6.orig/drivers/i2c/chips/pca9539.c
+++ gregkh-2.6/drivers/i2c/chips/pca9539.c
@@ -148,11 +148,16 @@ static int pca9539_detect(struct i2c_ada
 	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:
@@ -163,6 +168,8 @@ static int pca9539_detach_client(struct 
 {
 	int err;
 
+	sysfs_remove_group(&client->dev.kobj, &pca9539_defattr_group);
+
 	if ((err = i2c_detach_client(client)))
 		return err;
 
--- gregkh-2.6.orig/drivers/i2c/chips/pcf8574.c
+++ gregkh-2.6/drivers/i2c/chips/pcf8574.c
@@ -105,6 +105,16 @@ static ssize_t set_write(struct device *
 
 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
  */
@@ -166,13 +176,13 @@ static int pcf8574_detect(struct i2c_ada
 	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:
@@ -183,6 +193,8 @@ static int pcf8574_detach_client(struct 
 {
 	int err;
 
+	sysfs_remove_group(&client->dev.kobj, &pcf8574_attr_group);
+
 	if ((err = i2c_detach_client(client)))
 		return err;
 
--- gregkh-2.6.orig/drivers/i2c/chips/pcf8591.c
+++ gregkh-2.6/drivers/i2c/chips/pcf8591.c
@@ -158,6 +158,28 @@ static ssize_t set_out0_enable(struct de
 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
  */
@@ -211,24 +233,31 @@ static int pcf8591_detect(struct i2c_ada
 	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:
@@ -239,6 +268,9 @@ static int pcf8591_detach_client(struct 
 {
 	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;
 


Patches currently in gregkh-2.6 which might be from khali at linux-fr.org are

i2c/hwmon-w83627ehf-add-pwm-support.patch
i2c/hwmon-w83627ehf-documentation.patch
i2c/i2c-algo-bit-kill-mdelay.patch
i2c/hwmon-abituguru-suspend-resume.patch
i2c/i2c-__must_check-fixes-i2c-dev.patch
i2c/i2c-__must_check-fixes.patch
i2c/hwmon-it87-disabled-fans.patch
i2c/i2c-algo-sibyte-cleanups.patch
i2c/i2c-algo-sibyte-merge-in-i2c-sibyte.patch
i2c/i2c-au1550-add-au1200-support.patch
i2c/i2c-au1550-add-smbus-functionality-flag.patch
i2c/i2c-au1550-fix-timeout-problem.patch
i2c/i2c-bus-driver-for-TI-OMAP-boards.patch
i2c/i2c-isa-plan-for-removal.patch
i2c/i2c-dev-cleanups.patch
i2c/i2c-dev-convert-array-to-list.patch
i2c/i2c-dev-drop-template-client.patch
i2c/i2c-dev-device.patch
i2c/i2c-fix-copy-n-paste-in-subsystem-Kconfig.patch
i2c/i2c-matroxfb-c99-struct-init.patch
i2c/i2c-sibyte-drop-kip-walker-address.patch
i2c/i2c-stub-add-chip_addr-param.patch
i2c/hwmon-atxp1-signed-unsigned-char-bug.patch
i2c/hwmon-hdaps-handle-errors-from-input-register-device.patch
i2c/hwmon-it87-copyright-update.patch
i2c/hwmon-it87-div-to-reg-overflow.patch
i2c/hwmon-it87-in8-no-limits.patch
i2c/hwmon-it87-it8716f-support.patch
i2c/hwmon-it87-it8718f-support.patch
i2c/hwmon-it87-sane-limit-defaults.patch
i2c/hwmon-it87-set-fan-div.patch
i2c/hwmon-k8temp-autoload.patch
i2c/hwmon-k8temp-new-driver.patch
i2c/hwmon-smsc47m1-fix-dev-message.patch
i2c/i2c-algo-bit-cleanups.patch
i2c/i2c-algo-pcf-kill-mdelay.patch
i2c/i2c-algos-constify-i2c_algorithm.patch
i2c/i2c-busses-constify-i2c_algorithm.patch
i2c/i2c-chips-__must_check-fixes.patch
i2c/i2c-constify-i2c_algorithm.patch
i2c/i2c-dev-attach-detach-adapter-cleanups.patch
i2c/i2c-drop-slave-functions.patch
i2c/i2c-drop-useless-masking.patch
i2c/i2c-isa-restore-driver-owner.patch
i2c/i2c-isa-return-attach_adapter.patch
i2c/i2c-viapro-add-VT8251-VT8237A.patch
i2c/i2c-warn-on-failed-client-attach.patch



More information about the i2c mailing list