diff options
Diffstat (limited to 'drivers/i2c/chips/pcf8591.c')
-rw-r--r-- | drivers/i2c/chips/pcf8591.c | 58 |
1 files changed, 45 insertions, 13 deletions
diff --git a/drivers/i2c/chips/pcf8591.c b/drivers/i2c/chips/pcf8591.c index 925a6b3..4dc3637 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; |