aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/leds/leds-lm3530.c
diff options
context:
space:
mode:
authorJohan Hovold <johan@kernel.org>2014-06-25 13:08:45 -0400
committerBryan Wu <cooloney@gmail.com>2014-06-25 18:00:55 -0400
commit74c850394394efc0905c22ab9686e8d20e3921eb (patch)
tree53fdcc6e27c3ff5c459df368608cce191472030c /drivers/leds/leds-lm3530.c
parentd0d480cce8f522b37c2c1de38230fc9ad15fa506 (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.c20
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}
401static DEVICE_ATTR(mode, 0644, lm3530_mode_get, lm3530_mode_set); 401static DEVICE_ATTR(mode, 0644, lm3530_mode_get, lm3530_mode_set);
402 402
403static struct attribute *lm3530_attrs[] = {
404 &dev_attr_mode.attr,
405 NULL
406};
407ATTRIBUTE_GROUPS(lm3530);
408
403static int lm3530_probe(struct i2c_client *client, 409static 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
473err_create_file:
474 led_classdev_unregister(&drvdata->led_dev);
475 return err;
476} 472}
477 473
478static int lm3530_remove(struct i2c_client *client) 474static 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;