aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/leds
diff options
context:
space:
mode:
authorJohan Hovold <johan@kernel.org>2014-06-25 13:08:46 -0400
committerBryan Wu <cooloney@gmail.com>2014-06-25 18:02:31 -0400
commit9db9386016c6cfc6a6af3bacc7043cab8ff04ecf (patch)
tree77f0ca4c8fdd65069d4fb48ed26aeae4f7ea344d /drivers/leds
parent74c850394394efc0905c22ab9686e8d20e3921eb (diff)
leds: lm3533: fix attribute-creation race
Use the attribute groups of the led-class to create the attributes 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')
-rw-r--r--drivers/leds/leds-lm3533.c20
1 files changed, 8 insertions, 12 deletions
diff --git a/drivers/leds/leds-lm3533.c b/drivers/leds/leds-lm3533.c
index e2c642c1169b..cbf61a40137d 100644
--- a/drivers/leds/leds-lm3533.c
+++ b/drivers/leds/leds-lm3533.c
@@ -645,6 +645,11 @@ static struct attribute_group lm3533_led_attribute_group = {
645 .attrs = lm3533_led_attributes 645 .attrs = lm3533_led_attributes
646}; 646};
647 647
648static const struct attribute_group *lm3533_led_attribute_groups[] = {
649 &lm3533_led_attribute_group,
650 NULL
651};
652
648static int lm3533_led_setup(struct lm3533_led *led, 653static int lm3533_led_setup(struct lm3533_led *led,
649 struct lm3533_led_platform_data *pdata) 654 struct lm3533_led_platform_data *pdata)
650{ 655{
@@ -692,6 +697,7 @@ static int lm3533_led_probe(struct platform_device *pdev)
692 led->cdev.brightness_get = lm3533_led_get; 697 led->cdev.brightness_get = lm3533_led_get;
693 led->cdev.blink_set = lm3533_led_blink_set; 698 led->cdev.blink_set = lm3533_led_blink_set;
694 led->cdev.brightness = LED_OFF; 699 led->cdev.brightness = LED_OFF;
700 led->cdev.groups = lm3533_led_attribute_groups,
695 led->id = pdev->id; 701 led->id = pdev->id;
696 702
697 mutex_init(&led->mutex); 703 mutex_init(&led->mutex);
@@ -715,25 +721,16 @@ static int lm3533_led_probe(struct platform_device *pdev)
715 721
716 led->cb.dev = led->cdev.dev; 722 led->cb.dev = led->cdev.dev;
717 723
718 ret = sysfs_create_group(&led->cdev.dev->kobj,
719 &lm3533_led_attribute_group);
720 if (ret < 0) {
721 dev_err(&pdev->dev, "failed to create sysfs attributes\n");
722 goto err_unregister;
723 }
724
725 ret = lm3533_led_setup(led, pdata); 724 ret = lm3533_led_setup(led, pdata);
726 if (ret) 725 if (ret)
727 goto err_sysfs_remove; 726 goto err_unregister;
728 727
729 ret = lm3533_ctrlbank_enable(&led->cb); 728 ret = lm3533_ctrlbank_enable(&led->cb);
730 if (ret) 729 if (ret)
731 goto err_sysfs_remove; 730 goto err_unregister;
732 731
733 return 0; 732 return 0;
734 733
735err_sysfs_remove:
736 sysfs_remove_group(&led->cdev.dev->kobj, &lm3533_led_attribute_group);
737err_unregister: 734err_unregister:
738 led_classdev_unregister(&led->cdev); 735 led_classdev_unregister(&led->cdev);
739 flush_work(&led->work); 736 flush_work(&led->work);
@@ -748,7 +745,6 @@ static int lm3533_led_remove(struct platform_device *pdev)
748 dev_dbg(&pdev->dev, "%s\n", __func__); 745 dev_dbg(&pdev->dev, "%s\n", __func__);
749 746
750 lm3533_ctrlbank_disable(&led->cb); 747 lm3533_ctrlbank_disable(&led->cb);
751 sysfs_remove_group(&led->cdev.dev->kobj, &lm3533_led_attribute_group);
752 led_classdev_unregister(&led->cdev); 748 led_classdev_unregister(&led->cdev);
753 flush_work(&led->work); 749 flush_work(&led->work);
754 750