diff options
author | Johan Hovold <johan@kernel.org> | 2014-06-25 13:08:45 -0400 |
---|---|---|
committer | Bryan Wu <cooloney@gmail.com> | 2014-06-25 18:00:55 -0400 |
commit | 74c850394394efc0905c22ab9686e8d20e3921eb (patch) | |
tree | 53fdcc6e27c3ff5c459df368608cce191472030c /drivers/leds/leds-lm3530.c | |
parent | d0d480cce8f522b37c2c1de38230fc9ad15fa506 (diff) |
leds: lm3550: fix attribute-creation race
Use the attribute groups of the led-class to create the mode attribute
during probe in order to avoid racing with userspace.
Signed-off-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Bryan Wu <cooloney@gmail.com>
Diffstat (limited to 'drivers/leds/leds-lm3530.c')
-rw-r--r-- | drivers/leds/leds-lm3530.c | 20 |
1 files changed, 7 insertions, 13 deletions
diff --git a/drivers/leds/leds-lm3530.c b/drivers/leds/leds-lm3530.c index 652368c2ea9a..91325de3cd33 100644 --- a/drivers/leds/leds-lm3530.c +++ b/drivers/leds/leds-lm3530.c | |||
@@ -400,6 +400,12 @@ static ssize_t lm3530_mode_set(struct device *dev, struct device_attribute | |||
400 | } | 400 | } |
401 | static DEVICE_ATTR(mode, 0644, lm3530_mode_get, lm3530_mode_set); | 401 | static DEVICE_ATTR(mode, 0644, lm3530_mode_get, lm3530_mode_set); |
402 | 402 | ||
403 | static struct attribute *lm3530_attrs[] = { | ||
404 | &dev_attr_mode.attr, | ||
405 | NULL | ||
406 | }; | ||
407 | ATTRIBUTE_GROUPS(lm3530); | ||
408 | |||
403 | static int lm3530_probe(struct i2c_client *client, | 409 | static int lm3530_probe(struct i2c_client *client, |
404 | const struct i2c_device_id *id) | 410 | const struct i2c_device_id *id) |
405 | { | 411 | { |
@@ -436,6 +442,7 @@ static int lm3530_probe(struct i2c_client *client, | |||
436 | drvdata->led_dev.name = LM3530_LED_DEV; | 442 | drvdata->led_dev.name = LM3530_LED_DEV; |
437 | drvdata->led_dev.brightness_set = lm3530_brightness_set; | 443 | drvdata->led_dev.brightness_set = lm3530_brightness_set; |
438 | drvdata->led_dev.max_brightness = MAX_BRIGHTNESS; | 444 | drvdata->led_dev.max_brightness = MAX_BRIGHTNESS; |
445 | drvdata->led_dev.groups = lm3530_groups; | ||
439 | 446 | ||
440 | i2c_set_clientdata(client, drvdata); | 447 | i2c_set_clientdata(client, drvdata); |
441 | 448 | ||
@@ -461,26 +468,13 @@ static int lm3530_probe(struct i2c_client *client, | |||
461 | return err; | 468 | return err; |
462 | } | 469 | } |
463 | 470 | ||
464 | err = device_create_file(drvdata->led_dev.dev, &dev_attr_mode); | ||
465 | if (err < 0) { | ||
466 | dev_err(&client->dev, "File device creation failed: %d\n", err); | ||
467 | err = -ENODEV; | ||
468 | goto err_create_file; | ||
469 | } | ||
470 | |||
471 | return 0; | 471 | return 0; |
472 | |||
473 | err_create_file: | ||
474 | led_classdev_unregister(&drvdata->led_dev); | ||
475 | return err; | ||
476 | } | 472 | } |
477 | 473 | ||
478 | static int lm3530_remove(struct i2c_client *client) | 474 | static int lm3530_remove(struct i2c_client *client) |
479 | { | 475 | { |
480 | struct lm3530_data *drvdata = i2c_get_clientdata(client); | 476 | struct lm3530_data *drvdata = i2c_get_clientdata(client); |
481 | 477 | ||
482 | device_remove_file(drvdata->led_dev.dev, &dev_attr_mode); | ||
483 | |||
484 | lm3530_led_disable(drvdata); | 478 | lm3530_led_disable(drvdata); |
485 | led_classdev_unregister(&drvdata->led_dev); | 479 | led_classdev_unregister(&drvdata->led_dev); |
486 | return 0; | 480 | return 0; |