diff options
author | Jean Delvare <khali@linux-fr.org> | 2006-09-03 16:20:24 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-09-26 18:38:51 -0400 |
commit | 7d9db67febf67dd76329a9dd8f97cf4611a8ac2e (patch) | |
tree | 6354fa99b17f89c8f26ccf7c440d0d29096f2dc2 /drivers/i2c/chips/pcf8591.c | |
parent | b32d20dc8b187e03605f091dbde9a78676a2a642 (diff) |
i2c: __must_check fixes (chip drivers)
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@linux-fr.org>
Cc: Ben Gardner <bgardner@wabtec.com>
Cc: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
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 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 | |||
158 | static DEVICE_ATTR(out0_enable, S_IWUSR | S_IRUGO, | 158 | static DEVICE_ATTR(out0_enable, S_IWUSR | S_IRUGO, |
159 | show_out0_enable, set_out0_enable); | 159 | show_out0_enable, set_out0_enable); |
160 | 160 | ||
161 | static struct attribute *pcf8591_attributes[] = { | ||
162 | &dev_attr_out0_enable.attr, | ||
163 | &dev_attr_out0_output.attr, | ||
164 | &dev_attr_in0_input.attr, | ||
165 | &dev_attr_in1_input.attr, | ||
166 | NULL | ||
167 | }; | ||
168 | |||
169 | static const struct attribute_group pcf8591_attr_group = { | ||
170 | .attrs = pcf8591_attributes, | ||
171 | }; | ||
172 | |||
173 | static struct attribute *pcf8591_attributes_opt[] = { | ||
174 | &dev_attr_in2_input.attr, | ||
175 | &dev_attr_in3_input.attr, | ||
176 | NULL | ||
177 | }; | ||
178 | |||
179 | static const struct attribute_group pcf8591_attr_group_opt = { | ||
180 | .attrs = pcf8591_attributes_opt, | ||
181 | }; | ||
182 | |||
161 | /* | 183 | /* |
162 | * Real code | 184 | * Real code |
163 | */ | 185 | */ |
@@ -211,24 +233,31 @@ static int pcf8591_detect(struct i2c_adapter *adapter, int address, int kind) | |||
211 | pcf8591_init_client(new_client); | 233 | pcf8591_init_client(new_client); |
212 | 234 | ||
213 | /* Register sysfs hooks */ | 235 | /* Register sysfs hooks */ |
214 | device_create_file(&new_client->dev, &dev_attr_out0_enable); | 236 | err = sysfs_create_group(&new_client->dev.kobj, &pcf8591_attr_group); |
215 | device_create_file(&new_client->dev, &dev_attr_out0_output); | 237 | if (err) |
216 | device_create_file(&new_client->dev, &dev_attr_in0_input); | 238 | goto exit_detach; |
217 | device_create_file(&new_client->dev, &dev_attr_in1_input); | ||
218 | 239 | ||
219 | /* Register input2 if not in "two differential inputs" mode */ | 240 | /* Register input2 if not in "two differential inputs" mode */ |
220 | if (input_mode != 3 ) | 241 | if (input_mode != 3) { |
221 | device_create_file(&new_client->dev, &dev_attr_in2_input); | 242 | if ((err = device_create_file(&new_client->dev, |
222 | 243 | &dev_attr_in2_input))) | |
244 | goto exit_sysfs_remove; | ||
245 | } | ||
246 | |||
223 | /* Register input3 only in "four single ended inputs" mode */ | 247 | /* Register input3 only in "four single ended inputs" mode */ |
224 | if (input_mode == 0) | 248 | if (input_mode == 0) { |
225 | device_create_file(&new_client->dev, &dev_attr_in3_input); | 249 | if ((err = device_create_file(&new_client->dev, |
226 | 250 | &dev_attr_in3_input))) | |
251 | goto exit_sysfs_remove; | ||
252 | } | ||
253 | |||
227 | return 0; | 254 | return 0; |
228 | |||
229 | /* OK, this is not exactly good programming practice, usually. But it is | ||
230 | very code-efficient in this case. */ | ||
231 | 255 | ||
256 | exit_sysfs_remove: | ||
257 | sysfs_remove_group(&new_client->dev.kobj, &pcf8591_attr_group_opt); | ||
258 | sysfs_remove_group(&new_client->dev.kobj, &pcf8591_attr_group); | ||
259 | exit_detach: | ||
260 | i2c_detach_client(new_client); | ||
232 | exit_kfree: | 261 | exit_kfree: |
233 | kfree(data); | 262 | kfree(data); |
234 | exit: | 263 | exit: |
@@ -239,6 +268,9 @@ static int pcf8591_detach_client(struct i2c_client *client) | |||
239 | { | 268 | { |
240 | int err; | 269 | int err; |
241 | 270 | ||
271 | sysfs_remove_group(&client->dev.kobj, &pcf8591_attr_group_opt); | ||
272 | sysfs_remove_group(&client->dev.kobj, &pcf8591_attr_group); | ||
273 | |||
242 | if ((err = i2c_detach_client(client))) | 274 | if ((err = i2c_detach_client(client))) |
243 | return err; | 275 | return err; |
244 | 276 | ||