summaryrefslogtreecommitdiffstats
path: root/drivers/i2c/chips/pcf8591.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/i2c/chips/pcf8591.c')
-rw-r--r--drivers/i2c/chips/pcf8591.c58
1 files changed, 45 insertions, 13 deletions
diff --git a/drivers/i2c/chips/pcf8591.c b/drivers/i2c/chips/pcf8591.c
index 925a6b371fd2..4dc36376eb32 100644
--- a/drivers/i2c/chips/pcf8591.c
+++ b/drivers/i2c/chips/pcf8591.c
@@ -158,6 +158,28 @@ static ssize_t set_out0_enable(struct device *dev, struct device_attribute *attr
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_adapter *adapter, int address, int kind)
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 i2c_client *client)
{
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;